diff --git a/lib/index.d.ts b/lib/index.d.ts new file mode 100644 index 0000000..be82fd4 --- /dev/null +++ b/lib/index.d.ts @@ -0,0 +1,245 @@ + +import { + Plugin as HapiPlugin, + Server, + ServerEvents, + ServerMethod, + ServerMethods, + ServerCache, + ServerAuth, + ServerAuthScheme, + Dependencies, + DecorationMethod, + HandlerDecorationMethod, + ServerMethodOptions, + CachePolicyOptions, + ServerStateCookieOptions, + ServerExtType, + ServerRequestExtType, + ServerExtOptions, + ServerExtPointFunction, + Lifecycle, + RouteOptionsAccess, + Request, + ResponseToolkit, + ServerRoute +} from '@hapi/hapi'; + +import { ServerViewsConfiguration } from '@hapi/vision'; +import { ServerSubscriptionOptions } from '@hapi/nes'; + +import { Service, ServiceFactory, ServiceRegistrationObject } from '@hapipal/schmervice'; +import { ModelClass } from '@hapipal/schwifty'; +import { Root as Joi } from 'joi'; + +type OneOrArrayOf = T | T[]; + +export namespace HcAmendmentTypes { + + + type Decoration = { + type?: 'handler' | 'request' | 'toolkit' | 'server', + property?: string, + method: DecorationMethod | HandlerDecorationMethod + options?: { + apply?: boolean, + extend?: boolean + } + } + + type Expose = { + key: string, + value: any + } + + type AuthScheme = { + name: string, + scheme: ServerAuthScheme + }; + + type AuthStrategy = { + name: string, + scheme: string, + options: object + } + + type AuthDefault = string | RouteOptionsAccess + + type Dependency = { + dependencies: Dependencies, + after?: ((server: Server) => Promise) + } + + type Method = ServerMethod | { + name?: string, + method: ServerMethod, + options: ServerMethodOptions + } + + type Extensions = { + type?: ServerExtType | ServerRequestExtType, + method: Lifecycle.Method | OneOrArrayOf, + options: ServerExtOptions + } + + type Cookies = { + name: string, + options: ServerStateCookieOptions + } + + type Models = OneOrArrayOf + + type Services = typeof ServiceFactory | OneOrArrayOf + + type Subscription = { + path: string, + options: ServerSubscriptionOptions + } +} + +// Make a list of all the methods we can bind to +// using the exiting typings. Server methods should +// augment when you install respective plugin typings, +// such as Nes or Schwifty, and become available in +// this list +type AllAmendmentMethods = ( + keyof Server | + `events.${keyof ServerEvents}`| + `methods.${keyof ServerMethods}` | + `cache.${keyof ServerCache}` | + `auth.${keyof ServerAuth}` +); + +// Turn the union of those strings into a type +type AmendmentMethodFilter = { + [_key in AllAmendmentMethods]: never +} + +// Omit any methods or properties that cannot +// be leveraged by Haute Couture +type UsefulAmendmentMethods = Omit< + AmendmentMethodFilter, + + // Readonly properties + 'auth' | 'decorations' | 'info' | + 'load' | 'methods' | 'realm' | + 'registrations' | 'settings' | + 'states' | 'type' | 'version' | + + // Not useful + 'inject' | 'log' | 'lookup' | + 'match' | 'table' | 'cache' | + 'start' | 'stop' | 'initialize' | + 'events' | 'events.hasListeners' | + 'events.removeListener' | 'events.removeAllListeners' +> + +// Known methods will be the keys of resulting type +export type KnownAmendmentMethods = keyof UsefulAmendmentMethods; + +// This is the type used to check amendment methods. +// Can be overridden to include custom decorations +// that you might have on the server object. +export type AmendmentMethods = KnownAmendmentMethods + +// Enumerate the types that example can be so that +// IDE can pick it up when it is an object +type AmendmentExampleType = ( + AmendmentExample | + string | number | boolean | + any[] | undefined +); + +interface AmendmentExample { + $literal?: string, + $comment?: string, + $value?: any, + $requires?: any, + [key: string]: AmendmentExampleType; +} + +// Amendment return type +export type AmendmentConfig< + T = Record +> = { + method: AmendmentMethods, + signature?: (keyof T | `[${string & keyof T}]`)[] | string[], + list: boolean, + useFilename: (value: T | T[], path: string, filename: string) => T | T[], + example: AmendmentExampleType, + after?: string[], + recursive?: boolean +} + +// Amendment configuration override +export type CustomAmendmentConfig> = Partial> + +// Types that a place enforces +export type PlaceTypes = { + path: string + bind: any + caches: CachePolicyOptions + plugins: HapiPlugin + dependencies: HcAmendmentTypes.Dependency + methods: HcAmendmentTypes.Method + decorations: HcAmendmentTypes.Decoration + extensions: HcAmendmentTypes.Extensions + expose: HcAmendmentTypes.Expose + cookies: HcAmendmentTypes.Cookies + models: HcAmendmentTypes.Models + services: HcAmendmentTypes.Services + subscriptions: HcAmendmentTypes.Subscription + validator: Joi + routes: ServerRoute + 'view-manager': ServerViewsConfiguration + 'auth/schemes': HcAmendmentTypes.AuthScheme + 'auth/strategies': HcAmendmentTypes.AuthStrategy + 'auth/default': HcAmendmentTypes.AuthDefault +} + +// Amendment mapping +type InternalAmemdments = { + path: AmendmentConfig + bind: AmendmentConfig + caches: AmendmentConfig + plugins: AmendmentConfig + dependencies: AmendmentConfig + methods: AmendmentConfig + decorations: AmendmentConfig + extensions: AmendmentConfig + expose: AmendmentConfig + cookies: AmendmentConfig + models: AmendmentConfig + services: AmendmentConfig + subscriptions: AmendmentConfig + validator: AmendmentConfig + routes: AmendmentConfig + 'view-manager': AmendmentConfig + 'auth/schemes': AmendmentConfig + 'auth/strategies': AmendmentConfig + 'auth/default': AmendmentConfig +} + +// Creates an amendment config +export function amendment

( + place: P, + override?: CustomAmendmentConfig +): InternalAmemdments[P] + +export function amendments > (overrides: O): O + +export interface HcComposeFunction> { + + (server: Server, options: Options): ReturnType +} + +type ComposeOptions = { + dirname?: string, + amendments?: { + [key: string]: CustomAmendmentConfig + } +} + +export function compose > (server: Server, options: Options, composeOptions?: ComposeOptions): Promise + +export function composeWith > (composeOptions: ComposeOptions): HcComposeFunction, Options> diff --git a/package.json b/package.json index ef5e59e..672ff7e 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "4.3.1", "description": "File-based hapi plugin composer", "main": "lib/index.js", + "types": "lib/index.d.ts", "engines": { "node": ">=12" },