UNPKG

@trapi/metadata

Version:

Generate REST-API metadata scheme from TypeScript Decorators.

741 lines (740 loc) 32.6 kB
import { BaseError } from "@ebec/core"; import { ClassDeclaration, CompilerOptions, EnumDeclaration, EnumMember, Expression, HasInitializer, InterfaceDeclaration, JSDoc, JSDocComment, JSDocTag, LiteralTypeNode, MethodDeclaration, Node, NodeArray, ParameterDeclaration, PropertyDeclaration, PropertySignature, SyntaxKind, Token, TypeAliasDeclaration, TypeChecker, TypeNode, TypeReferenceNode } from "typescript"; import { BaseType, Controller, DecoratorArgument, DecoratorHost, DecoratorSource, DecoratorTarget, DependencyResolver, Extension, HandlerContext, IControllerGenerator, IParameterGenerator, IResolverCache, JsDocHandlerContext, JsDocMatch, JsDocSource, Match, Metadata, Method, NeverType, Parameter, Preset, PrimitiveType, RefEnumType, RefObjectType, ReferenceType, Registry, ResolverProperty, Type, UnmatchedDecoratorReport, Validator, VoidType } from "@trapi/core"; //#region src/adapters/cache/types.d.ts interface CacheOptions { /** * Specify if the cache driver should be enabled. * * Default: false * */ enabled: boolean; /** * Directory relative or absolute path. Auto-created on first save. * * Default: tmpDir() */ directoryPath: string; /** * Specify the cache file name. When set, the cache becomes a single-slot * store at this exact name (instead of one file per cache key). The * in-file `cacheKey` check still rejects mismatches; you just lose * multi-key caching. * * Default: .trapi-metadata-{cacheKey}.json */ fileName?: string; /** * Files older than this many milliseconds are pruned opportunistically * after each successful save. Set to `0` to disable eviction. * * Default: 7 days */ maxAgeMs: number; } type CacheOptionsInput = Partial<CacheOptions>; type CacheData = { /** * Opaque composite key — sha256 over (schema version, source files content, * compiler options, resolved registry shape, preset name). The reader * cross-checks this against the expected key to defend against collisions * or schema drift. */ cacheKey: string; /** Stamped at write time; rejected on read if not equal to the current value. */ schemaVersion: string; } & Metadata; interface ICacheClient { save(data: CacheData): Promise<string | undefined>; get(cacheKey: string): Promise<CacheData | undefined>; /** Prune cache files older than `maxAgeMs`. Safe to call concurrently. */ evict(): Promise<void>; } //#endregion //#region src/adapters/cache/client.d.ts declare class CacheClient implements ICacheClient { private readonly options; constructor(input?: string | boolean | CacheOptionsInput); save(data: CacheData): Promise<string | undefined>; get(cacheKey: string): Promise<CacheData | undefined>; /** * Prune cache files older than `maxAgeMs`. No-op when disabled or when * `maxAgeMs <= 0`. Each unlink is best-effort — a concurrent generator * may have already removed the file. */ evict(): Promise<void>; private resolveFilePath; private ensureDirectory; } //#endregion //#region src/adapters/cache/constants.d.ts /** * Bump whenever the on-disk cache shape changes incompatibly * (Metadata, Controller, Method, Parameter, resolver type nodes, * or the cache wrapper itself). Old cache files with a different * version are rejected on read. */ declare const CACHE_SCHEMA_VERSION = "3"; declare const CACHE_FILE_PREFIX = ".trapi-metadata-"; declare const CACHE_FILE_SUFFIX = ".json"; /** 7 days. */ declare const CACHE_DEFAULT_MAX_AGE_MS: number; //#endregion //#region src/adapters/cache/utils.d.ts declare function buildCacheOptions(input?: string | boolean | CacheOptionsInput): CacheOptions; type CacheKeyParts = { schemaVersion: string; sourceFilesHash: string; compilerOptionsHash: string; registryHash: string; presetName?: string; }; /** * Combines all key contributors into a single sha256 hex string. The order is * stable; each part is null-separated to avoid concatenation ambiguity. */ declare function composeCacheKey(parts: CacheKeyParts): string; /** * Hash a stable JSON projection of `compilerOptions`. Sorting keys keeps the * output deterministic regardless of declaration order in tsconfig.json. */ declare function hashCompilerOptions(options?: CompilerOptions): string; /** * Hash the resolved registry's structural shape. Catches structural changes * (handler added/removed/renamed, marker changed, replaces policy changed) * AND most logic changes via `apply.toString()`. Misses changes that are * purely captured-variable shifts in factory-built handlers — acceptable * trade-off for catching local preset edits. */ declare function hashRegistry(registry: Registry): string; //#endregion //#region src/adapters/filesystem/tsconfig/types.d.ts type TsconfigLoadContext = { cwd?: string; name?: string; }; type TsCompilerOptions = CompilerOptions; type TsConfig = { compilerOptions?: TsCompilerOptions; [key: string]: any; }; //#endregion //#region src/adapters/filesystem/tsconfig/module.d.ts declare function loadTSConfig(context?: TsconfigLoadContext): Promise<TsConfig>; declare function softLoadTsconfig(context?: TsconfigLoadContext): Promise<TsConfig>; //#endregion //#region src/core/config/types.d.ts type EntryPointOptions = { cwd: string; pattern: string; }; type EntryPoint = string | string[] | EntryPointOptions | EntryPointOptions[]; type MetadataGeneratorOptions = { /** * The entry point to your API. */ entryPoint: EntryPoint; /** * Directory to ignore during TypeScript files scan. * Default: [] */ ignore?: string[]; /** * Directory to allow during TypeScript files scan. * Default: [] */ allow?: string[]; /** * Directory to store and cache metadata cache files. * Default: false */ cache?: string | boolean | Partial<CacheOptions>; /** * Decorator preset to load. Either: * - a string identifier resolved via {@link resolvePresetByName} * (npm package, relative path, or `module:` specifier), or * - an inline {@link Preset} object (still walked through `loadRegistry`, * so its `extends` chain — if any — is resolved by name). * * If both `preset` and `registry` are provided, the resolved preset * registry comes first and the inline `registry` is appended after. * Inline handlers therefore run last (winning on scalar mutations like * `into('path')`) and additively contribute on `append`-style fields. */ preset?: string | Preset; /** * An already-resolved decorator {@link Registry}. Use this to wire * decorator handlers manually without authoring a full {@link Preset}. * * If provided alongside `preset`, the registry is appended to the * preset-derived registry (preset first, registry second). Inline * handlers cannot carry `replaces` semantics — those are enforced at * preset-load time. To remove a preset handler, author a `Preset` with * `replaces` and pass it via `preset` instead. */ registry?: Registry; /** * Controls how unmatched decorators (decorators with no matching handler * in the resolved registry) are surfaced. * * - `false` / unset (default): silent. * - `true`: emit a single `console.warn` listing every unmatched decorator * at the end of generation. Useful for catching typos (e.g. `@Hiden` * instead of `@Hidden`) and unwired decorators in custom presets. * - `'throw'`: throw a `GeneratorError` instead of warning. Useful as a * CI gate. * * If `onUnmatchedDecorator` is also set, the callback is invoked instead * of warning/throwing — collection still happens, but reporting is yours. * * Note: JSDoc tags are not currently included in strict-mode reporting * because standard documentation tags (`@param`, `@returns`, ...) would * generate excessive noise. */ strict?: boolean | 'throw'; /** * Optional callback invoked at the end of generation with all unmatched- * decorator reports collected during the run. Replaces the default * `console.warn` / `throw` behaviour of `strict` — when set, the callback * is the terminal step (no warn, no throw). * * Setting this implicitly enables collection — you don't also need to set * `strict`. */ onUnmatchedDecorator?: (reports: UnmatchedDecoratorReport[]) => void; }; type MetadataGenerateOptions = MetadataGeneratorOptions & { /** * Path to tsconfig.json or a TsConfig object. */ tsconfig?: string | TsConfig; }; //#endregion //#region src/core/metadata/types.d.ts type MetadataGeneratorContext = { options: MetadataGeneratorOptions; sourceFiles: string[]; compilerOptions?: CompilerOptions; }; interface IMetadataGenerator { generate(): Promise<Metadata>; } /** * Narrow context interface for the type resolver. * Contains only what TypeNodeResolver needs — no generator methods. */ interface IResolverContext { readonly typeChecker: TypeChecker; readonly nodes: Node[]; readonly registry: Registry; readonly resolverCache: IResolverCache; isExportedNode(node: Node): boolean; } /** * Callback interface for resolver → generator communication. * Allows the resolver to register discovered reference types * without importing the MetadataGenerator class. */ interface IReferenceTypeRegistry { addReferenceType(type: ReferenceType): void; getReferenceType(refName: string): ReferenceType | undefined; registerDependencyResolver(callback: DependencyResolver): void; } /** * Context interface for generators. * Extends IResolverContext and IReferenceTypeRegistry so generators * can pass `this.current` directly to TypeNodeResolver. */ interface IGeneratorContext extends IResolverContext, IReferenceTypeRegistry { readonly config: MetadataGeneratorOptions; readonly registry: Registry; /** * Optional sink for unmatched-decorator reports. Generators forward to * this when `config.strict` is enabled. The metadata generator drains the * sink after the controller walk and emits a single warning summary. */ reportUnmatchedDecorator?(report: UnmatchedDecoratorReport): void; } //#endregion //#region src/core/error/base.d.ts declare class MetadataError extends BaseError {} //#endregion //#region src/core/error/config.d.ts declare class ConfigError extends MetadataError {} //#endregion //#region src/core/error/config-codes.d.ts declare const ConfigErrorCode: { readonly TSCONFIG_MALFORMED: "CONFIG_TSCONFIG_MALFORMED"; readonly PRESET_NOT_FOUND: "CONFIG_PRESET_NOT_FOUND"; readonly PRESET_MISSING: "CONFIG_PRESET_MISSING"; }; type ConfigErrorCode = typeof ConfigErrorCode[keyof typeof ConfigErrorCode]; //#endregion //#region src/core/error/generator.d.ts declare class GeneratorError extends MetadataError {} declare function isGeneratorError(input: unknown): input is GeneratorError & { code: string; }; //#endregion //#region src/core/error/generator-codes.d.ts declare const GeneratorErrorCode: { readonly CONTROLLER_NO_SOURCE_FILE: "GENERATOR_CONTROLLER_NO_SOURCE_FILE"; readonly CONTROLLER_NO_NAME: "GENERATOR_CONTROLLER_NO_NAME"; readonly PARAMETER_GENERATION_FAILED: "GENERATOR_PARAMETER_GENERATION_FAILED"; readonly BODY_PARAMETER_DUPLICATE: "GENERATOR_BODY_PARAMETER_DUPLICATE"; readonly BODY_FORM_CONFLICT: "GENERATOR_BODY_FORM_CONFLICT"; readonly STRICT_UNMATCHED_DECORATORS: "GENERATOR_STRICT_UNMATCHED_DECORATORS"; }; type GeneratorErrorCode = typeof GeneratorErrorCode[keyof typeof GeneratorErrorCode]; //#endregion //#region src/core/error/parameter.d.ts type UnsupportedTypeContext = { decoratorName: string; propertyName: string; type: BaseType; node?: Node; }; type UnsupportedMethodContext = { decoratorName: string; propertyName: string; method: string; node?: Node; }; type PathMatchInvalidContext = { decoratorName: string; propertyName: string; path: string; node?: Node; }; type ScopeRequiredContext = { decoratorName: string; node?: Node; }; declare class ParameterError extends MetadataError { static typeUnsupported(context: UnsupportedTypeContext): ParameterError; static methodUnsupported(context: UnsupportedMethodContext): ParameterError; static invalidPathMatch(context: PathMatchInvalidContext): ParameterError; static scopeRequired(context: ScopeRequiredContext): ParameterError; static invalidExampleSchema(): ParameterError; static getCurrentLocation(node: Node): string; } //#endregion //#region src/core/error/parameter-codes.d.ts declare const ParameterErrorCode: { readonly TYPE_UNSUPPORTED: "PARAMETER_TYPE_UNSUPPORTED"; readonly METHOD_UNSUPPORTED: "PARAMETER_METHOD_UNSUPPORTED"; readonly PATH_MISMATCH: "PARAMETER_PATH_MISMATCH"; readonly SCOPE_REQUIRED: "PARAMETER_SCOPE_REQUIRED"; readonly INVALID_EXAMPLE: "PARAMETER_INVALID_EXAMPLE"; }; type ParameterErrorCode = typeof ParameterErrorCode[keyof typeof ParameterErrorCode]; //#endregion //#region src/core/error/resolver.d.ts declare class ResolverError extends MetadataError { readonly file?: string; readonly line?: number; constructor(message: string, node?: Node | TypeNode, options?: boolean | { onlyCurrent?: boolean; cause?: unknown; }); } declare function isResolverError(input: unknown): input is ResolverError; declare function prettyLocationOfNode(node: Node | TypeNode): { text: string; file: string; line?: number; } | undefined; declare function prettyTroubleCause(node: Node | TypeNode, onlyCurrent?: boolean): string; //#endregion //#region src/core/error/validator.d.ts declare class ValidatorError extends MetadataError {} //#endregion //#region src/core/error/validator-codes.d.ts declare const ValidatorErrorCode: { readonly EXPECTED_NUMBER: "VALIDATOR_EXPECTED_NUMBER"; readonly EXPECTED_DATE: "VALIDATOR_EXPECTED_DATE"; readonly EXPECTED_STRING: "VALIDATOR_EXPECTED_STRING"; }; type ValidatorErrorCode = typeof ValidatorErrorCode[keyof typeof ValidatorErrorCode]; //#endregion //#region src/adapters/typescript/resolver/types.d.ts type OverrideToken = Token<SyntaxKind.QuestionToken> | Token<SyntaxKind.PlusToken> | Token<SyntaxKind.MinusToken>; type UsableDeclaration = InterfaceDeclaration | ClassDeclaration | PropertySignature | TypeAliasDeclaration | EnumMember; type TypeNodeResolverContext = { [name: string]: TypeReferenceNode | TypeNode; }; type SubResolverContext = { readonly typeChecker: TypeChecker; readonly current: IResolverContext & IReferenceTypeRegistry; readonly parentNode?: Node; readonly context: TypeNodeResolverContext; readonly referencer?: TypeNode; resolveType(typeNode: TypeNode, parentNode?: Node, context?: TypeNodeResolverContext, referencer?: TypeNode): Type; propertyFromSignature(sig: PropertySignature, overrideToken?: OverrideToken): ResolverProperty; propertyFromDeclaration(decl: PropertyDeclaration | ParameterDeclaration, overrideToken?: OverrideToken): ResolverProperty; getNodeDescription(node: UsableDeclaration | PropertyDeclaration | ParameterDeclaration | EnumDeclaration): string | undefined; getNodeExample(node: UsableDeclaration | PropertyDeclaration | ParameterDeclaration | EnumDeclaration): unknown; getNodeExtensions(node: UsableDeclaration | PropertyDeclaration | ParameterDeclaration | EnumDeclaration): Extension[]; }; //#endregion //#region src/adapters/typescript/resolver/sub/array.d.ts declare function resolveArrayType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/base.d.ts declare class ResolverBase { protected hasPublicModifier(node: Node): boolean; protected hasStaticModifier(node: Node): boolean | undefined; protected isAccessibleParameter(node: Node): boolean; } //#endregion //#region src/adapters/typescript/resolver/sub/indexed-access.d.ts declare function resolveIndexedAccessType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/intersection.d.ts declare function resolveIntersectionType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/literal.d.ts declare function resolveLiteralType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; declare function getLiteralValue(typeNode: LiteralTypeNode): string | number | boolean | null; //#endregion //#region src/adapters/typescript/resolver/sub/mapped.d.ts declare function resolveMappedType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/object-literal.d.ts declare function resolveObjectLiteralType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/primitive.d.ts declare class PrimitiveResolver { protected registry: Registry; constructor(registry: Registry); resolve(node: TypeNode, parentNode?: Node): PrimitiveType | NeverType | VoidType | undefined; resolveSyntaxKind(syntaxKind: SyntaxKind): "string" | "boolean" | "void" | "undefined" | "null" | "number" | "bigint" | "never" | undefined; } //#endregion //#region src/adapters/typescript/resolver/sub/reference.d.ts declare class ReferenceResolver extends ResolverBase { protected typeChecker: TypeChecker; constructor(typeChecker: TypeChecker); merge(referenceTypes: ReferenceType[]): ReferenceType; mergeManyRefEnums(many: RefEnumType[]): RefEnumType; mergeRefEnums(first: RefEnumType, second: RefEnumType): RefEnumType; mergeManyRefObjects(many: RefObjectType[]): RefObjectType; mergeRefObject(first: RefObjectType, second: RefObjectType): RefObjectType; transformEnum(declaration: EnumDeclaration, enumName: string): RefEnumType; transformEnumMember(declaration: EnumMember, enumName: string): RefEnumType; } //#endregion //#region src/adapters/typescript/resolver/sub/tuple.d.ts declare function resolveTupleType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/type-operator.d.ts declare function resolveTypeOperatorType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/sub/union.d.ts declare function resolveUnionType(typeNode: TypeNode, ctx: SubResolverContext): Type | undefined; //#endregion //#region src/adapters/typescript/resolver/module.d.ts declare class TypeNodeResolver extends ResolverBase { private static readonly MAX_DEPTH; private readonly typeNode; private readonly current; private readonly parentNode?; private context; private readonly referencer; private readonly depth; private readonly primitiveResolver; private readonly referenceResolver; constructor(typeNode: TypeNode, current: IResolverContext & IReferenceTypeRegistry, parentNode?: Node, context?: TypeNodeResolverContext, referencer?: TypeNode, depth?: number); /** * @deprecated Use resolverCache.clear() on the context instead. * Kept for backward compatibility — no-ops since cache is now instance-scoped. */ static clearCache(): void; resolve(): Type; private createSubResolverContext; private resolveNestedType; private throwUnknownType; private resolveConditionalType; private resolveTypeReference; private static readonly CHECKER_RESOLVABLE_UTILITY_TYPES; private static isCheckerResolvableUtilityType; private resolveUtilityTypeViaChecker; /** * Shared checker delegation: resolves a type node by letting the TS * type checker evaluate it, converting back to a TypeNode, and * recursively resolving the result. */ private resolveTypeViaChecker; /** * Check if a type reference has type arguments that reference unbound * type parameters from this.context (e.g. `Awaited<T>` where T is a * generic parameter mapped in context). */ private hasUnboundContextArgs; private static resolveSpecialReference; private getDateType; private static getDesignatedModels; private getReferenceType; private getTypeAliasReference; private getModelReference; private static getRefTypeName; private contextualizedName; private createCircularDependencyResolver; private static nodeIsUsable; private getModelTypeDeclarations; private getModelTypeDeclaration; private hasFlag; private getSymbolAtLocation; private getModelProperties; private propertyFromSignature; private propertyFromDeclaration; private getModelAdditionalProperties; private typeArgumentsToContext; private getModelInheritedProperties; private getNodeDescription; private static getNodeFormat; private getNodeExample; protected getNodeExtensions(node: UsableDeclaration | PropertyDeclaration | ParameterDeclaration | EnumDeclaration): Extension[]; } //#endregion //#region src/adapters/typescript/resolver/cache.d.ts declare class ResolverCache implements IResolverCache { private referenceTypes; private inProgressTypes; getCachedType(name: string): ReferenceType | undefined; setCachedType(name: string, type: ReferenceType): void; isInProgress(name: string): boolean; markInProgress(name: string): void; clearInProgress(name: string): void; clear(): void; } //#endregion //#region src/adapters/typescript/resolver/utils.d.ts declare function getNodeDescription(node: Node, typeChecker: TypeChecker): string | undefined; declare function toTypeNodeOrFail(typeChecker: TypeChecker, ...args: Parameters<TypeChecker['typeToTypeNode']>): TypeNode; //#endregion //#region src/adapters/typescript/resolver/extension/module.d.ts declare function getNodeExtensions(node: Node, registry: Registry): Extension[]; //#endregion //#region src/adapters/typescript/node-utils/types.d.ts interface NodeDecorator { text: string; arguments: any[]; typeArguments: any[]; } //#endregion //#region src/adapters/typescript/node-utils/module.d.ts /** * Get Decorators for a specific node. * * @param node * @param isMatching */ declare function getNodeDecorators(node: Node, isMatching?: (data: NodeDecorator) => boolean): NodeDecorator[]; //#endregion //#region src/adapters/typescript/initializer.d.ts declare function getInitializerValue(initializer?: Expression, typeChecker?: TypeChecker, type?: Type): unknown; declare const hasInitializer: (node: Node) => node is HasInitializer; //#endregion //#region src/adapters/typescript/js-doc/constants.d.ts declare enum JSDocTagName { ABSTRACT = "abstract", ACCESS = "access", ALIAS = "alias", ASYNC = "async", /** * Alias for @extends */ AUGMENTS = "augments", AUTHOR = "author", DEFAULT = "default", DEPRECATED = "deprecated", DESCRIPTION = "description", EXAMPLE = "example", FORMAT = "format", IGNORE = "ignore", SUMMARY = "summary" } //#endregion //#region src/adapters/typescript/js-doc/module.d.ts declare function getJSDocDescription(node: Node, index?: number): string | undefined; declare function getJSDoc(node: Node, index?: number): undefined | JSDoc; declare function getJSDocTags(node: Node, isMatching?: `${JSDocTagName}` | `${JSDocTagName}`[] | (string & {}) | (string & {})[] | ((tag: JSDocTag) => boolean)): JSDocTag[]; declare function hasJSDocTag(node: Node, tagName: ((tag: JSDocTag) => boolean) | `${JSDocTagName}` | (string & {})): boolean; declare function getJSDocTagComment(node: Node, tagName: ((tag: JSDocTag) => boolean) | `${JSDocTagName}`): undefined | string; declare function getJSDocTagNames(node: Node, requireTagName?: boolean): string[]; //#endregion //#region src/adapters/typescript/js-doc/utils.d.ts declare function transformJSDocComment(input?: string | NodeArray<JSDocComment>): string | undefined; //#endregion //#region src/adapters/typescript/validator/module.d.ts declare function getDeclarationValidators(declaration: PropertyDeclaration | TypeAliasDeclaration | PropertySignature | ParameterDeclaration, name?: string): Record<string, Validator>; //#endregion //#region src/adapters/decorator/orchestrator/types.d.ts type ApplyHandlersOptions = { target: DecoratorTarget; host: DecoratorHost; resolveTypeNode: (node: TypeNode) => Type; parameterType?: () => Type | undefined; typeChecker?: TypeChecker; /** * Optional reporter for decorator sources that no handler matched. * The orchestrator builds a {@link DecoratorSource} for every decorator * on the node; if iteration finishes without any handler claiming a * source, this callback fires once for that source. */ onUnmatchedDecorator?: (report: UnmatchedDecoratorReport, source: DecoratorSource) => void; }; //#endregion //#region src/adapters/decorator/orchestrator/module.d.ts type DecoratorHandlerLike<D> = { match: Match; apply: (ctx: HandlerContext, draft: D) => void; }; type JsDocHandlerLike<D> = { match: JsDocMatch; apply: (ctx: JsDocHandlerContext, draft: D) => void; }; declare function buildHandlerContext(source: DecoratorSource, options: ApplyHandlersOptions): HandlerContext; declare function buildJsDocHandlerContext(source: JsDocSource, options: ApplyHandlersOptions): JsDocHandlerContext; declare function applyDecoratorHandlers<D>(node: Node, handlers: DecoratorHandlerLike<D>[], draft: D, options: ApplyHandlersOptions): void; declare function applyJsDocHandlers<D>(node: Node, handlers: JsDocHandlerLike<D>[], draft: D, options: ApplyHandlersOptions): void; //#endregion //#region src/adapters/decorator/typescript/types.d.ts type DecoratorSourceBuilderOptions = { target: DecoratorTarget; host: DecoratorHost; resolveTypeNode: (node: TypeNode) => Type; typeChecker?: TypeChecker; }; type JsDocSourceBuilderOptions = { target: DecoratorTarget; host: DecoratorHost; resolveTypeNode: (node: TypeNode) => Type; }; //#endregion //#region src/adapters/decorator/typescript/module.d.ts declare function buildDecoratorSources(node: Node, options: DecoratorSourceBuilderOptions): DecoratorSource[]; declare function buildJsDocSources(node: Node, options: JsDocSourceBuilderOptions): JsDocSource[]; //#endregion //#region src/adapters/decorator/typescript/utils.d.ts type RawDecorator = { name: string; arguments: DecoratorArgument[]; }; /** * Enumerate decorators on a TS node and classify their argument values without * going through the registry. Used by read-side consumers (type resolver, * extension extraction) that only need decorator names + argument values. */ declare function readNodeDecorators(node: Node, typeChecker?: TypeChecker): RawDecorator[]; declare function findDecoratorByName(node: Node, name: string, typeChecker?: TypeChecker): RawDecorator | undefined; declare function findDecoratorsByName(node: Node, name: string, typeChecker?: TypeChecker): RawDecorator[]; declare function hasDecoratorNamed(node: Node, name: string, typeChecker?: TypeChecker): boolean; declare function buildDecoratorArgument(expr: Expression, typeChecker?: TypeChecker): DecoratorArgument; //#endregion //#region src/adapters/filesystem/source-files.d.ts declare function scanSourceFiles(input: EntryPoint): Promise<string[]>; //#endregion //#region src/app/generate.d.ts declare function generateMetadata(options: MetadataGenerateOptions): Promise<Metadata>; //#endregion //#region src/app/generator/metadata/module.d.ts declare class MetadataGenerator implements IGeneratorContext, IMetadataGenerator { readonly nodes: Node[]; readonly typeChecker: TypeChecker; registry: Registry; readonly resolverCache: ResolverCache; readonly config: MetadataGeneratorOptions; private readonly program; private cache; private controllers; private referenceTypes; private circularDependencyResolvers; private unmatchedDecorators; constructor(context: MetadataGeneratorContext); generate(): Promise<Metadata>; private assertPresetProducedControllers; reportUnmatchedDecorator(report: UnmatchedDecoratorReport): void; private dispatchUnmatchedDecoratorReports; private formatUnmatchedSummary; protected buildNodesFromSourceFiles(): string; /** * Check if the source file path is in the ignored path list. * * @param filePath * @protected */ protected isIgnoredPath(filePath: string): boolean; /** * Check if the source file path is in the ignored path list. * * @param filePath * @protected */ protected isAllowedPath(filePath: string): boolean; isExportedNode(_node: Node): boolean; addReferenceType(referenceType: ReferenceType): void; getReferenceType(refName: string): ReferenceType | undefined; registerDependencyResolver(callback: DependencyResolver): void; private buildControllers; } //#endregion //#region src/app/generator/controller/module.d.ts declare class ControllerGenerator implements IControllerGenerator { protected readonly node: ClassDeclaration; protected readonly current: IGeneratorContext; constructor(node: ClassDeclaration, current: IGeneratorContext); isValid(): boolean; generate(): Controller | null; private applyOptions; protected buildMethods(controllerPaths: string[]): Method[]; private collectInheritedMethodDeclarations; private resolveBaseClassDeclaration; } //#endregion //#region src/app/generator/method/module.d.ts declare class MethodGenerator { protected readonly node: MethodDeclaration; protected readonly current: IGeneratorContext; constructor(node: MethodDeclaration, current: IGeneratorContext); getMethodName(): string; generate(controllerPaths: string[]): Method | null; private applyOptions; private resolveReturnType; private buildParameters; } //#endregion //#region src/app/generator/parameter/module.d.ts declare class ParameterGenerator implements IParameterGenerator { private readonly parameter; private readonly method; private readonly paths; private readonly current; constructor(parameter: ParameterDeclaration, method: string, paths: string[], current: IGeneratorContext); generate(): Parameter[]; private finalize; private draftToParameter; private decomposeObject; private pathContainsParam; private validatePathDecomposition; private validatePathName; private isLeafTypeSupported; private isLeafOrEnumOrUnion; private resolveType; private getParameterName; private getDescription; private getJsDocExamples; private applyOptions; } //#endregion //#region src/core/utils/array.d.ts declare function isStringArray(input: unknown): input is string[]; //#endregion //#region src/core/utils/object.d.ts declare function hasOwnProperty<Y extends PropertyKey>(obj: unknown, prop: Y): obj is Record<Y, unknown>; //#endregion //#region src/core/utils/path-normalize.d.ts declare function normalizePath(str: string): string; //#endregion export { ApplyHandlersOptions, CACHE_DEFAULT_MAX_AGE_MS, CACHE_FILE_PREFIX, CACHE_FILE_SUFFIX, CACHE_SCHEMA_VERSION, CacheClient, CacheData, CacheKeyParts, CacheOptions, CacheOptionsInput, ConfigError, ConfigErrorCode, ControllerGenerator, DecoratorSourceBuilderOptions, EntryPoint, EntryPointOptions, GeneratorError, GeneratorErrorCode, ICacheClient, IGeneratorContext, IMetadataGenerator, IReferenceTypeRegistry, IResolverContext, JSDocTagName, JsDocSourceBuilderOptions, MetadataError, MetadataGenerateOptions, MetadataGenerator, MetadataGeneratorContext, MetadataGeneratorOptions, MethodGenerator, NodeDecorator, OverrideToken, ParameterError, ParameterErrorCode, ParameterGenerator, PrimitiveResolver, RawDecorator, ReferenceResolver, ResolverBase, ResolverCache, ResolverError, SubResolverContext, TsCompilerOptions, TsConfig, TsconfigLoadContext, TypeNodeResolver, TypeNodeResolverContext, UsableDeclaration, ValidatorError, ValidatorErrorCode, applyDecoratorHandlers, applyJsDocHandlers, buildCacheOptions, buildDecoratorArgument, buildDecoratorSources, buildHandlerContext, buildJsDocHandlerContext, buildJsDocSources, composeCacheKey, findDecoratorByName, findDecoratorsByName, generateMetadata, getDeclarationValidators, getInitializerValue, getJSDoc, getJSDocDescription, getJSDocTagComment, getJSDocTagNames, getJSDocTags, getLiteralValue, getNodeDecorators, getNodeDescription, getNodeExtensions, hasDecoratorNamed, hasInitializer, hasJSDocTag, hasOwnProperty, hashCompilerOptions, hashRegistry, isGeneratorError, isResolverError, isStringArray, loadTSConfig, normalizePath, prettyLocationOfNode, prettyTroubleCause, readNodeDecorators, resolveArrayType, resolveIndexedAccessType, resolveIntersectionType, resolveLiteralType, resolveMappedType, resolveObjectLiteralType, resolveTupleType, resolveTypeOperatorType, resolveUnionType, scanSourceFiles, softLoadTsconfig, toTypeNodeOrFail, transformJSDocComment }; //# sourceMappingURL=index.d.mts.map