adorn-api 1.0.12 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/express/auth.d.ts +8 -0
- package/dist/adapter/express/auth.d.ts.map +1 -1
- package/dist/adapter/express/bootstrap.d.ts +12 -0
- package/dist/adapter/express/bootstrap.d.ts.map +1 -1
- package/dist/adapter/express/coercion.d.ts +81 -1
- package/dist/adapter/express/coercion.d.ts.map +1 -1
- package/dist/adapter/express/index.d.ts +1 -0
- package/dist/adapter/express/index.d.ts.map +1 -1
- package/dist/adapter/express/merge.d.ts +17 -0
- package/dist/adapter/express/merge.d.ts.map +1 -1
- package/dist/adapter/express/openapi.d.ts +55 -0
- package/dist/adapter/express/openapi.d.ts.map +1 -1
- package/dist/adapter/express/router.d.ts +6 -0
- package/dist/adapter/express/router.d.ts.map +1 -1
- package/dist/adapter/express/swagger.d.ts +6 -0
- package/dist/adapter/express/swagger.d.ts.map +1 -1
- package/dist/adapter/express/types.d.ts +26 -0
- package/dist/adapter/express/types.d.ts.map +1 -1
- package/dist/adapter/express/validation.d.ts +19 -2
- package/dist/adapter/express/validation.d.ts.map +1 -1
- package/dist/cli.cjs +1016 -445
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1016 -445
- package/dist/cli.js.map +1 -1
- package/dist/compiler/analyze/index.d.ts +5 -0
- package/dist/compiler/analyze/index.d.ts.map +1 -0
- package/dist/compiler/analyze/scanControllers.d.ts +52 -0
- package/dist/compiler/analyze/scanControllers.d.ts.map +1 -1
- package/dist/compiler/cache/isStale.d.ts +26 -0
- package/dist/compiler/cache/isStale.d.ts.map +1 -1
- package/dist/compiler/cache/loadArtifacts.d.ts +36 -0
- package/dist/compiler/cache/loadArtifacts.d.ts.map +1 -1
- package/dist/compiler/cache/schema.d.ts +14 -0
- package/dist/compiler/cache/schema.d.ts.map +1 -1
- package/dist/compiler/cache/writeCache.d.ts +6 -0
- package/dist/compiler/cache/writeCache.d.ts.map +1 -1
- package/dist/compiler/gems.d.ts +75 -0
- package/dist/compiler/gems.d.ts.map +1 -0
- package/dist/compiler/generator/index.d.ts +7 -0
- package/dist/compiler/generator/index.d.ts.map +1 -0
- package/dist/compiler/generator/manifest.d.ts +23 -0
- package/dist/compiler/generator/manifest.d.ts.map +1 -0
- package/dist/compiler/generator/openapi.d.ts +118 -0
- package/dist/compiler/generator/openapi.d.ts.map +1 -0
- package/dist/compiler/graph/builder.d.ts +24 -0
- package/dist/compiler/graph/builder.d.ts.map +1 -0
- package/dist/compiler/graph/index.d.ts +7 -0
- package/dist/compiler/graph/index.d.ts.map +1 -0
- package/dist/compiler/graph/schemaGraph.d.ts +67 -0
- package/dist/compiler/graph/schemaGraph.d.ts.map +1 -0
- package/dist/compiler/graph/types.d.ts +203 -0
- package/dist/compiler/graph/types.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +12 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/ir/index.d.ts +7 -0
- package/dist/compiler/ir/index.d.ts.map +1 -0
- package/dist/compiler/ir/pipeline.d.ts +82 -0
- package/dist/compiler/ir/pipeline.d.ts.map +1 -0
- package/dist/compiler/ir/stages.d.ts +40 -0
- package/dist/compiler/ir/stages.d.ts.map +1 -0
- package/dist/compiler/ir/visitor.d.ts +98 -0
- package/dist/compiler/ir/visitor.d.ts.map +1 -0
- package/dist/compiler/manifest/emit.d.ts +14 -0
- package/dist/compiler/manifest/emit.d.ts.map +1 -1
- package/dist/compiler/manifest/format.d.ts +42 -0
- package/dist/compiler/manifest/format.d.ts.map +1 -1
- package/dist/compiler/manifest/index.d.ts +6 -0
- package/dist/compiler/manifest/index.d.ts.map +1 -0
- package/dist/compiler/runner/createProgram.d.ts +16 -0
- package/dist/compiler/runner/createProgram.d.ts.map +1 -1
- package/dist/compiler/runner/index.d.ts +5 -0
- package/dist/compiler/runner/index.d.ts.map +1 -0
- package/dist/compiler/schema/extractAnnotations.d.ts +47 -0
- package/dist/compiler/schema/extractAnnotations.d.ts.map +1 -1
- package/dist/compiler/schema/index.d.ts +6 -0
- package/dist/compiler/schema/index.d.ts.map +1 -0
- package/dist/compiler/schema/intersectionHandler.d.ts +44 -0
- package/dist/compiler/schema/intersectionHandler.d.ts.map +1 -0
- package/dist/compiler/schema/objectHandler.d.ts +106 -0
- package/dist/compiler/schema/objectHandler.d.ts.map +1 -0
- package/dist/compiler/schema/openapi.d.ts +16 -1
- package/dist/compiler/schema/openapi.d.ts.map +1 -1
- package/dist/compiler/schema/parameters.d.ts +90 -0
- package/dist/compiler/schema/parameters.d.ts.map +1 -0
- package/dist/compiler/schema/primitives.d.ts +68 -0
- package/dist/compiler/schema/primitives.d.ts.map +1 -0
- package/dist/compiler/schema/typeToJsonSchema.d.ts +22 -51
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -1
- package/dist/compiler/schema/types.d.ts +69 -0
- package/dist/compiler/schema/types.d.ts.map +1 -0
- package/dist/compiler/schema/unionHandler.d.ts +70 -0
- package/dist/compiler/schema/unionHandler.d.ts.map +1 -0
- package/dist/compiler/transform/dedup.d.ts +35 -0
- package/dist/compiler/transform/dedup.d.ts.map +1 -0
- package/dist/compiler/transform/flatten.d.ts +50 -0
- package/dist/compiler/transform/flatten.d.ts.map +1 -0
- package/dist/compiler/transform/index.d.ts +7 -0
- package/dist/compiler/transform/index.d.ts.map +1 -0
- package/dist/compiler/transform/inline.d.ts +46 -0
- package/dist/compiler/transform/inline.d.ts.map +1 -0
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts +16 -0
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts.map +1 -1
- package/dist/compiler/validation/index.d.ts +5 -0
- package/dist/compiler/validation/index.d.ts.map +1 -0
- package/dist/decorators/Auth.d.ts +17 -0
- package/dist/decorators/Auth.d.ts.map +1 -1
- package/dist/decorators/Controller.d.ts +15 -0
- package/dist/decorators/Controller.d.ts.map +1 -1
- package/dist/decorators/Public.d.ts +13 -0
- package/dist/decorators/Public.d.ts.map +1 -1
- package/dist/decorators/Use.d.ts +18 -0
- package/dist/decorators/Use.d.ts.map +1 -1
- package/dist/decorators/methods.d.ts +20 -0
- package/dist/decorators/methods.d.ts.map +1 -1
- package/dist/express.cjs +73 -54
- package/dist/express.cjs.map +1 -1
- package/dist/express.js +73 -54
- package/dist/express.js.map +1 -1
- package/dist/http.d.ts +1 -2
- package/dist/http.d.ts.map +1 -1
- package/dist/index.cjs +161 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +156 -3
- package/dist/index.js.map +1 -1
- package/dist/metal/applyListQuery.d.ts +73 -0
- package/dist/metal/applyListQuery.d.ts.map +1 -1
- package/dist/metal/index.cjs +2 -2
- package/dist/metal/index.cjs.map +1 -1
- package/dist/metal/index.d.ts +4 -0
- package/dist/metal/index.d.ts.map +1 -1
- package/dist/metal/index.js +2 -2
- package/dist/metal/index.js.map +1 -1
- package/dist/metal/listQuery.d.ts +19 -0
- package/dist/metal/listQuery.d.ts.map +1 -1
- package/dist/metal/queryOptions.d.ts +8 -0
- package/dist/metal/queryOptions.d.ts.map +1 -1
- package/dist/metal/readMetalBag.d.ts +36 -0
- package/dist/metal/readMetalBag.d.ts.map +1 -1
- package/dist/metal/registerMetalEntities.d.ts +20 -0
- package/dist/metal/registerMetalEntities.d.ts.map +1 -1
- package/dist/metal/schemaFromEntity.d.ts +30 -0
- package/dist/metal/schemaFromEntity.d.ts.map +1 -1
- package/dist/metal/searchWhere.d.ts +39 -0
- package/dist/metal/searchWhere.d.ts.map +1 -1
- package/dist/metal/symbolMetadata.d.ts +6 -0
- package/dist/metal/symbolMetadata.d.ts.map +1 -1
- package/dist/runtime/auth/runtime.d.ts +155 -6
- package/dist/runtime/auth/runtime.d.ts.map +1 -1
- package/dist/runtime/metadata/bucket.d.ts +1 -2
- package/dist/runtime/metadata/bucket.d.ts.map +1 -1
- package/dist/runtime/metadata/key.d.ts +1 -1
- package/dist/runtime/metadata/key.d.ts.map +1 -1
- package/dist/runtime/metadata/read.d.ts +1 -2
- package/dist/runtime/metadata/read.d.ts.map +1 -1
- package/dist/runtime/metadata/types.d.ts +74 -0
- package/dist/runtime/metadata/types.d.ts.map +1 -1
- package/dist/runtime/polyfill.d.ts +1 -1
- package/dist/runtime/polyfill.d.ts.map +1 -1
- package/dist/runtime/upload.d.ts +37 -0
- package/dist/runtime/upload.d.ts.map +1 -1
- package/dist/runtime/validation/ajv.d.ts +100 -0
- package/dist/runtime/validation/ajv.d.ts.map +1 -1
- package/dist/runtime/validation/index.d.ts +9 -0
- package/dist/runtime/validation/index.d.ts.map +1 -1
- package/dist/scripts/adorn-example.cjs +238 -6
- package/dist/scripts/adorn-example.cjs.map +1 -1
- package/dist/utils/port.d.ts +9 -0
- package/dist/utils/port.d.ts.map +1 -0
- package/package.json +4 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime/polyfill.ts","../src/runtime/metadata/key.ts","../src/runtime/metadata/bucket.ts","../src/decorators/Controller.ts","../src/decorators/methods.ts","../src/decorators/Use.ts","../src/decorators/Auth.ts","../src/decorators/Public.ts","../src/runtime/metadata/read.ts","../src/schema/decorators.ts","../src/runtime/validation/ajv.ts","../src/http.ts","../src/compiler/cache/loadArtifacts.ts"],"sourcesContent":["// Polyfill Symbol.metadata for environments that don't support it\n// Must run before any decorated classes are imported\n(Symbol as any).metadata ??= Symbol(\"Symbol.metadata\");\n\n// Export a symbol to prevent tree-shaking\nexport const ADORN_POLYFILL = Symbol(\"adorn-polyfill\");\n","export const ADORN_META = Symbol.for(\"adorn-api/meta\");\n","import { ADORN_META } from \"./key.js\";\nimport type { AdornBucket } from \"./types.js\";\n\nexport function getBucket(metadata: DecoratorMetadata): AdornBucket {\n if (!metadata) {\n throw new Error(\"Decorator context.metadata is undefined. Ensure Symbol.metadata polyfill runs before decorators.\");\n }\n let bucket = metadata[ADORN_META] as AdornBucket | undefined;\n if (!bucket) {\n bucket = { ops: [], controllerUse: [] };\n metadata[ADORN_META] = bucket;\n }\n if (!bucket.controllerUse) {\n bucket.controllerUse = [];\n }\n return bucket;\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\n\nexport function Controller(basePath: string) {\n return function <T extends new (...args: any[]) => any>(\n target: T,\n context: ClassDecoratorContext<T>\n ): T | void {\n const bucket = getBucket(context.metadata);\n bucket.basePath = basePath;\n };\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { HttpMethod } from \"../runtime/metadata/types.js\";\n\nfunction createMethodDecorator(httpMethod: HttpMethod, path: string) {\n return function <T extends (...args: any[]) => any>(\n target: T,\n context: ClassMethodDecoratorContext<any, T>\n ): T | void {\n if (context.private || context.static) {\n return;\n }\n\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod,\n path,\n methodName,\n };\n bucket.ops.push(op);\n } else {\n op.httpMethod = httpMethod;\n op.path = path;\n }\n };\n}\n\nexport const Get = (path: string) => createMethodDecorator(\"GET\", path);\nexport const Post = (path: string) => createMethodDecorator(\"POST\", path);\nexport const Put = (path: string) => createMethodDecorator(\"PUT\", path);\nexport const Patch = (path: string) => createMethodDecorator(\"PATCH\", path);\nexport const Delete = (path: string) => createMethodDecorator(\"DELETE\", path);\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { ExpressMw, HttpMethod } from \"../runtime/metadata/types.js\";\n\ntype UseTarget = string | ExpressMw;\n\nexport function Use(...middleware: UseTarget[]) {\n return function (\n target: any,\n context: ClassDecoratorContext | ClassMethodDecoratorContext\n ) {\n if (context.kind === \"class\") {\n const bucket = getBucket(context.metadata);\n if (!bucket.controllerUse) {\n bucket.controllerUse = [];\n }\n bucket.controllerUse.push(...middleware);\n } else if (context.kind === \"method\") {\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod: \"GET\" as HttpMethod,\n path: \"/\",\n methodName,\n };\n bucket.ops.push(op);\n }\n if (!op.use) {\n op.use = [];\n }\n op.use.push(...middleware);\n } else {\n throw new Error(\"@Use decorator can only be applied to classes or methods\");\n }\n };\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { AuthMeta, HttpMethod } from \"../runtime/metadata/types.js\";\n\nexport function Auth(scheme: string, options?: { scopes?: string[]; optional?: boolean }) {\n return function (\n target: any,\n context: ClassMethodDecoratorContext\n ) {\n if (context.kind !== \"method\") {\n throw new Error(\"@Auth decorator can only be applied to methods\");\n }\n\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod: \"GET\" as HttpMethod,\n path: \"/\",\n methodName,\n };\n bucket.ops.push(op);\n }\n\n op.auth = {\n scheme,\n scopes: options?.scopes,\n optional: options?.optional ?? false,\n };\n };\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { HttpMethod } from \"../runtime/metadata/types.js\";\n\nexport function Public() {\n return function (\n target: any,\n context: ClassMethodDecoratorContext\n ) {\n if (context.kind !== \"method\") {\n throw new Error(\"@Public decorator can only be applied to methods\");\n }\n\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod: \"GET\" as HttpMethod,\n path: \"/\",\n methodName,\n };\n bucket.ops.push(op);\n }\n\n op.auth = \"public\";\n };\n}\n","import { ADORN_META } from \"./key.js\";\nimport type { AdornBucket } from \"./types.js\";\n\nexport function readAdornBucket(ctor: Function): AdornBucket | null {\n const metaSym = (Symbol as any).metadata as symbol | undefined;\n if (!metaSym) {\n return null;\n }\n\n const classMetadata = (ctor as any)[metaSym] as DecoratorMetadata | undefined;\n if (!classMetadata) {\n return null;\n }\n\n const bucket = classMetadata[ADORN_META] as AdornBucket | undefined;\n return bucket ?? null;\n}\n","const ADORN_META = Symbol.for(\"adorn-api.metadata\");\n\ninterface SchemaFrag {\n [key: string]: unknown;\n}\n\ninterface SchemaMetadata {\n schema: {\n props: Record<string, SchemaFrag[]>;\n };\n}\n\nfunction getOrCreateMetadata(metadata: Record<PropertyKey, unknown>): SchemaMetadata {\n const meta = (metadata[ADORN_META] ??= {}) as SchemaMetadata;\n meta.schema ??= { props: {} };\n return meta;\n}\n\nfunction pushSchemaFrag(\n target: Object,\n propertyKey: string | symbol,\n metadata: Record<PropertyKey, unknown>,\n frag: SchemaFrag\n): void {\n const meta = getOrCreateMetadata(metadata);\n const props = meta.schema.props;\n (props[propertyKey as string] ??= []).push(frag);\n}\n\ntype PropertyDecorator = (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => void;\n\nexport function Schema(frag: SchemaFrag): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, frag);\n };\n}\n\nexport function Min(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minimum: n });\n };\n}\n\nexport function Max(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maximum: n });\n };\n}\n\nexport function ExclusiveMin(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { exclusiveMinimum: n });\n };\n}\n\nexport function ExclusiveMax(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { exclusiveMaximum: n });\n };\n}\n\nexport function MinLength(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minLength: n });\n };\n}\n\nexport function MaxLength(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maxLength: n });\n };\n}\n\nexport function Pattern(re: RegExp | string): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { pattern: typeof re === \"string\" ? re : re.source });\n };\n}\n\nexport function Format(fmt: string): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { format: fmt });\n };\n}\n\nexport function MinItems(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minItems: n });\n };\n}\n\nexport function MaxItems(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maxItems: n });\n };\n}\n\nexport function MinProperties(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minProperties: n });\n };\n}\n\nexport function MaxProperties(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maxProperties: n });\n };\n}\n\nexport function MultipleOf(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { multipleOf: n });\n };\n}\n\nexport function Example(value: unknown): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { example: value });\n };\n}\n\nexport function Examples(values: unknown[]): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { examples: values });\n };\n}\n\nexport function Description(desc: string): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { description: desc });\n };\n}\n\nexport function Enum<T extends string | number>(vals: T[]): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { enum: vals });\n };\n}\n\nexport function Const<T>(val: T): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { const: val });\n };\n}\n\nexport function Default<T>(val: T): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { default: val });\n };\n}\n\nexport function AdditionalProperties(value: boolean | Record<string, unknown>): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { additionalProperties: value });\n };\n}\n\nexport function Closed(): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { additionalProperties: false });\n };\n}\n\nexport function ClosedUnevaluated(): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { unevaluatedProperties: false });\n };\n}\n\nexport function Union(mode: \"anyOf\" | \"oneOf\" | \"allOf\"): ClassDecorator {\n return function (target: Function): void {\n (target as any)[ADORN_META] = (target as any)[ADORN_META] ?? {};\n const meta = (target as any)[ADORN_META] as SchemaMetadata;\n meta.schema = meta.schema ?? { props: {} };\n (meta.schema as any).unionMode = mode;\n };\n}\n\nexport { ADORN_META };\nexport type { SchemaFrag, SchemaMetadata };\n","import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { ErrorObject } from \"ajv\";\n\nexport interface ValidationError {\n path: string;\n message: string;\n keyword: string;\n params: Record<string, unknown>;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[] | null;\n}\n\nexport class ValidationErrorResponse extends Error {\n constructor(\n public statusCode: number,\n public errors: ValidationError[]\n ) {\n super(\"Validation failed\");\n this.name = \"ValidationErrorResponse\";\n }\n}\n\nexport function createValidator() {\n const ajv = new Ajv.default({\n allErrors: true,\n coerceTypes: false,\n strict: false,\n validateFormats: true,\n });\n\n addFormats.default(ajv);\n\n ajv.addFormat(\"br-phone\", /^\\(\\d{2}\\)\\s\\d{5}-\\d{4}$/);\n\n return ajv;\n}\n\nexport function validateData(\n ajv: ReturnType<typeof createValidator>,\n data: unknown,\n schema: Record<string, unknown>,\n dataPath: string = \"#\"\n): ValidationResult {\n const validate = ajv.compile(schema);\n const valid = validate(data);\n\n if (valid) {\n return { valid: true, errors: null };\n }\n\n const errors: ValidationError[] = (validate.errors || []).map((err: ErrorObject) => ({\n path: formatErrorPath(dataPath, err),\n message: err.message || \"Invalid value\",\n keyword: err.keyword,\n params: err.params as Record<string, unknown>,\n }));\n\n return { valid: false, errors };\n}\n\nfunction formatErrorPath(basePath: string, err: ErrorObject): string {\n const instancePath = err.instancePath;\n\n if (!instancePath || instancePath === \"\") {\n return basePath;\n }\n\n if (basePath === \"#\" || basePath.endsWith(\"/\")) {\n return `${basePath}${instancePath.slice(1)}`;\n }\n\n return `${basePath}${instancePath}`;\n}\n\nexport function formatValidationErrors(errors: ValidationError[]): Record<string, unknown> {\n const formatted: Record<string, string[]> = {};\n\n for (const error of errors) {\n const path = error.path || \"body\";\n if (!formatted[path]) {\n formatted[path] = [];\n }\n formatted[path].push(error.message);\n }\n\n return {\n error: \"Validation failed\",\n details: formatted,\n };\n}\n","import \"./runtime/polyfill.js\";\n\nconst ADORN_META = Symbol.for(\"adorn-api.metadata\");\n\ninterface HttpMetadata {\n consumes?: string[];\n produces?: string[];\n fileParts?: Record<string, FilePartOptions>;\n cookies?: Record<string, boolean>;\n}\n\ninterface FilePartOptions {\n contentType?: string;\n headers?: Record<string, string>;\n}\n\ntype DecoratorMetadata = Record<PropertyKey, unknown> & { [ADORN_META]?: HttpMetadata };\n\nfunction getMetadata(target: Object | DecoratorMetadata): HttpMetadata {\n const host = target as DecoratorMetadata;\n const metadata = host[ADORN_META] ?? {};\n host[ADORN_META] = metadata;\n return metadata;\n}\n\nexport type PartType = FilePartOptions;\n\nexport function PartType(contentTypeOrOptions: string | FilePartOptions): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n const metadata = getMetadata(target);\n const options: FilePartOptions = typeof contentTypeOrOptions === \"string\"\n ? { contentType: contentTypeOrOptions }\n : contentTypeOrOptions;\n metadata.fileParts ??= {};\n metadata.fileParts[propertyKey.toString()] = options;\n };\n}\n\nexport function File(): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n const metadata = getMetadata(target);\n metadata.fileParts ??= {};\n metadata.fileParts[propertyKey.toString()] = metadata.fileParts[propertyKey.toString()] ?? {};\n };\n}\n\nexport function Consumes(...contentTypes: string[]): ClassDecorator {\n return function (target: Function): void {\n const metadata = getMetadata(target.prototype);\n metadata.consumes = contentTypes;\n };\n}\n\nexport function Produces(...contentTypes: string[]): ClassDecorator {\n return function (target: Function): void {\n const metadata = getMetadata(target.prototype);\n metadata.produces = contentTypes;\n };\n}\n\nexport type Query<T = any> = T;\nexport type Body<T = any> = T;\nexport type Headers<T = any> = T;\nexport type Cookies<T = any> = T;\n\nexport interface PaginationParams {\n page: number;\n pageSize: number;\n}\n\nexport type PaginatedResponse<T> = {\n items: T[];\n totalItems: number;\n page: number;\n pageSize: number;\n};\n\nexport { ADORN_META };\nexport type { HttpMetadata, FilePartOptions };\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { stat } from \"node:fs/promises\";\n\ninterface OpenApi {\n openapi: string;\n components?: {\n schemas?: Record<string, unknown>;\n };\n paths?: Record<string, unknown>;\n info?: Record<string, unknown>;\n security?: Array<Record<string, string[]>>;\n}\n\ninterface Manifest {\n manifestVersion: number;\n generatedAt: string;\n generator: {\n name: string;\n version: string;\n typescript: string;\n };\n schemas: {\n kind: string;\n file: string;\n componentsSchemasPointer: string;\n };\n validation: {\n mode: \"none\" | \"ajv-runtime\" | \"precompiled\";\n precompiledModule: string | null;\n };\n controllers: Array<{\n controllerId: string;\n basePath: string;\n operations: Array<{\n operationId: string;\n http: {\n method: string;\n path: string;\n };\n handler: {\n methodName: string;\n };\n args: {\n body: {\n index: number;\n required: boolean;\n contentType: string;\n schemaRef: string;\n } | null;\n path: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n query: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n headers: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n cookies: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n };\n responses: Array<{\n status: number;\n contentType: string;\n schemaRef: string;\n isArray?: boolean;\n }>;\n }>;\n }>;\n}\n\ninterface ValidatorModule {\n validators: Record<string, {\n body?: (data: unknown) => boolean;\n response: Record<string, (data: unknown) => boolean>;\n }>;\n validateBody: (operationId: string, data: unknown) => { ok: boolean; errors: unknown[] | null };\n validateResponse: (operationId: string, status: number, contentType: string, data: unknown) => { ok: boolean; errors: unknown[] | null };\n}\n\ninterface ArtifactCacheEntry {\n openapi: OpenApi | null;\n manifest: Manifest | null;\n validators: ValidatorModule | null;\n mtimes: {\n openapi: number | null;\n manifest: number | null;\n validators: number | null;\n };\n}\n\nconst artifactCache = new Map<string, ArtifactCacheEntry>();\n\nasync function getMtime(filePath: string): Promise<number | null> {\n try {\n const stats = await stat(filePath);\n return stats.mtimeMs;\n } catch {\n return null;\n }\n}\n\nexport interface LoadArtifactsOptions {\n outDir: string;\n}\n\nexport interface LoadedArtifacts {\n openapi: OpenApi;\n manifest: Manifest;\n validators: ValidatorModule | null;\n}\n\nexport async function loadArtifacts(options: LoadArtifactsOptions): Promise<LoadedArtifacts> {\n const { outDir } = options;\n const cacheKey = path.resolve(outDir);\n\n let entry = artifactCache.get(cacheKey);\n\n const openapiPath = path.join(outDir, \"openapi.json\");\n const manifestPath = path.join(outDir, \"manifest.json\");\n const validatorsPath = path.join(outDir, \"validators.mjs\");\n\n const openapiMtime = await getMtime(openapiPath);\n const manifestMtime = await getMtime(manifestPath);\n const validatorsMtime = await getMtime(validatorsPath);\n\n if (entry) {\n const mtimesMatch = \n entry.mtimes.openapi === openapiMtime &&\n entry.mtimes.manifest === manifestMtime &&\n entry.mtimes.validators === validatorsMtime;\n\n if (mtimesMatch) {\n if (entry.openapi && entry.manifest) {\n return {\n openapi: entry.openapi,\n manifest: entry.manifest,\n validators: entry.validators,\n };\n }\n }\n }\n\n const openapiContent = fs.readFileSync(openapiPath, \"utf-8\");\n const manifestContent = fs.readFileSync(manifestPath, \"utf-8\");\n\n const openapi = JSON.parse(openapiContent) as OpenApi;\n const manifest = JSON.parse(manifestContent) as Manifest;\n\n let validators: ValidatorModule | null = null;\n\n if (manifest.validation.mode === \"precompiled\" && manifest.validation.precompiledModule) {\n try {\n const validatorsModule = await import(path.join(outDir, manifest.validation.precompiledModule));\n validators = validatorsModule as ValidatorModule;\n } catch (err) {\n console.warn(`Failed to load precompiled validators: ${err}`);\n }\n }\n\n artifactCache.set(cacheKey, {\n openapi,\n manifest,\n validators,\n mtimes: {\n openapi: openapiMtime,\n manifest: manifestMtime,\n validators: validatorsMtime,\n },\n });\n\n return {\n openapi,\n manifest,\n validators,\n };\n}\n\nexport function clearArtifactCache(outDir?: string): void {\n if (outDir) {\n const cacheKey = path.resolve(outDir);\n artifactCache.delete(cacheKey);\n } else {\n artifactCache.clear();\n }\n}\n\nexport function getArtifactCacheStats(): { size: number; keys: string[] } {\n return {\n size: artifactCache.size,\n keys: Array.from(artifactCache.keys()),\n };\n}\n"],"mappings":"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","names":["path","op","op","op","op","ADORN_META","path","ADORN_META"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime/polyfill.ts","../src/runtime/metadata/key.ts","../src/runtime/metadata/bucket.ts","../src/decorators/Controller.ts","../src/decorators/methods.ts","../src/decorators/Use.ts","../src/decorators/Auth.ts","../src/decorators/Public.ts","../src/runtime/metadata/read.ts","../src/schema/decorators.ts","../src/runtime/validation/ajv.ts","../src/http.ts","../src/compiler/cache/loadArtifacts.ts","../src/utils/port.ts"],"sourcesContent":["/**\n * Polyfill for Symbol.metadata in environments that don't natively support it.\n * This polyfill must run before any decorated classes are imported to ensure\n * the metadata API is available for decorator metadata storage.\n * \n * @remarks\n * This module provides a global polyfill for the `Symbol.metadata` well-known symbol.\n * Some JavaScript environments (like older browsers or non-standard runtimes) may not\n * natively support this symbol, which is required by the adorn-api decorator system.\n * \n * @example\n * ```typescript\n * // Import this first before any decorated classes\n * import \"adorn-api/runtime/polyfill\";\n * \n * // Now decorators can safely use Symbol.metadata\n * @Controller()\n * class MyController { }\n * ```\n * \n * @package\n */\n(Symbol as any).metadata ??= Symbol(\"Symbol.metadata\");\n\n/**\n * Export symbol to prevent tree-shaking of the polyfill module.\n * This ensures the polyfill code is retained in production builds.\n * \n * @internal\n */\nexport const ADORN_POLYFILL = Symbol(\"adorn-polyfill\");\n","/**\n * Symbol key used to store Adorn metadata in class decorator metadata.\n * \n * @remarks\n * This Symbol.for() call creates a global symbol that is used as the key\n * for storing Adorn-specific metadata in the decorator metadata store.\n * Using Symbol.for() ensures the same symbol is used across different\n * module loads.\n * \n * @internal\n */\nexport const ADORN_META = Symbol.for(\"adorn-api/meta\");\n","import { ADORN_META } from \"./key.js\";\nimport type { AdornBucket } from \"./types.js\";\n\n/**\n * Retrieves the AdornBucket from decorator metadata, creating it if necessary.\n * \n * @remarks\n * This function safely accesses the AdornBucket stored in decorator metadata.\n * If the bucket doesn't exist, it creates a new one with default values.\n * The bucket is stored under the ADORN_META symbol key.\n * \n * @param metadata - The decorator context metadata object\n * @returns The AdornBucket for the decorated class\n * @throws Error if metadata is undefined (polyfill not loaded)\n * \n * @internal\n */\nexport function getBucket(metadata: DecoratorMetadata): AdornBucket {\n if (!metadata) {\n throw new Error(\"Decorator context.metadata is undefined. Ensure Symbol.metadata polyfill runs before decorators.\");\n }\n let bucket = metadata[ADORN_META] as AdornBucket | undefined;\n if (!bucket) {\n bucket = { ops: [], controllerUse: [] };\n metadata[ADORN_META] = bucket;\n }\n if (!bucket.controllerUse) {\n bucket.controllerUse = [];\n }\n return bucket;\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\n\n/**\n * Decorator to mark a class as a controller with a base path.\n * All methods in the controller will be relative to this base path.\n * \n * @param basePath - The base path for all routes in this controller\n * \n * @example\n * ```ts\n * @Controller(\"/users\")\n * export class UsersController {\n * @Get(\"/:id\")\n * getUser() { }\n * }\n * ```\n */\nexport function Controller(basePath: string) {\n return function <T extends new (...args: any[]) => any>(\n target: T,\n context: ClassDecoratorContext<T>\n ): T | void {\n const bucket = getBucket(context.metadata);\n bucket.basePath = basePath;\n };\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { HttpMethod } from \"../runtime/metadata/types.js\";\n\nfunction createMethodDecorator(httpMethod: HttpMethod, path: string) {\n return function <T extends (...args: any[]) => any>(\n target: T,\n context: ClassMethodDecoratorContext<any, T>\n ): T | void {\n if (context.private || context.static) {\n return;\n }\n\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod,\n path,\n methodName,\n };\n bucket.ops.push(op);\n } else {\n op.httpMethod = httpMethod;\n op.path = path;\n }\n };\n}\n\n/**\n * Creates a method decorator for HTTP GET requests.\n * @param path - The route path for this endpoint\n */\nexport const Get = (path: string) => createMethodDecorator(\"GET\", path);\n\n/**\n * Creates a method decorator for HTTP POST requests.\n * @param path - The route path for this endpoint\n */\nexport const Post = (path: string) => createMethodDecorator(\"POST\", path);\n\n/**\n * Creates a method decorator for HTTP PUT requests.\n * @param path - The route path for this endpoint\n */\nexport const Put = (path: string) => createMethodDecorator(\"PUT\", path);\n\n/**\n * Creates a method decorator for HTTP PATCH requests.\n * @param path - The route path for this endpoint\n */\nexport const Patch = (path: string) => createMethodDecorator(\"PATCH\", path);\n\n/**\n * Creates a method decorator for HTTP DELETE requests.\n * @param path - The route path for this endpoint\n */\nexport const Delete = (path: string) => createMethodDecorator(\"DELETE\", path);\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { ExpressMw, HttpMethod } from \"../runtime/metadata/types.js\";\n\ntype UseTarget = string | ExpressMw;\n\n/**\n * Decorator to apply middleware to a controller class or individual methods.\n * \n * @param middleware - One or more middleware functions or paths (for path-specific middleware)\n * \n * @example\n * ```ts\n * // Apply to entire controller\n * @Use(cors(), helmet())\n * @Controller(\"/api\")\n * class ApiController { }\n * \n * // Apply to specific method\n * @Use(express.json())\n * @Post(\"/upload\")\n * uploadFile() { }\n * ```\n */\nexport function Use(...middleware: UseTarget[]) {\n return function (\n target: any,\n context: ClassDecoratorContext | ClassMethodDecoratorContext\n ) {\n if (context.kind === \"class\") {\n const bucket = getBucket(context.metadata);\n if (!bucket.controllerUse) {\n bucket.controllerUse = [];\n }\n bucket.controllerUse.push(...middleware);\n } else if (context.kind === \"method\") {\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod: \"GET\" as HttpMethod,\n path: \"/\",\n methodName,\n };\n bucket.ops.push(op);\n }\n if (!op.use) {\n op.use = [];\n }\n op.use.push(...middleware);\n } else {\n throw new Error(\"@Use decorator can only be applied to classes or methods\");\n }\n };\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { HttpMethod } from \"../runtime/metadata/types.js\";\n\n/**\n * Decorator to mark a method as requiring authentication.\n * \n * @param scheme - The authentication scheme to use (e.g., \"Bearer\", \"Basic\")\n * @param options - Optional authentication configuration\n * @param options.scopes - Required permission scopes for this endpoint\n * @param options.optional - If true, authentication is optional (useful for mixed auth endpoints)\n * \n * @example\n * ```ts\n * @Auth(\"Bearer\", { scopes: [\"admin\"] })\n * @Delete(\"/users/:id\")\n * deleteUser() {\n * // Implementation\n * }\n * ```\n */\nexport function Auth(scheme: string, options?: { scopes?: string[]; optional?: boolean }) {\n return function (\n target: any,\n context: ClassMethodDecoratorContext\n ) {\n if (context.kind !== \"method\") {\n throw new Error(\"@Auth decorator can only be applied to methods\");\n }\n\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod: \"GET\" as HttpMethod,\n path: \"/\",\n methodName,\n };\n bucket.ops.push(op);\n }\n\n op.auth = {\n scheme,\n scopes: options?.scopes,\n optional: options?.optional ?? false,\n };\n };\n}\n","import { getBucket } from \"../runtime/metadata/bucket.js\";\nimport type { HttpMethod } from \"../runtime/metadata/types.js\";\n\n/**\n * Decorator to mark a method as public (no authentication required).\n * Use this to explicitly allow unauthenticated access to specific endpoints.\n * \n * @example\n * ```ts\n * @Public()\n * @Get(\"/health\")\n * healthCheck() {\n * return { status: \"ok\" };\n * }\n * ```\n */\nexport function Public() {\n return function (\n target: any,\n context: ClassMethodDecoratorContext\n ) {\n if (context.kind !== \"method\") {\n throw new Error(\"@Public decorator can only be applied to methods\");\n }\n\n const methodName = String(context.name);\n const bucket = getBucket(context.metadata);\n let op = bucket.ops.find(op => op.methodName === methodName);\n if (!op) {\n op = {\n httpMethod: \"GET\" as HttpMethod,\n path: \"/\",\n methodName,\n };\n bucket.ops.push(op);\n }\n\n op.auth = \"public\";\n };\n}\n","import { ADORN_META } from \"./key.js\";\nimport type { AdornBucket } from \"./types.js\";\n\n/**\n * Reads the AdornBucket metadata from a class constructor.\n * \n * @remarks\n * This function retrieves the AdornBucket stored on a class via the\n * Symbol.metadata mechanism. It safely handles cases where metadata\n * is not available (e.g., polyfill not loaded or class not decorated).\n * \n * @param ctor - The class constructor to read metadata from\n * @returns The AdornBucket if found, or null if not available\n * \n * @example\n * ```typescript\n * @Controller()\n * class MyController { }\n * \n * const bucket = readAdornBucket(MyController);\n * if (bucket) {\n * console.log(bucket.ops);\n * }\n * ```\n * \n * @internal\n */\nexport function readAdornBucket(ctor: Function): AdornBucket | null {\n const metaSym = (Symbol as any).metadata as symbol | undefined;\n if (!metaSym) {\n return null;\n }\n\n const classMetadata = (ctor as any)[metaSym] as DecoratorMetadata | undefined;\n if (!classMetadata) {\n return null;\n }\n\n const bucket = classMetadata[ADORN_META] as AdornBucket | undefined;\n return bucket ?? null;\n}\n","const ADORN_META = Symbol.for(\"adorn-api.metadata\");\n\ninterface SchemaFrag {\n [key: string]: unknown;\n}\n\ninterface SchemaMetadata {\n schema: {\n props: Record<string, SchemaFrag[]>;\n };\n}\n\nfunction getOrCreateMetadata(metadata: Record<PropertyKey, unknown>): SchemaMetadata {\n const meta = (metadata[ADORN_META] ??= {}) as SchemaMetadata;\n meta.schema ??= { props: {} };\n return meta;\n}\n\nfunction pushSchemaFrag(\n target: Object,\n propertyKey: string | symbol,\n metadata: Record<PropertyKey, unknown>,\n frag: SchemaFrag\n): void {\n const meta = getOrCreateMetadata(metadata);\n const props = meta.schema.props;\n (props[propertyKey as string] ??= []).push(frag);\n}\n\ntype PropertyDecorator = (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => void;\n\nexport function Schema(frag: SchemaFrag): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, frag);\n };\n}\n\nexport function Min(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minimum: n });\n };\n}\n\nexport function Max(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maximum: n });\n };\n}\n\nexport function ExclusiveMin(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { exclusiveMinimum: n });\n };\n}\n\nexport function ExclusiveMax(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { exclusiveMaximum: n });\n };\n}\n\nexport function MinLength(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minLength: n });\n };\n}\n\nexport function MaxLength(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maxLength: n });\n };\n}\n\nexport function Pattern(re: RegExp | string): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { pattern: typeof re === \"string\" ? re : re.source });\n };\n}\n\nexport function Format(fmt: string): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { format: fmt });\n };\n}\n\nexport function MinItems(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minItems: n });\n };\n}\n\nexport function MaxItems(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maxItems: n });\n };\n}\n\nexport function MinProperties(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { minProperties: n });\n };\n}\n\nexport function MaxProperties(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { maxProperties: n });\n };\n}\n\nexport function MultipleOf(n: number): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { multipleOf: n });\n };\n}\n\nexport function Example(value: unknown): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { example: value });\n };\n}\n\nexport function Examples(values: unknown[]): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { examples: values });\n };\n}\n\nexport function Description(desc: string): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { description: desc });\n };\n}\n\nexport function Enum<T extends string | number>(vals: T[]): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { enum: vals });\n };\n}\n\nexport function Const<T>(val: T): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { const: val });\n };\n}\n\nexport function Default<T>(val: T): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { default: val });\n };\n}\n\nexport function AdditionalProperties(value: boolean | Record<string, unknown>): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { additionalProperties: value });\n };\n}\n\nexport function Closed(): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { additionalProperties: false });\n };\n}\n\nexport function ClosedUnevaluated(): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n pushSchemaFrag(target, propertyKey, {}, { unevaluatedProperties: false });\n };\n}\n\nexport function Union(mode: \"anyOf\" | \"oneOf\" | \"allOf\"): ClassDecorator {\n return function (target: Function): void {\n (target as any)[ADORN_META] = (target as any)[ADORN_META] ?? {};\n const meta = (target as any)[ADORN_META] as SchemaMetadata;\n meta.schema = meta.schema ?? { props: {} };\n (meta.schema as any).unionMode = mode;\n };\n}\n\nexport { ADORN_META };\nexport type { SchemaFrag, SchemaMetadata };\n","import Ajv from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport type { ErrorObject } from \"ajv\";\n\n/**\n * Runtime validation module using AJV.\n * \n * @remarks\n * This module provides validation utilities using the AJV JSON schema validator.\n * It includes interfaces for validation results, errors, and helper functions\n * for creating validators and formatting error messages.\n * \n * @package\n */\n\n/**\n * Represents a single validation error with details.\n * \n * @public\n */\nexport interface ValidationError {\n /**\n * The JSON path to the invalid property.\n */\n path: string;\n \n /**\n * Human-readable error message.\n */\n message: string;\n \n /**\n * The AJV keyword that failed validation.\n */\n keyword: string;\n \n /**\n * Additional parameters from the validation error.\n */\n params: Record<string, unknown>;\n}\n\n/**\n * Result of a validation operation.\n * \n * @public\n */\nexport interface ValidationResult {\n /**\n * Whether the data passed validation.\n */\n valid: boolean;\n \n /**\n * Array of validation errors if validation failed, null otherwise.\n */\n errors: ValidationError[] | null;\n}\n\n/**\n * Error thrown when request validation fails.\n * \n * @public\n */\nexport class ValidationErrorResponse extends Error {\n /**\n * HTTP status code for validation errors.\n */\n statusCode: number;\n \n /**\n * Detailed validation errors.\n */\n errors: ValidationError[];\n\n /**\n * Creates a new ValidationErrorResponse.\n * \n * @param statusCode - HTTP status code (typically 400)\n * @param errors - Array of validation errors\n */\n constructor(statusCode: number, errors: ValidationError[]) {\n super(\"Validation failed\");\n this.name = \"ValidationErrorResponse\";\n this.statusCode = statusCode;\n this.errors = errors;\n }\n}\n\n/**\n * Creates a configured AJV validator instance.\n * \n * @remarks\n * This function creates an AJV validator with adorn-api's default configuration,\n * including support for custom formats like \"br-phone\" for Brazilian phone numbers.\n * \n * @returns A configured AJV validator instance\n * \n * @example\n * ```typescript\n * const validator = createValidator();\n * const validate = validator.compile(mySchema);\n * const result = validate(myData);\n * ```\n * \n * @public\n */\nexport function createValidator() {\n const ajv = new Ajv.default({\n allErrors: true,\n coerceTypes: false,\n strict: false,\n validateFormats: true,\n });\n\n addFormats.default(ajv);\n\n ajv.addFormat(\"br-phone\", /^\\(\\d{2}\\)\\s\\d{5}-\\d{4}$/);\n\n return ajv;\n}\n\n/**\n * Validates data against a JSON schema.\n * \n * @remarks\n * This function compiles the schema and validates the data, returning a\n * structured result with formatted error messages.\n * \n * @param ajv - The AJV validator instance\n * @param data - The data to validate\n * @param schema - The JSON schema to validate against\n * @param dataPath - Base path for error messages (default: \"#\")\n * @returns ValidationResult with validity and any errors\n * \n * @public\n */\nexport function validateData(\n ajv: ReturnType<typeof createValidator>,\n data: unknown,\n schema: Record<string, unknown>,\n dataPath: string = \"#\"\n): ValidationResult {\n const validate = ajv.compile(schema);\n const valid = validate(data);\n\n if (valid) {\n return { valid: true, errors: null };\n }\n\n const errors: ValidationError[] = (validate.errors || []).map((err: ErrorObject) => ({\n path: formatErrorPath(dataPath, err),\n message: err.message || \"Invalid value\",\n keyword: err.keyword,\n params: err.params as Record<string, unknown>,\n }));\n\n return { valid: false, errors };\n}\n\n/**\n * Formats an error path for display.\n * \n * @internal\n */\nfunction formatErrorPath(basePath: string, err: ErrorObject): string {\n const instancePath = err.instancePath;\n\n if (!instancePath || instancePath === \"\") {\n return basePath;\n }\n\n if (basePath === \"#\" || basePath.endsWith(\"/\")) {\n return `${basePath}${instancePath.slice(1)}`;\n }\n\n return `${basePath}${instancePath}`;\n}\n\n/**\n * Formats validation errors into a structured API response.\n * \n * @remarks\n * This function converts validation errors into a format suitable for API\n * responses, grouping errors by their path.\n * \n * @param errors - Array of validation errors\n * @returns Formatted error response object\n * \n * @public\n */\nexport function formatValidationErrors(errors: ValidationError[]): Record<string, unknown> {\n const formatted: Record<string, string[]> = {};\n\n for (const error of errors) {\n const path = error.path || \"body\";\n if (!formatted[path]) {\n formatted[path] = [];\n }\n formatted[path].push(error.message);\n }\n\n return {\n error: \"Validation failed\",\n details: formatted,\n };\n}\n","import \"./runtime/polyfill.js\";\n\nconst ADORN_META = Symbol.for(\"adorn-api.metadata\");\n\ninterface HttpMetadata {\n consumes?: string[];\n produces?: string[];\n fileParts?: Record<string, FilePartOptions>;\n cookies?: Record<string, boolean>;\n}\n\ninterface FilePartOptions {\n contentType?: string;\n headers?: Record<string, string>;\n}\n\ntype DecoratorMetadata = Record<PropertyKey, unknown> & { [ADORN_META]?: HttpMetadata };\n\nfunction getMetadata(target: Object | DecoratorMetadata): HttpMetadata {\n const host = target as DecoratorMetadata;\n const metadata = host[ADORN_META] ?? {};\n host[ADORN_META] = metadata;\n return metadata;\n}\n\nexport function PartType(contentTypeOrOptions: string | FilePartOptions): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n const metadata = getMetadata(target);\n const options: FilePartOptions = typeof contentTypeOrOptions === \"string\"\n ? { contentType: contentTypeOrOptions }\n : contentTypeOrOptions;\n metadata.fileParts ??= {};\n metadata.fileParts[propertyKey.toString()] = options;\n };\n}\n\nexport function File(): PropertyDecorator {\n return function (target: Object, propertyKey: string | symbol): void {\n const metadata = getMetadata(target);\n metadata.fileParts ??= {};\n metadata.fileParts[propertyKey.toString()] = metadata.fileParts[propertyKey.toString()] ?? {};\n };\n}\n\nexport function Consumes(...contentTypes: string[]): ClassDecorator {\n return function (target: Function): void {\n const metadata = getMetadata(target.prototype);\n metadata.consumes = contentTypes;\n };\n}\n\nexport function Produces(...contentTypes: string[]): ClassDecorator {\n return function (target: Function): void {\n const metadata = getMetadata(target.prototype);\n metadata.produces = contentTypes;\n };\n}\n\nexport type Query<T = any> = T;\nexport type Body<T = any> = T;\nexport type Headers<T = any> = T;\nexport type Cookies<T = any> = T;\n\nexport interface PaginationParams {\n page: number;\n pageSize: number;\n}\n\nexport type PaginatedResponse<T> = {\n items: T[];\n totalItems: number;\n page: number;\n pageSize: number;\n};\n\nexport { ADORN_META };\nexport type { HttpMetadata, FilePartOptions, PartType as PartType2 };\n","/**\n * Cache management module for compiled artifacts.\n * Loads OpenAPI specs, manifests, and validators from the output directory.\n */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { stat } from \"node:fs/promises\";\n\n/**\n * OpenAPI specification interface as loaded from openapi.json\n */\ninterface OpenApi {\n openapi: string;\n components?: {\n schemas?: Record<string, unknown>;\n };\n paths?: Record<string, unknown>;\n info?: Record<string, unknown>;\n security?: Array<Record<string, string[]>>;\n}\n\n/**\n * Manifest interface describing the compiled API structure.\n * Contains metadata about the generation process and all controllers/operations.\n */\ninterface Manifest {\n manifestVersion: number;\n generatedAt: string;\n generator: {\n name: string;\n version: string;\n typescript: string;\n };\n schemas: {\n kind: string;\n file: string;\n componentsSchemasPointer: string;\n };\n validation: {\n mode: \"none\" | \"ajv-runtime\" | \"precompiled\";\n precompiledModule: string | null;\n };\n controllers: Array<{\n controllerId: string;\n basePath: string;\n operations: Array<{\n operationId: string;\n http: {\n method: string;\n path: string;\n };\n handler: {\n methodName: string;\n };\n args: {\n body: {\n index: number;\n required: boolean;\n contentType: string;\n schemaRef: string;\n } | null;\n path: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n query: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n headers: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n cookies: Array<{\n name: string;\n index: number;\n required: boolean;\n schemaRef: string;\n schemaType?: string | string[];\n }>;\n };\n responses: Array<{\n status: number;\n contentType: string;\n schemaRef: string;\n isArray?: boolean;\n }>;\n }>;\n }>;\n}\n\n/**\n * Validator module interface for precompiled validation logic.\n */\ninterface ValidatorModule {\n validators: Record<string, {\n body?: (data: unknown) => boolean;\n response: Record<string, (data: unknown) => boolean>;\n }>;\n validateBody: (operationId: string, data: unknown) => { ok: boolean; errors: unknown[] | null };\n validateResponse: (operationId: string, status: number, contentType: string, data: unknown) => { ok: boolean; errors: unknown[] | null };\n}\n\n/**\n * Internal cache entry for tracking loaded artifacts and their modification times.\n */\ninterface ArtifactCacheEntry {\n openapi: OpenApi | null;\n manifest: Manifest | null;\n validators: ValidatorModule | null;\n mtimes: {\n openapi: number | null;\n manifest: number | null;\n validators: number | null;\n };\n}\n\nconst artifactCache = new Map<string, ArtifactCacheEntry>();\n\nasync function getMtime(filePath: string): Promise<number | null> {\n try {\n const stats = await stat(filePath);\n return stats.mtimeMs;\n } catch {\n return null;\n }\n}\n\n/**\n * Options for loading artifacts from the output directory.\n */\nexport interface LoadArtifactsOptions {\n outDir: string;\n}\n\n/**\n * Result of loading artifacts from the output directory.\n */\nexport interface LoadedArtifacts {\n openapi: OpenApi;\n manifest: Manifest;\n validators: ValidatorModule | null;\n}\n\n/**\n * Loads OpenAPI spec, manifest, and validators from the output directory.\n * Results are cached in memory to avoid repeated file I/O.\n * \n * @param options - Object containing the output directory path\n * @returns Promise resolving to loaded artifacts including OpenAPI spec, manifest, and validators\n */\nexport async function loadArtifacts(options: LoadArtifactsOptions): Promise<LoadedArtifacts> {\n const { outDir } = options;\n const cacheKey = path.resolve(outDir);\n\n const entry = artifactCache.get(cacheKey);\n\n const openapiPath = path.join(outDir, \"openapi.json\");\n const manifestPath = path.join(outDir, \"manifest.json\");\n const validatorsPath = path.join(outDir, \"validators.mjs\");\n\n const openapiMtime = await getMtime(openapiPath);\n const manifestMtime = await getMtime(manifestPath);\n const validatorsMtime = await getMtime(validatorsPath);\n\n if (entry) {\n const mtimesMatch = \n entry.mtimes.openapi === openapiMtime &&\n entry.mtimes.manifest === manifestMtime &&\n entry.mtimes.validators === validatorsMtime;\n\n if (mtimesMatch) {\n if (entry.openapi && entry.manifest) {\n return {\n openapi: entry.openapi,\n manifest: entry.manifest,\n validators: entry.validators,\n };\n }\n }\n }\n\n const openapiContent = fs.readFileSync(openapiPath, \"utf-8\");\n const manifestContent = fs.readFileSync(manifestPath, \"utf-8\");\n\n const openapi = JSON.parse(openapiContent) as OpenApi;\n const manifest = JSON.parse(manifestContent) as Manifest;\n\n let validators: ValidatorModule | null = null;\n\n if (manifest.validation.mode === \"precompiled\" && manifest.validation.precompiledModule) {\n try {\n const validatorsModule = await import(path.join(outDir, manifest.validation.precompiledModule));\n validators = validatorsModule as ValidatorModule;\n } catch (err) {\n console.warn(`Failed to load precompiled validators: ${err}`);\n }\n }\n\n artifactCache.set(cacheKey, {\n openapi,\n manifest,\n validators,\n mtimes: {\n openapi: openapiMtime,\n manifest: manifestMtime,\n validators: validatorsMtime,\n },\n });\n\n return {\n openapi,\n manifest,\n validators,\n };\n}\n\n/**\n * Clears the in-memory artifact cache.\n * If an output directory is specified, only that entry is removed.\n * Otherwise, the entire cache is cleared.\n * \n * @param outDir - Optional specific output directory to clear from cache\n */\nexport function clearArtifactCache(outDir?: string): void {\n if (outDir) {\n const cacheKey = path.resolve(outDir);\n artifactCache.delete(cacheKey);\n } else {\n artifactCache.clear();\n }\n}\n\n/**\n * Returns statistics about the current artifact cache state.\n * Useful for debugging and monitoring cache behavior.\n * \n * @returns Object containing cache size and array of cached keys\n */\nexport function getArtifactCacheStats(): { size: number; keys: string[] } {\n return {\n size: artifactCache.size,\n keys: Array.from(artifactCache.keys()),\n };\n}\n","import { createServer, Server } from \"net\";\nimport { exec } from \"child_process\";\nimport { promisify } from \"util\";\n\nconst execAsync = promisify(exec);\n\nexport interface ProcessInfo {\n pid: number;\n command?: string;\n}\n\nexport async function isPortAvailable(port: number, host: string = \"0.0.0.0\"): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const server: Server = createServer();\n\n server.on(\"error\", (err: any) => {\n if (err.code === \"EADDRINUSE\") {\n resolve(false);\n } else {\n resolve(false);\n }\n });\n\n server.once(\"listening\", () => {\n server.close(() => {\n resolve(true);\n });\n });\n\n server.listen(port, host);\n });\n}\n\nexport async function findProcessOnPort(port: number): Promise<ProcessInfo | null> {\n try {\n const platform = process.platform;\n\n if (platform === \"win32\") {\n const { stdout } = await execAsync(`netstat -ano | findstr :${port}`);\n \n for (const line of stdout.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.includes(\"PID\")) continue;\n \n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 5) {\n const address = parts[1];\n const pid = parseInt(parts[parts.length - 1], 10);\n \n if (address.includes(`:${port}`) && !isNaN(pid)) {\n const command = await getProcessNameOnWindows(pid);\n return { pid, command };\n }\n }\n }\n } else {\n const { stdout } = await execAsync(`lsof -ti:${port}`);\n const pids = stdout.trim().split(\"\\n\").filter(Boolean).map(Number);\n \n if (pids.length > 0) {\n const pid = pids[0];\n const command = await getProcessNameOnUnix(pid);\n return { pid, command };\n }\n }\n\n return null;\n } catch (error: any) {\n if (error.message.includes(\"matches found\")) {\n return null;\n }\n return null;\n }\n}\n\nasync function getProcessNameOnWindows(pid: number): Promise<string | undefined> {\n try {\n const { stdout } = await execAsync(`tasklist /FI \"PID eq ${pid}\" /FO CSV /NH`);\n const line = stdout.trim().split(\"\\n\")[0];\n if (line) {\n const parts = line.split('\",\"');\n if (parts.length >= 2) {\n return parts[0].replace(/\"/g, \"\");\n }\n }\n } catch {\n return undefined;\n }\n}\n\nasync function getProcessNameOnUnix(pid: number): Promise<string | undefined> {\n try {\n const { stdout } = await execAsync(`ps -p ${pid} -o comm=`);\n return stdout.trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport async function killProcess(pid: number): Promise<boolean> {\n try {\n process.kill(pid, \"SIGTERM\");\n \n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Process did not terminate gracefully\"));\n }, 5000);\n \n const check = () => {\n try {\n process.kill(pid, 0);\n setTimeout(check, 500);\n } catch {\n clearInterval(interval);\n clearTimeout(timeout);\n resolve();\n }\n };\n \n const interval = setInterval(check, 500);\n });\n \n return true;\n } catch {\n try {\n process.kill(pid, \"SIGKILL\");\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Process did not terminate\"));\n }, 3000);\n \n setTimeout(() => {\n try {\n process.kill(pid, 0);\n clearTimeout(timeout);\n reject(new Error(\"Process still running\"));\n } catch {\n clearTimeout(timeout);\n resolve();\n }\n }, 1000);\n });\n \n return true;\n } catch {\n return false;\n }\n }\n}\n\nexport async function waitForPort(port: number, host: string = \"0.0.0.0\", timeout: number = 5000): Promise<boolean> {\n const start = Date.now();\n \n while (Date.now() - start < timeout) {\n if (await isPortAvailable(port, host)) {\n return true;\n }\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n \n return false;\n}\n"],"mappings":"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","names":["path","op","op","op","op","ADORN_META","path","ADORN_META"]}
|
|
@@ -1,8 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for applying list queries to Metal ORM query builders.
|
|
3
|
+
* Includes pagination, sorting, and parsing utilities.
|
|
4
|
+
*/
|
|
1
5
|
import type { ListQuery } from "./listQuery.js";
|
|
2
6
|
import type { SelectQueryBuilder } from "metal-orm";
|
|
3
7
|
import type { OrmSession } from "metal-orm";
|
|
4
8
|
import type { PaginatedResult } from "metal-orm";
|
|
9
|
+
/**
|
|
10
|
+
* Applies a list query to a Metal ORM select query builder and executes a paginated query.
|
|
11
|
+
*
|
|
12
|
+
* @typeParam TEntity - The entity type being queried
|
|
13
|
+
* @param qb - The Metal ORM select query builder
|
|
14
|
+
* @param session - The ORM session to use for execution
|
|
15
|
+
* @param query - Optional list query parameters (pagination, filtering, sorting)
|
|
16
|
+
* @returns A promise resolving to a paginated result
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const result = await applyListQuery(
|
|
21
|
+
* db.selectFrom("users"),
|
|
22
|
+
* session,
|
|
23
|
+
* { page: 1, pageSize: 10, where: { name: { eq: "John" } } }
|
|
24
|
+
* );
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
5
27
|
export declare function applyListQuery<TEntity extends object>(qb: SelectQueryBuilder<TEntity>, session: OrmSession, query?: ListQuery<TEntity>): Promise<PaginatedResult<TEntity>>;
|
|
28
|
+
/**
|
|
29
|
+
* Generates pagination options with defaults.
|
|
30
|
+
*
|
|
31
|
+
* @param query - Optional pagination parameters
|
|
32
|
+
* @param query.page - Page number (1-indexed, defaults to 1)
|
|
33
|
+
* @param query.pageSize - Items per page (defaults to 10)
|
|
34
|
+
* @returns Pagination options object
|
|
35
|
+
*/
|
|
6
36
|
export declare function pagedOptions(query?: {
|
|
7
37
|
page?: number;
|
|
8
38
|
pageSize?: number;
|
|
@@ -10,18 +40,61 @@ export declare function pagedOptions(query?: {
|
|
|
10
40
|
page: number;
|
|
11
41
|
pageSize: number;
|
|
12
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Normalizes sort input into an array of strings.
|
|
45
|
+
* Accepts comma-separated strings or arrays.
|
|
46
|
+
*
|
|
47
|
+
* @param sort - Sort input (string, array of strings, or undefined)
|
|
48
|
+
* @returns Array of sort field names
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* normalizeSort("name,-age") // ["name", "-age"]
|
|
53
|
+
* normalizeSort(["name", "-age"]) // ["name", "-age"]
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
13
56
|
export declare function normalizeSort(sort: unknown): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Sort direction indicator.
|
|
59
|
+
* "ASC" for ascending order, "DESC" for descending order.
|
|
60
|
+
*/
|
|
14
61
|
export type SortDirection = "ASC" | "DESC";
|
|
62
|
+
/**
|
|
63
|
+
* Represents a parsed sort token with direction and field information.
|
|
64
|
+
*/
|
|
15
65
|
export type SortToken = {
|
|
66
|
+
/** Original sort string */
|
|
16
67
|
raw: string;
|
|
68
|
+
/** Field name without direction prefix */
|
|
17
69
|
field: string;
|
|
70
|
+
/** Dot-separated path for nested fields */
|
|
18
71
|
path: string[];
|
|
72
|
+
/** Sort direction (ASC or DESC) */
|
|
19
73
|
direction: SortDirection;
|
|
74
|
+
/** Whether this field references a relation */
|
|
20
75
|
isRelationField: boolean;
|
|
21
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* Options for parsing sort tokens.
|
|
79
|
+
*/
|
|
22
80
|
export type ParseSortOptions = {
|
|
81
|
+
/** Maximum number of sort tokens to return (default: 20) */
|
|
23
82
|
max?: number;
|
|
83
|
+
/** Whitelist of allowed field paths (supports wildcards like "user.*") */
|
|
24
84
|
whitelist?: string[];
|
|
25
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Parses sort input into structured SortToken objects.
|
|
88
|
+
*
|
|
89
|
+
* @param sort - Sort input (string, array, or undefined)
|
|
90
|
+
* @param opts - Optional parsing configuration
|
|
91
|
+
* @returns Array of parsed sort tokens
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* parseSort("name,-age,address.city")
|
|
96
|
+
* // Returns tokens with direction, field, path, and isRelationField
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
26
99
|
export declare function parseSort(sort: unknown, opts?: ParseSortOptions): SortToken[];
|
|
27
100
|
//# sourceMappingURL=applyListQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applyListQuery.d.ts","sourceRoot":"","sources":["../../src/metal/applyListQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,wBAAsB,cAAc,CAAC,OAAO,SAAS,MAAM,EACzD,EAAE,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAC/B,OAAO,EAAE,UAAU,EACnB,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,GACzB,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAEnC;AAED,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAKA;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAQrD;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAiBF,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,SAAS,EAAE,CA4B7E"}
|
|
1
|
+
{"version":3,"file":"applyListQuery.d.ts","sourceRoot":"","sources":["../../src/metal/applyListQuery.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,OAAO,SAAS,MAAM,EACzD,EAAE,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAC/B,OAAO,EAAE,UAAU,EACnB,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,GACzB,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAEnC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAKA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAQrD;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,mCAAmC;IACnC,SAAS,EAAE,aAAa,CAAC;IACzB,+CAA+C;IAC/C,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAiBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,SAAS,EAAE,CA4B7E"}
|
package/dist/metal/index.cjs
CHANGED
|
@@ -130,7 +130,7 @@ function makeNullable(schema) {
|
|
|
130
130
|
return schema;
|
|
131
131
|
}
|
|
132
132
|
function isGenerated(col) {
|
|
133
|
-
return !!col.primary || !!col.autoIncrement || col.generated
|
|
133
|
+
return !!col.primary || !!col.autoIncrement || col.generated !== null && col.generated !== void 0;
|
|
134
134
|
}
|
|
135
135
|
function shouldIncludeColumn(col, mode) {
|
|
136
136
|
if (mode === "read") return true;
|
|
@@ -141,7 +141,7 @@ function shouldIncludeColumn(col, mode) {
|
|
|
141
141
|
function shouldRequire(col, mode) {
|
|
142
142
|
if (mode === "update") return false;
|
|
143
143
|
if (!col.notNull) return false;
|
|
144
|
-
if (mode === "create" && col.default
|
|
144
|
+
if (mode === "create" && (col.default !== null && col.default !== void 0)) return false;
|
|
145
145
|
return true;
|
|
146
146
|
}
|
|
147
147
|
function schemaFromEntity(ctor, opts = {}) {
|
package/dist/metal/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/metal/index.ts","../../src/metal/symbolMetadata.ts","../../src/metal/readMetalBag.ts","../../src/metal/schemaFromEntity.ts","../../src/metal/registerMetalEntities.ts","../../src/metal/applyListQuery.ts"],"sourcesContent":["export { ensureSymbolMetadata } from \"./symbolMetadata.js\";\nexport { readMetalDecoratorBagFromConstructor, METAL_METADATA_KEY } from \"./readMetalBag.js\";\nexport { schemaFromEntity } from \"./schemaFromEntity.js\";\nexport { registerMetalEntities } from \"./registerMetalEntities.js\";\nexport type { ListQuery } from \"./listQuery.js\";\nexport { applyListQuery, normalizeSort, pagedOptions, parseSort } from \"./applyListQuery.js\";\n\nexport type { SchemaFromEntityOptions, EntitySchemaMode, JsonSchema } from \"./schemaFromEntity.js\";\nexport type { SearchWhere, SearchWhereDepth, SearchWhereOptions, SearchWherePath } from \"./searchWhere.js\";\nexport type { QueryOptions } from \"./queryOptions.js\";\n\nexport type { SortDirection, SortToken, ParseSortOptions } from \"./applyListQuery.js\";\n","export function ensureSymbolMetadata(): symbol {\n const s = Symbol as unknown as { metadata?: symbol };\n if (!s.metadata) {\n s.metadata = Symbol(\"Symbol.metadata\");\n }\n return s.metadata;\n}\n","import { ensureSymbolMetadata } from \"./symbolMetadata.js\";\n\nexport const METAL_METADATA_KEY = \"metal-orm:decorators\";\n\nexport type MetalColumnDef = {\n type: string;\n args?: unknown[];\n dialectTypes?: unknown;\n notNull?: boolean;\n primary?: boolean;\n tsType?: unknown;\n unique?: boolean;\n default?: unknown;\n autoIncrement?: boolean;\n generated?: unknown;\n check?: unknown;\n references?: unknown;\n comment?: string;\n};\n\nexport type MetalRelationMetadata = {\n kind: string;\n propertyKey: string;\n target?: (...args: any[]) => any;\n};\n\nexport type MetalDecoratorBag = {\n columns: Array<{ propertyName: string; column: MetalColumnDef }>;\n relations: Array<{ propertyName: string; relation: MetalRelationMetadata }>;\n};\n\nexport function readMetalDecoratorBagFromConstructor(ctor: object): MetalDecoratorBag | undefined {\n const metadataSymbol = ensureSymbolMetadata();\n const metadata = Reflect.get(ctor, metadataSymbol) as Record<PropertyKey, unknown> | undefined;\n return metadata?.[METAL_METADATA_KEY] as MetalDecoratorBag | undefined;\n}\n","import { readMetalDecoratorBagFromConstructor, type MetalColumnDef, type MetalDecoratorBag } from \"./readMetalBag.js\";\n\nexport type JsonSchema = Record<string, any>;\n\nexport type EntitySchemaMode = \"read\" | \"create\" | \"update\";\n\nexport interface SchemaFromEntityOptions {\n name?: string;\n stripEntitySuffix?: boolean;\n mode?: EntitySchemaMode;\n additionalProperties?: boolean;\n includeRelations?: \"none\" | \"inline\";\n}\n\nfunction defaultSchemaName(ctor: Function, strip: boolean) {\n const raw = ctor.name || \"AnonymousEntity\";\n return strip ? raw.replace(/Entity$/i, \"\") || raw : raw;\n}\n\nfunction columnTypeToSchema(col: MetalColumnDef): JsonSchema {\n const t = String(col.type).toLowerCase();\n const s: JsonSchema = {};\n\n if ([\"varchar\", \"text\", \"string\", \"char\", \"citext\"].includes(t)) {\n s.type = \"string\";\n const a0 = Array.isArray(col.args) ? col.args[0] : undefined;\n if (typeof a0 === \"number\" && Number.isFinite(a0) && a0 > 0) s.maxLength = a0;\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"uuid\"].includes(t)) {\n s.type = \"string\";\n s.format = \"uuid\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"timestamp\", \"timestamptz\", \"datetime\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date-time\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n if ([\"date\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bool\", \"boolean\"].includes(t)) {\n s.type = \"boolean\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"int\", \"int4\", \"integer\", \"smallint\", \"int2\", \"serial\", \"bigserial\"].includes(t)) {\n s.type = \"integer\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bigint\", \"int8\"].includes(t)) {\n s.type = \"string\";\n s.format = \"int64\";\n s.pattern = \"^-?\\\\d+$\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"float\", \"float4\", \"float8\", \"double\", \"decimal\", \"numeric\", \"real\"].includes(t)) {\n s.type = \"number\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"json\", \"jsonb\"].includes(t)) {\n s.type = [\"object\", \"array\", \"string\", \"number\", \"boolean\", \"null\"];\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n s.type = \"string\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n}\n\nfunction isLiteralDefault(v: unknown) {\n return v === null || [\"string\", \"number\", \"boolean\"].includes(typeof v);\n}\n\nfunction makeNullable(schema: JsonSchema): JsonSchema {\n if (schema.type === \"null\") return schema;\n if (Array.isArray(schema.type)) {\n if (!schema.type.includes(\"null\")) schema.type = [...schema.type, \"null\"];\n return schema;\n }\n if (typeof schema.type === \"string\") {\n schema.type = [schema.type, \"null\"];\n } else {\n schema.type = [\"null\"];\n }\n return schema;\n}\n\nfunction isGenerated(col: MetalColumnDef) {\n return !!col.primary || !!col.autoIncrement || col.generated != null;\n}\n\nfunction shouldIncludeColumn(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"read\") return true;\n if (mode === \"create\") return !isGenerated(col);\n if (mode === \"update\") return true;\n return true;\n}\n\nfunction shouldRequire(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"update\") return false;\n if (!col.notNull) return false;\n if (mode === \"create\" && col.default != null) return false;\n return true;\n}\n\nexport function schemaFromEntity(ctor: Function, opts: SchemaFromEntityOptions = {}): JsonSchema | undefined {\n const bag = readMetalDecoratorBagFromConstructor(ctor);\n if (!bag || !Array.isArray(bag.columns) || bag.columns.length === 0) return undefined;\n\n const mode = opts.mode ?? \"read\";\n const name = opts.name ?? defaultSchemaName(ctor, opts.stripEntitySuffix ?? true);\n\n const schema: JsonSchema = {\n title: name,\n type: \"object\",\n properties: {},\n additionalProperties: opts.additionalProperties ?? true\n };\n\n const required: string[] = [];\n\n for (const entry of bag.columns) {\n const prop = entry.propertyName;\n const col = entry.column;\n\n if (!shouldIncludeColumn(col, mode)) continue;\n\n const propSchema = columnTypeToSchema(col);\n\n if (!col.notNull) makeNullable(propSchema);\n\n if (isLiteralDefault(col.default)) propSchema.default = col.default;\n\n if (mode === \"read\" && col.primary) propSchema.readOnly = true;\n\n (schema.properties as any)[prop] = propSchema;\n\n if (shouldRequire(col, mode)) required.push(prop);\n }\n\n if (required.length) schema.required = required;\n\n if ((opts.includeRelations ?? \"none\") === \"inline\") {\n for (const r of bag.relations ?? []) {\n const rel = r.relation;\n if (typeof rel?.target !== \"function\") continue;\n\n let target: any;\n try {\n target = rel.target();\n } catch {\n continue;\n }\n if (typeof target !== \"function\") continue;\n\n const targetName = defaultSchemaName(target, true);\n (schema.properties as any)[r.propertyName] = { $ref: `#/components/schemas/${targetName}` };\n }\n }\n\n return schema;\n}\n","import { schemaFromEntity, type SchemaFromEntityOptions, type JsonSchema } from \"./schemaFromEntity.js\";\n\nfunction deepMerge(a: any, b: any): any {\n if (Array.isArray(a) || Array.isArray(b)) return b ?? a;\n if (a && typeof a === \"object\" && b && typeof b === \"object\") {\n const out: any = { ...a };\n for (const [k, v] of Object.entries(b)) out[k] = deepMerge(out[k], v);\n return out;\n }\n return b ?? a;\n}\n\nexport interface RegisterMetalEntitiesOptions extends SchemaFromEntityOptions {\n merge?: \"override\" | \"merge\";\n}\n\nexport function registerMetalEntities(\n openapi: any,\n entities: Function[],\n opts: RegisterMetalEntitiesOptions = {}\n) {\n openapi.components ??= {};\n openapi.components.schemas ??= {};\n\n const mergeMode = opts.merge ?? \"merge\";\n\n for (const ctor of entities) {\n const s = schemaFromEntity(ctor, opts);\n if (!s) continue;\n\n const name = s.title || ctor.name;\n const existing = openapi.components.schemas[name];\n\n if (!existing || mergeMode === \"override\") {\n openapi.components.schemas[name] = s;\n } else {\n openapi.components.schemas[name] = deepMerge(existing, s);\n }\n }\n}\n","import type { ListQuery } from \"./listQuery.js\";\nimport type { SelectQueryBuilder } from \"metal-orm\";\nimport type { OrmSession } from \"metal-orm\";\nimport type { PaginatedResult } from \"metal-orm\";\n\nexport async function applyListQuery<TEntity extends object>(\n qb: SelectQueryBuilder<TEntity>,\n session: OrmSession,\n query?: ListQuery<TEntity>\n): Promise<PaginatedResult<TEntity>> {\n return qb.executePaged(session, pagedOptions(query));\n}\n\nexport function pagedOptions(query?: { page?: number; pageSize?: number }): {\n page: number;\n pageSize: number;\n} {\n return {\n page: query?.page ?? 1,\n pageSize: query?.pageSize ?? 10,\n };\n}\n\nexport function normalizeSort(sort: unknown): string[] {\n if (Array.isArray(sort)) {\n return sort.flatMap((v) => String(v).split(\",\"));\n }\n if (typeof sort === \"string\") {\n return sort.split(\",\");\n }\n return [];\n}\n\nexport type SortDirection = \"ASC\" | \"DESC\";\n\nexport type SortToken = {\n raw: string;\n field: string;\n path: string[];\n direction: SortDirection;\n isRelationField: boolean;\n};\n\nexport type ParseSortOptions = {\n max?: number;\n whitelist?: string[];\n};\n\nfunction matchWhitelist(path: string[], whitelist: string[]): boolean {\n const pathStr = path.join(\".\");\n\n for (const pattern of whitelist) {\n if (pattern === pathStr) return true;\n\n if (pattern.endsWith(\"*\")) {\n const prefix = pattern.slice(0, -1);\n if (pathStr.startsWith(prefix)) return true;\n }\n }\n\n return false;\n}\n\nexport function parseSort(sort: unknown, opts?: ParseSortOptions): SortToken[] {\n const max = opts?.max ?? 20;\n const whitelist = opts?.whitelist;\n\n const tokens = normalizeSort(sort)\n .map((s) => s.trim())\n .filter(Boolean)\n .slice(0, max)\n .map((raw) => {\n const direction: SortDirection = raw.startsWith(\"-\") ? \"DESC\" : \"ASC\";\n const field = raw.replace(/^[-+]/, \"\").trim();\n const path = field.split(\".\").map((p) => p.trim()).filter(Boolean);\n\n return {\n raw,\n field,\n path,\n direction,\n isRelationField: path.length > 1,\n };\n })\n .filter((t) => t.field.length > 0);\n\n if (whitelist && whitelist.length > 0) {\n return tokens.filter((t) => matchWhitelist(t.path, whitelist));\n }\n\n return tokens;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/metal/index.ts","../../src/metal/symbolMetadata.ts","../../src/metal/readMetalBag.ts","../../src/metal/schemaFromEntity.ts","../../src/metal/registerMetalEntities.ts","../../src/metal/applyListQuery.ts"],"sourcesContent":["/**\n * Metal ORM integration utilities for Adorn.\n * Provides type-safe query building, entity schema generation, and metadata handling.\n */\nexport { ensureSymbolMetadata } from \"./symbolMetadata.js\";\nexport { readMetalDecoratorBagFromConstructor, METAL_METADATA_KEY } from \"./readMetalBag.js\";\nexport { schemaFromEntity } from \"./schemaFromEntity.js\";\nexport { registerMetalEntities } from \"./registerMetalEntities.js\";\nexport type { ListQuery } from \"./listQuery.js\";\nexport { applyListQuery, normalizeSort, pagedOptions, parseSort } from \"./applyListQuery.js\";\n\nexport type { SchemaFromEntityOptions, EntitySchemaMode, JsonSchema } from \"./schemaFromEntity.js\";\nexport type { SearchWhere, SearchWhereDepth, SearchWhereOptions, SearchWherePath } from \"./searchWhere.js\";\nexport type { QueryOptions } from \"./queryOptions.js\";\n\nexport type { SortDirection, SortToken, ParseSortOptions } from \"./applyListQuery.js\";\n","/**\n * Ensures the Symbol.metadata symbol exists and returns it.\n * Used by Metal ORM decorators to store metadata on classes.\n * \n * @returns The Symbol.metadata symbol\n */\nexport function ensureSymbolMetadata(): symbol {\n const s = Symbol as unknown as { metadata?: symbol };\n if (!s.metadata) {\n s.metadata = Symbol(\"Symbol.metadata\");\n }\n return s.metadata;\n}\n","/**\n * Metal ORM decorator metadata utilities.\n * Provides functions to read and manage entity decorator metadata.\n */\nimport { ensureSymbolMetadata } from \"./symbolMetadata.js\";\n\n/**\n * Symbol key for storing Metal ORM decorator metadata.\n */\nexport const METAL_METADATA_KEY = \"metal-orm:decorators\";\n\n/**\n * Represents a column definition in Metal ORM entity metadata.\n */\nexport type MetalColumnDef = {\n /** Database column type (e.g., \"varchar\", \"int\", \"timestamp\") */\n type: string;\n /** Additional type arguments (e.g., length for varchar) */\n args?: unknown[];\n /** Database dialect-specific type definitions */\n dialectTypes?: unknown;\n /** Whether the column is NOT NULL */\n notNull?: boolean;\n /** Whether this is a primary key column */\n primary?: boolean;\n /** TypeScript type override for the column */\n tsType?: unknown;\n /** Whether the column has a unique constraint */\n unique?: boolean;\n /** Default value for the column */\n default?: unknown;\n /** Whether the column auto-increments */\n autoIncrement?: boolean;\n /** How the column value is generated (e.g., \"byDefault\", \"always\") */\n generated?: unknown;\n /** CHECK constraint for the column */\n check?: unknown;\n /** Foreign key references */\n references?: unknown;\n /** Column comment/description */\n comment?: string;\n};\n\n/**\n * Represents relation metadata in a Metal ORM entity.\n */\nexport type MetalRelationMetadata = {\n /** Type of relation (e.g., \"hasMany\", \"belongsTo\") */\n kind: string;\n /** Property name of the relation */\n propertyKey: string;\n /** Target entity constructor (optional, may be a getter) */\n target?: (...args: any[]) => any;\n};\n\n/**\n * Container for all decorator metadata of a Metal ORM entity.\n */\nexport type MetalDecoratorBag = {\n /** Array of column definitions */\n columns: Array<{ propertyName: string; column: MetalColumnDef }>;\n /** Array of relation metadata */\n relations: Array<{ propertyName: string; relation: MetalRelationMetadata }>;\n};\n\n/**\n * Reads Metal ORM decorator metadata from a class constructor.\n * \n * @param ctor - The class constructor to read metadata from\n * @returns The decorator bag if metadata exists, undefined otherwise\n */\nexport function readMetalDecoratorBagFromConstructor(ctor: object): MetalDecoratorBag | undefined {\n const metadataSymbol = ensureSymbolMetadata();\n const metadata = Reflect.get(ctor, metadataSymbol) as Record<PropertyKey, unknown> | undefined;\n return metadata?.[METAL_METADATA_KEY] as MetalDecoratorBag | undefined;\n}\n","/**\n * Converts Metal ORM entity decorators into JSON Schema for OpenAPI.\n */\nimport { readMetalDecoratorBagFromConstructor, type MetalColumnDef } from \"./readMetalBag.js\";\n\n/**\n * JSON Schema representation for OpenAPI.\n */\nexport type JsonSchema = Record<string, any>;\n\n/**\n * Schema generation mode determining which fields are included.\n * - \"read\": All fields (read-only marked on primary keys)\n * - \"create\": Exclude auto-generated fields (primary keys, autoIncrement)\n * - \"update\": All fields (none required)\n */\nexport type EntitySchemaMode = \"read\" | \"create\" | \"update\";\n\n/**\n * Options for generating a JSON Schema from an entity.\n */\nexport interface SchemaFromEntityOptions {\n /** Custom name for the schema (defaults to entity class name) */\n name?: string;\n /** Strip \"Entity\" suffix from class name (default: true) */\n stripEntitySuffix?: boolean;\n /** Schema generation mode (default: \"read\") */\n mode?: EntitySchemaMode;\n /** Allow additional properties not defined in schema (default: true) */\n additionalProperties?: boolean;\n /** How to handle relations in the schema (default: \"none\") */\n includeRelations?: \"none\" | \"inline\";\n}\n\nfunction defaultSchemaName(ctor: Function, strip: boolean) {\n const raw = ctor.name || \"AnonymousEntity\";\n return strip ? raw.replace(/Entity$/i, \"\") || raw : raw;\n}\n\nfunction columnTypeToSchema(col: MetalColumnDef): JsonSchema {\n const t = String(col.type).toLowerCase();\n const s: JsonSchema = {};\n\n if ([\"varchar\", \"text\", \"string\", \"char\", \"citext\"].includes(t)) {\n s.type = \"string\";\n const a0 = Array.isArray(col.args) ? col.args[0] : undefined;\n if (typeof a0 === \"number\" && Number.isFinite(a0) && a0 > 0) s.maxLength = a0;\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"uuid\"].includes(t)) {\n s.type = \"string\";\n s.format = \"uuid\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"timestamp\", \"timestamptz\", \"datetime\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date-time\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n if ([\"date\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bool\", \"boolean\"].includes(t)) {\n s.type = \"boolean\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"int\", \"int4\", \"integer\", \"smallint\", \"int2\", \"serial\", \"bigserial\"].includes(t)) {\n s.type = \"integer\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bigint\", \"int8\"].includes(t)) {\n s.type = \"string\";\n s.format = \"int64\";\n s.pattern = \"^-?\\\\d+$\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"float\", \"float4\", \"float8\", \"double\", \"decimal\", \"numeric\", \"real\"].includes(t)) {\n s.type = \"number\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"json\", \"jsonb\"].includes(t)) {\n s.type = [\"object\", \"array\", \"string\", \"number\", \"boolean\", \"null\"];\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n s.type = \"string\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n}\n\nfunction isLiteralDefault(v: unknown) {\n return v === null || [\"string\", \"number\", \"boolean\"].includes(typeof v);\n}\n\nfunction makeNullable(schema: JsonSchema): JsonSchema {\n if (schema.type === \"null\") return schema;\n if (Array.isArray(schema.type)) {\n if (!schema.type.includes(\"null\")) schema.type = [...schema.type, \"null\"];\n return schema;\n }\n if (typeof schema.type === \"string\") {\n schema.type = [schema.type, \"null\"];\n } else {\n schema.type = [\"null\"];\n }\n return schema;\n}\n\nfunction isGenerated(col: MetalColumnDef) {\n return !!col.primary || !!col.autoIncrement || (col.generated !== null && col.generated !== undefined);\n}\n\nfunction shouldIncludeColumn(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"read\") return true;\n if (mode === \"create\") return !isGenerated(col);\n if (mode === \"update\") return true;\n return true;\n}\n\nfunction shouldRequire(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"update\") return false;\n if (!col.notNull) return false;\n if (mode === \"create\" && (col.default !== null && col.default !== undefined)) return false;\n return true;\n}\n\n/**\n * Generates a JSON Schema from a Metal ORM entity class.\n * \n * @param ctor - The entity class constructor\n * @param opts - Schema generation options\n * @returns JSON Schema object or undefined if entity has no columns\n * \n * @example\n * ```ts\n * const schema = schemaFromEntity(User, { mode: \"create\" });\n * // Returns: { title: \"User\", type: \"object\", properties: {...}, required: [...] }\n * ```\n */\nexport function schemaFromEntity(ctor: Function, opts: SchemaFromEntityOptions = {}): JsonSchema | undefined {\n const bag = readMetalDecoratorBagFromConstructor(ctor);\n if (!bag || !Array.isArray(bag.columns) || bag.columns.length === 0) return undefined;\n\n const mode = opts.mode ?? \"read\";\n const name = opts.name ?? defaultSchemaName(ctor, opts.stripEntitySuffix ?? true);\n\n const schema: JsonSchema = {\n title: name,\n type: \"object\",\n properties: {},\n additionalProperties: opts.additionalProperties ?? true\n };\n\n const required: string[] = [];\n\n for (const entry of bag.columns) {\n const prop = entry.propertyName;\n const col = entry.column;\n\n if (!shouldIncludeColumn(col, mode)) continue;\n\n const propSchema = columnTypeToSchema(col);\n\n if (!col.notNull) makeNullable(propSchema);\n\n if (isLiteralDefault(col.default)) propSchema.default = col.default;\n\n if (mode === \"read\" && col.primary) propSchema.readOnly = true;\n\n (schema.properties as any)[prop] = propSchema;\n\n if (shouldRequire(col, mode)) required.push(prop);\n }\n\n if (required.length) schema.required = required;\n\n if ((opts.includeRelations ?? \"none\") === \"inline\") {\n for (const r of bag.relations ?? []) {\n const rel = r.relation;\n if (typeof rel?.target !== \"function\") continue;\n\n let target: any;\n try {\n target = rel.target();\n } catch {\n continue;\n }\n if (typeof target !== \"function\") continue;\n\n const targetName = defaultSchemaName(target, true);\n (schema.properties as any)[r.propertyName] = { $ref: `#/components/schemas/${targetName}` };\n }\n }\n\n return schema;\n}\n","/**\n * Utilities for registering Metal ORM entities as OpenAPI components.\n */\nimport { schemaFromEntity, type SchemaFromEntityOptions } from \"./schemaFromEntity.js\";\n\nfunction deepMerge(a: any, b: any): any {\n if (Array.isArray(a) || Array.isArray(b)) return b ?? a;\n if (a && typeof a === \"object\" && b && typeof b === \"object\") {\n const out: any = { ...a };\n for (const [k, v] of Object.entries(b)) out[k] = deepMerge(out[k], v);\n return out;\n }\n return b ?? a;\n}\n\n/**\n * Options for registering Metal ORM entities.\n */\nexport interface RegisterMetalEntitiesOptions extends SchemaFromEntityOptions {\n /** How to handle existing schemas with the same name: \"override\" or \"merge\" (default: \"merge\") */\n merge?: \"override\" | \"merge\";\n}\n\n/**\n * Registers Metal ORM entity schemas in an OpenAPI document.\n * \n * @param openapi - The OpenAPI document to modify (will be mutated)\n * @param entities - Array of entity class constructors to register\n * @param opts - Optional configuration for schema generation and merging\n * \n * @example\n * ```ts\n * const openapi = { components: { schemas: {} } };\n * registerMetalEntities(openapi, [User, Post, Comment]);\n * ```\n */\nexport function registerMetalEntities(\n openapi: any,\n entities: Function[],\n opts: RegisterMetalEntitiesOptions = {}\n) {\n openapi.components ??= {};\n openapi.components.schemas ??= {};\n\n const mergeMode = opts.merge ?? \"merge\";\n\n for (const ctor of entities) {\n const s = schemaFromEntity(ctor, opts);\n if (!s) continue;\n\n const name = s.title || ctor.name;\n const existing = openapi.components.schemas[name];\n\n if (!existing || mergeMode === \"override\") {\n openapi.components.schemas[name] = s;\n } else {\n openapi.components.schemas[name] = deepMerge(existing, s);\n }\n }\n}\n","/**\n * Utility functions for applying list queries to Metal ORM query builders.\n * Includes pagination, sorting, and parsing utilities.\n */\nimport type { ListQuery } from \"./listQuery.js\";\nimport type { SelectQueryBuilder } from \"metal-orm\";\nimport type { OrmSession } from \"metal-orm\";\nimport type { PaginatedResult } from \"metal-orm\";\n\n/**\n * Applies a list query to a Metal ORM select query builder and executes a paginated query.\n * \n * @typeParam TEntity - The entity type being queried\n * @param qb - The Metal ORM select query builder\n * @param session - The ORM session to use for execution\n * @param query - Optional list query parameters (pagination, filtering, sorting)\n * @returns A promise resolving to a paginated result\n * \n * @example\n * ```ts\n * const result = await applyListQuery(\n * db.selectFrom(\"users\"),\n * session,\n * { page: 1, pageSize: 10, where: { name: { eq: \"John\" } } }\n * );\n * ```\n */\nexport async function applyListQuery<TEntity extends object>(\n qb: SelectQueryBuilder<TEntity>,\n session: OrmSession,\n query?: ListQuery<TEntity>\n): Promise<PaginatedResult<TEntity>> {\n return qb.executePaged(session, pagedOptions(query));\n}\n\n/**\n * Generates pagination options with defaults.\n * \n * @param query - Optional pagination parameters\n * @param query.page - Page number (1-indexed, defaults to 1)\n * @param query.pageSize - Items per page (defaults to 10)\n * @returns Pagination options object\n */\nexport function pagedOptions(query?: { page?: number; pageSize?: number }): {\n page: number;\n pageSize: number;\n} {\n return {\n page: query?.page ?? 1,\n pageSize: query?.pageSize ?? 10,\n };\n}\n\n/**\n * Normalizes sort input into an array of strings.\n * Accepts comma-separated strings or arrays.\n * \n * @param sort - Sort input (string, array of strings, or undefined)\n * @returns Array of sort field names\n * \n * @example\n * ```ts\n * normalizeSort(\"name,-age\") // [\"name\", \"-age\"]\n * normalizeSort([\"name\", \"-age\"]) // [\"name\", \"-age\"]\n * ```\n */\nexport function normalizeSort(sort: unknown): string[] {\n if (Array.isArray(sort)) {\n return sort.flatMap((v) => String(v).split(\",\"));\n }\n if (typeof sort === \"string\") {\n return sort.split(\",\");\n }\n return [];\n}\n\n/**\n * Sort direction indicator.\n * \"ASC\" for ascending order, \"DESC\" for descending order.\n */\nexport type SortDirection = \"ASC\" | \"DESC\";\n\n/**\n * Represents a parsed sort token with direction and field information.\n */\nexport type SortToken = {\n /** Original sort string */\n raw: string;\n /** Field name without direction prefix */\n field: string;\n /** Dot-separated path for nested fields */\n path: string[];\n /** Sort direction (ASC or DESC) */\n direction: SortDirection;\n /** Whether this field references a relation */\n isRelationField: boolean;\n};\n\n/**\n * Options for parsing sort tokens.\n */\nexport type ParseSortOptions = {\n /** Maximum number of sort tokens to return (default: 20) */\n max?: number;\n /** Whitelist of allowed field paths (supports wildcards like \"user.*\") */\n whitelist?: string[];\n};\n\nfunction matchWhitelist(path: string[], whitelist: string[]): boolean {\n const pathStr = path.join(\".\");\n\n for (const pattern of whitelist) {\n if (pattern === pathStr) return true;\n\n if (pattern.endsWith(\"*\")) {\n const prefix = pattern.slice(0, -1);\n if (pathStr.startsWith(prefix)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Parses sort input into structured SortToken objects.\n * \n * @param sort - Sort input (string, array, or undefined)\n * @param opts - Optional parsing configuration\n * @returns Array of parsed sort tokens\n * \n * @example\n * ```ts\n * parseSort(\"name,-age,address.city\")\n * // Returns tokens with direction, field, path, and isRelationField\n * ```\n */\nexport function parseSort(sort: unknown, opts?: ParseSortOptions): SortToken[] {\n const max = opts?.max ?? 20;\n const whitelist = opts?.whitelist;\n\n const tokens = normalizeSort(sort)\n .map((s) => s.trim())\n .filter(Boolean)\n .slice(0, max)\n .map((raw) => {\n const direction: SortDirection = raw.startsWith(\"-\") ? \"DESC\" : \"ASC\";\n const field = raw.replace(/^[-+]/, \"\").trim();\n const path = field.split(\".\").map((p) => p.trim()).filter(Boolean);\n\n return {\n raw,\n field,\n path,\n direction,\n isRelationField: path.length > 1,\n };\n })\n .filter((t) => t.field.length > 0);\n\n if (whitelist && whitelist.length > 0) {\n return tokens.filter((t) => matchWhitelist(t.path, whitelist));\n }\n\n return tokens;\n}\n"],"mappings":"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","names":[]}
|
package/dist/metal/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metal ORM integration utilities for Adorn.
|
|
3
|
+
* Provides type-safe query building, entity schema generation, and metadata handling.
|
|
4
|
+
*/
|
|
1
5
|
export { ensureSymbolMetadata } from "./symbolMetadata.js";
|
|
2
6
|
export { readMetalDecoratorBagFromConstructor, METAL_METADATA_KEY } from "./readMetalBag.js";
|
|
3
7
|
export { schemaFromEntity } from "./schemaFromEntity.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oCAAoC,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE7F,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnG,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC3G,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metal/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oCAAoC,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE7F,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnG,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC3G,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/metal/index.js
CHANGED
|
@@ -96,7 +96,7 @@ function makeNullable(schema) {
|
|
|
96
96
|
return schema;
|
|
97
97
|
}
|
|
98
98
|
function isGenerated(col) {
|
|
99
|
-
return !!col.primary || !!col.autoIncrement || col.generated
|
|
99
|
+
return !!col.primary || !!col.autoIncrement || col.generated !== null && col.generated !== void 0;
|
|
100
100
|
}
|
|
101
101
|
function shouldIncludeColumn(col, mode) {
|
|
102
102
|
if (mode === "read") return true;
|
|
@@ -107,7 +107,7 @@ function shouldIncludeColumn(col, mode) {
|
|
|
107
107
|
function shouldRequire(col, mode) {
|
|
108
108
|
if (mode === "update") return false;
|
|
109
109
|
if (!col.notNull) return false;
|
|
110
|
-
if (mode === "create" && col.default
|
|
110
|
+
if (mode === "create" && (col.default !== null && col.default !== void 0)) return false;
|
|
111
111
|
return true;
|
|
112
112
|
}
|
|
113
113
|
function schemaFromEntity(ctor, opts = {}) {
|
package/dist/metal/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/metal/symbolMetadata.ts","../../src/metal/readMetalBag.ts","../../src/metal/schemaFromEntity.ts","../../src/metal/registerMetalEntities.ts","../../src/metal/applyListQuery.ts"],"sourcesContent":["export function ensureSymbolMetadata(): symbol {\n const s = Symbol as unknown as { metadata?: symbol };\n if (!s.metadata) {\n s.metadata = Symbol(\"Symbol.metadata\");\n }\n return s.metadata;\n}\n","import { ensureSymbolMetadata } from \"./symbolMetadata.js\";\n\nexport const METAL_METADATA_KEY = \"metal-orm:decorators\";\n\nexport type MetalColumnDef = {\n type: string;\n args?: unknown[];\n dialectTypes?: unknown;\n notNull?: boolean;\n primary?: boolean;\n tsType?: unknown;\n unique?: boolean;\n default?: unknown;\n autoIncrement?: boolean;\n generated?: unknown;\n check?: unknown;\n references?: unknown;\n comment?: string;\n};\n\nexport type MetalRelationMetadata = {\n kind: string;\n propertyKey: string;\n target?: (...args: any[]) => any;\n};\n\nexport type MetalDecoratorBag = {\n columns: Array<{ propertyName: string; column: MetalColumnDef }>;\n relations: Array<{ propertyName: string; relation: MetalRelationMetadata }>;\n};\n\nexport function readMetalDecoratorBagFromConstructor(ctor: object): MetalDecoratorBag | undefined {\n const metadataSymbol = ensureSymbolMetadata();\n const metadata = Reflect.get(ctor, metadataSymbol) as Record<PropertyKey, unknown> | undefined;\n return metadata?.[METAL_METADATA_KEY] as MetalDecoratorBag | undefined;\n}\n","import { readMetalDecoratorBagFromConstructor, type MetalColumnDef, type MetalDecoratorBag } from \"./readMetalBag.js\";\n\nexport type JsonSchema = Record<string, any>;\n\nexport type EntitySchemaMode = \"read\" | \"create\" | \"update\";\n\nexport interface SchemaFromEntityOptions {\n name?: string;\n stripEntitySuffix?: boolean;\n mode?: EntitySchemaMode;\n additionalProperties?: boolean;\n includeRelations?: \"none\" | \"inline\";\n}\n\nfunction defaultSchemaName(ctor: Function, strip: boolean) {\n const raw = ctor.name || \"AnonymousEntity\";\n return strip ? raw.replace(/Entity$/i, \"\") || raw : raw;\n}\n\nfunction columnTypeToSchema(col: MetalColumnDef): JsonSchema {\n const t = String(col.type).toLowerCase();\n const s: JsonSchema = {};\n\n if ([\"varchar\", \"text\", \"string\", \"char\", \"citext\"].includes(t)) {\n s.type = \"string\";\n const a0 = Array.isArray(col.args) ? col.args[0] : undefined;\n if (typeof a0 === \"number\" && Number.isFinite(a0) && a0 > 0) s.maxLength = a0;\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"uuid\"].includes(t)) {\n s.type = \"string\";\n s.format = \"uuid\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"timestamp\", \"timestamptz\", \"datetime\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date-time\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n if ([\"date\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bool\", \"boolean\"].includes(t)) {\n s.type = \"boolean\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"int\", \"int4\", \"integer\", \"smallint\", \"int2\", \"serial\", \"bigserial\"].includes(t)) {\n s.type = \"integer\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bigint\", \"int8\"].includes(t)) {\n s.type = \"string\";\n s.format = \"int64\";\n s.pattern = \"^-?\\\\d+$\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"float\", \"float4\", \"float8\", \"double\", \"decimal\", \"numeric\", \"real\"].includes(t)) {\n s.type = \"number\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"json\", \"jsonb\"].includes(t)) {\n s.type = [\"object\", \"array\", \"string\", \"number\", \"boolean\", \"null\"];\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n s.type = \"string\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n}\n\nfunction isLiteralDefault(v: unknown) {\n return v === null || [\"string\", \"number\", \"boolean\"].includes(typeof v);\n}\n\nfunction makeNullable(schema: JsonSchema): JsonSchema {\n if (schema.type === \"null\") return schema;\n if (Array.isArray(schema.type)) {\n if (!schema.type.includes(\"null\")) schema.type = [...schema.type, \"null\"];\n return schema;\n }\n if (typeof schema.type === \"string\") {\n schema.type = [schema.type, \"null\"];\n } else {\n schema.type = [\"null\"];\n }\n return schema;\n}\n\nfunction isGenerated(col: MetalColumnDef) {\n return !!col.primary || !!col.autoIncrement || col.generated != null;\n}\n\nfunction shouldIncludeColumn(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"read\") return true;\n if (mode === \"create\") return !isGenerated(col);\n if (mode === \"update\") return true;\n return true;\n}\n\nfunction shouldRequire(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"update\") return false;\n if (!col.notNull) return false;\n if (mode === \"create\" && col.default != null) return false;\n return true;\n}\n\nexport function schemaFromEntity(ctor: Function, opts: SchemaFromEntityOptions = {}): JsonSchema | undefined {\n const bag = readMetalDecoratorBagFromConstructor(ctor);\n if (!bag || !Array.isArray(bag.columns) || bag.columns.length === 0) return undefined;\n\n const mode = opts.mode ?? \"read\";\n const name = opts.name ?? defaultSchemaName(ctor, opts.stripEntitySuffix ?? true);\n\n const schema: JsonSchema = {\n title: name,\n type: \"object\",\n properties: {},\n additionalProperties: opts.additionalProperties ?? true\n };\n\n const required: string[] = [];\n\n for (const entry of bag.columns) {\n const prop = entry.propertyName;\n const col = entry.column;\n\n if (!shouldIncludeColumn(col, mode)) continue;\n\n const propSchema = columnTypeToSchema(col);\n\n if (!col.notNull) makeNullable(propSchema);\n\n if (isLiteralDefault(col.default)) propSchema.default = col.default;\n\n if (mode === \"read\" && col.primary) propSchema.readOnly = true;\n\n (schema.properties as any)[prop] = propSchema;\n\n if (shouldRequire(col, mode)) required.push(prop);\n }\n\n if (required.length) schema.required = required;\n\n if ((opts.includeRelations ?? \"none\") === \"inline\") {\n for (const r of bag.relations ?? []) {\n const rel = r.relation;\n if (typeof rel?.target !== \"function\") continue;\n\n let target: any;\n try {\n target = rel.target();\n } catch {\n continue;\n }\n if (typeof target !== \"function\") continue;\n\n const targetName = defaultSchemaName(target, true);\n (schema.properties as any)[r.propertyName] = { $ref: `#/components/schemas/${targetName}` };\n }\n }\n\n return schema;\n}\n","import { schemaFromEntity, type SchemaFromEntityOptions, type JsonSchema } from \"./schemaFromEntity.js\";\n\nfunction deepMerge(a: any, b: any): any {\n if (Array.isArray(a) || Array.isArray(b)) return b ?? a;\n if (a && typeof a === \"object\" && b && typeof b === \"object\") {\n const out: any = { ...a };\n for (const [k, v] of Object.entries(b)) out[k] = deepMerge(out[k], v);\n return out;\n }\n return b ?? a;\n}\n\nexport interface RegisterMetalEntitiesOptions extends SchemaFromEntityOptions {\n merge?: \"override\" | \"merge\";\n}\n\nexport function registerMetalEntities(\n openapi: any,\n entities: Function[],\n opts: RegisterMetalEntitiesOptions = {}\n) {\n openapi.components ??= {};\n openapi.components.schemas ??= {};\n\n const mergeMode = opts.merge ?? \"merge\";\n\n for (const ctor of entities) {\n const s = schemaFromEntity(ctor, opts);\n if (!s) continue;\n\n const name = s.title || ctor.name;\n const existing = openapi.components.schemas[name];\n\n if (!existing || mergeMode === \"override\") {\n openapi.components.schemas[name] = s;\n } else {\n openapi.components.schemas[name] = deepMerge(existing, s);\n }\n }\n}\n","import type { ListQuery } from \"./listQuery.js\";\nimport type { SelectQueryBuilder } from \"metal-orm\";\nimport type { OrmSession } from \"metal-orm\";\nimport type { PaginatedResult } from \"metal-orm\";\n\nexport async function applyListQuery<TEntity extends object>(\n qb: SelectQueryBuilder<TEntity>,\n session: OrmSession,\n query?: ListQuery<TEntity>\n): Promise<PaginatedResult<TEntity>> {\n return qb.executePaged(session, pagedOptions(query));\n}\n\nexport function pagedOptions(query?: { page?: number; pageSize?: number }): {\n page: number;\n pageSize: number;\n} {\n return {\n page: query?.page ?? 1,\n pageSize: query?.pageSize ?? 10,\n };\n}\n\nexport function normalizeSort(sort: unknown): string[] {\n if (Array.isArray(sort)) {\n return sort.flatMap((v) => String(v).split(\",\"));\n }\n if (typeof sort === \"string\") {\n return sort.split(\",\");\n }\n return [];\n}\n\nexport type SortDirection = \"ASC\" | \"DESC\";\n\nexport type SortToken = {\n raw: string;\n field: string;\n path: string[];\n direction: SortDirection;\n isRelationField: boolean;\n};\n\nexport type ParseSortOptions = {\n max?: number;\n whitelist?: string[];\n};\n\nfunction matchWhitelist(path: string[], whitelist: string[]): boolean {\n const pathStr = path.join(\".\");\n\n for (const pattern of whitelist) {\n if (pattern === pathStr) return true;\n\n if (pattern.endsWith(\"*\")) {\n const prefix = pattern.slice(0, -1);\n if (pathStr.startsWith(prefix)) return true;\n }\n }\n\n return false;\n}\n\nexport function parseSort(sort: unknown, opts?: ParseSortOptions): SortToken[] {\n const max = opts?.max ?? 20;\n const whitelist = opts?.whitelist;\n\n const tokens = normalizeSort(sort)\n .map((s) => s.trim())\n .filter(Boolean)\n .slice(0, max)\n .map((raw) => {\n const direction: SortDirection = raw.startsWith(\"-\") ? \"DESC\" : \"ASC\";\n const field = raw.replace(/^[-+]/, \"\").trim();\n const path = field.split(\".\").map((p) => p.trim()).filter(Boolean);\n\n return {\n raw,\n field,\n path,\n direction,\n isRelationField: path.length > 1,\n };\n })\n .filter((t) => t.field.length > 0);\n\n if (whitelist && whitelist.length > 0) {\n return tokens.filter((t) => matchWhitelist(t.path, whitelist));\n }\n\n return tokens;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/metal/symbolMetadata.ts","../../src/metal/readMetalBag.ts","../../src/metal/schemaFromEntity.ts","../../src/metal/registerMetalEntities.ts","../../src/metal/applyListQuery.ts"],"sourcesContent":["/**\n * Ensures the Symbol.metadata symbol exists and returns it.\n * Used by Metal ORM decorators to store metadata on classes.\n * \n * @returns The Symbol.metadata symbol\n */\nexport function ensureSymbolMetadata(): symbol {\n const s = Symbol as unknown as { metadata?: symbol };\n if (!s.metadata) {\n s.metadata = Symbol(\"Symbol.metadata\");\n }\n return s.metadata;\n}\n","/**\n * Metal ORM decorator metadata utilities.\n * Provides functions to read and manage entity decorator metadata.\n */\nimport { ensureSymbolMetadata } from \"./symbolMetadata.js\";\n\n/**\n * Symbol key for storing Metal ORM decorator metadata.\n */\nexport const METAL_METADATA_KEY = \"metal-orm:decorators\";\n\n/**\n * Represents a column definition in Metal ORM entity metadata.\n */\nexport type MetalColumnDef = {\n /** Database column type (e.g., \"varchar\", \"int\", \"timestamp\") */\n type: string;\n /** Additional type arguments (e.g., length for varchar) */\n args?: unknown[];\n /** Database dialect-specific type definitions */\n dialectTypes?: unknown;\n /** Whether the column is NOT NULL */\n notNull?: boolean;\n /** Whether this is a primary key column */\n primary?: boolean;\n /** TypeScript type override for the column */\n tsType?: unknown;\n /** Whether the column has a unique constraint */\n unique?: boolean;\n /** Default value for the column */\n default?: unknown;\n /** Whether the column auto-increments */\n autoIncrement?: boolean;\n /** How the column value is generated (e.g., \"byDefault\", \"always\") */\n generated?: unknown;\n /** CHECK constraint for the column */\n check?: unknown;\n /** Foreign key references */\n references?: unknown;\n /** Column comment/description */\n comment?: string;\n};\n\n/**\n * Represents relation metadata in a Metal ORM entity.\n */\nexport type MetalRelationMetadata = {\n /** Type of relation (e.g., \"hasMany\", \"belongsTo\") */\n kind: string;\n /** Property name of the relation */\n propertyKey: string;\n /** Target entity constructor (optional, may be a getter) */\n target?: (...args: any[]) => any;\n};\n\n/**\n * Container for all decorator metadata of a Metal ORM entity.\n */\nexport type MetalDecoratorBag = {\n /** Array of column definitions */\n columns: Array<{ propertyName: string; column: MetalColumnDef }>;\n /** Array of relation metadata */\n relations: Array<{ propertyName: string; relation: MetalRelationMetadata }>;\n};\n\n/**\n * Reads Metal ORM decorator metadata from a class constructor.\n * \n * @param ctor - The class constructor to read metadata from\n * @returns The decorator bag if metadata exists, undefined otherwise\n */\nexport function readMetalDecoratorBagFromConstructor(ctor: object): MetalDecoratorBag | undefined {\n const metadataSymbol = ensureSymbolMetadata();\n const metadata = Reflect.get(ctor, metadataSymbol) as Record<PropertyKey, unknown> | undefined;\n return metadata?.[METAL_METADATA_KEY] as MetalDecoratorBag | undefined;\n}\n","/**\n * Converts Metal ORM entity decorators into JSON Schema for OpenAPI.\n */\nimport { readMetalDecoratorBagFromConstructor, type MetalColumnDef } from \"./readMetalBag.js\";\n\n/**\n * JSON Schema representation for OpenAPI.\n */\nexport type JsonSchema = Record<string, any>;\n\n/**\n * Schema generation mode determining which fields are included.\n * - \"read\": All fields (read-only marked on primary keys)\n * - \"create\": Exclude auto-generated fields (primary keys, autoIncrement)\n * - \"update\": All fields (none required)\n */\nexport type EntitySchemaMode = \"read\" | \"create\" | \"update\";\n\n/**\n * Options for generating a JSON Schema from an entity.\n */\nexport interface SchemaFromEntityOptions {\n /** Custom name for the schema (defaults to entity class name) */\n name?: string;\n /** Strip \"Entity\" suffix from class name (default: true) */\n stripEntitySuffix?: boolean;\n /** Schema generation mode (default: \"read\") */\n mode?: EntitySchemaMode;\n /** Allow additional properties not defined in schema (default: true) */\n additionalProperties?: boolean;\n /** How to handle relations in the schema (default: \"none\") */\n includeRelations?: \"none\" | \"inline\";\n}\n\nfunction defaultSchemaName(ctor: Function, strip: boolean) {\n const raw = ctor.name || \"AnonymousEntity\";\n return strip ? raw.replace(/Entity$/i, \"\") || raw : raw;\n}\n\nfunction columnTypeToSchema(col: MetalColumnDef): JsonSchema {\n const t = String(col.type).toLowerCase();\n const s: JsonSchema = {};\n\n if ([\"varchar\", \"text\", \"string\", \"char\", \"citext\"].includes(t)) {\n s.type = \"string\";\n const a0 = Array.isArray(col.args) ? col.args[0] : undefined;\n if (typeof a0 === \"number\" && Number.isFinite(a0) && a0 > 0) s.maxLength = a0;\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"uuid\"].includes(t)) {\n s.type = \"string\";\n s.format = \"uuid\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"timestamp\", \"timestamptz\", \"datetime\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date-time\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n if ([\"date\"].includes(t)) {\n s.type = \"string\";\n s.format = \"date\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bool\", \"boolean\"].includes(t)) {\n s.type = \"boolean\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"int\", \"int4\", \"integer\", \"smallint\", \"int2\", \"serial\", \"bigserial\"].includes(t)) {\n s.type = \"integer\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"bigint\", \"int8\"].includes(t)) {\n s.type = \"string\";\n s.format = \"int64\";\n s.pattern = \"^-?\\\\d+$\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"float\", \"float4\", \"float8\", \"double\", \"decimal\", \"numeric\", \"real\"].includes(t)) {\n s.type = \"number\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n if ([\"json\", \"jsonb\"].includes(t)) {\n s.type = [\"object\", \"array\", \"string\", \"number\", \"boolean\", \"null\"];\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n }\n\n s.type = \"string\";\n if (typeof col.comment === \"string\") s.description = col.comment;\n return s;\n}\n\nfunction isLiteralDefault(v: unknown) {\n return v === null || [\"string\", \"number\", \"boolean\"].includes(typeof v);\n}\n\nfunction makeNullable(schema: JsonSchema): JsonSchema {\n if (schema.type === \"null\") return schema;\n if (Array.isArray(schema.type)) {\n if (!schema.type.includes(\"null\")) schema.type = [...schema.type, \"null\"];\n return schema;\n }\n if (typeof schema.type === \"string\") {\n schema.type = [schema.type, \"null\"];\n } else {\n schema.type = [\"null\"];\n }\n return schema;\n}\n\nfunction isGenerated(col: MetalColumnDef) {\n return !!col.primary || !!col.autoIncrement || (col.generated !== null && col.generated !== undefined);\n}\n\nfunction shouldIncludeColumn(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"read\") return true;\n if (mode === \"create\") return !isGenerated(col);\n if (mode === \"update\") return true;\n return true;\n}\n\nfunction shouldRequire(col: MetalColumnDef, mode: \"read\" | \"create\" | \"update\") {\n if (mode === \"update\") return false;\n if (!col.notNull) return false;\n if (mode === \"create\" && (col.default !== null && col.default !== undefined)) return false;\n return true;\n}\n\n/**\n * Generates a JSON Schema from a Metal ORM entity class.\n * \n * @param ctor - The entity class constructor\n * @param opts - Schema generation options\n * @returns JSON Schema object or undefined if entity has no columns\n * \n * @example\n * ```ts\n * const schema = schemaFromEntity(User, { mode: \"create\" });\n * // Returns: { title: \"User\", type: \"object\", properties: {...}, required: [...] }\n * ```\n */\nexport function schemaFromEntity(ctor: Function, opts: SchemaFromEntityOptions = {}): JsonSchema | undefined {\n const bag = readMetalDecoratorBagFromConstructor(ctor);\n if (!bag || !Array.isArray(bag.columns) || bag.columns.length === 0) return undefined;\n\n const mode = opts.mode ?? \"read\";\n const name = opts.name ?? defaultSchemaName(ctor, opts.stripEntitySuffix ?? true);\n\n const schema: JsonSchema = {\n title: name,\n type: \"object\",\n properties: {},\n additionalProperties: opts.additionalProperties ?? true\n };\n\n const required: string[] = [];\n\n for (const entry of bag.columns) {\n const prop = entry.propertyName;\n const col = entry.column;\n\n if (!shouldIncludeColumn(col, mode)) continue;\n\n const propSchema = columnTypeToSchema(col);\n\n if (!col.notNull) makeNullable(propSchema);\n\n if (isLiteralDefault(col.default)) propSchema.default = col.default;\n\n if (mode === \"read\" && col.primary) propSchema.readOnly = true;\n\n (schema.properties as any)[prop] = propSchema;\n\n if (shouldRequire(col, mode)) required.push(prop);\n }\n\n if (required.length) schema.required = required;\n\n if ((opts.includeRelations ?? \"none\") === \"inline\") {\n for (const r of bag.relations ?? []) {\n const rel = r.relation;\n if (typeof rel?.target !== \"function\") continue;\n\n let target: any;\n try {\n target = rel.target();\n } catch {\n continue;\n }\n if (typeof target !== \"function\") continue;\n\n const targetName = defaultSchemaName(target, true);\n (schema.properties as any)[r.propertyName] = { $ref: `#/components/schemas/${targetName}` };\n }\n }\n\n return schema;\n}\n","/**\n * Utilities for registering Metal ORM entities as OpenAPI components.\n */\nimport { schemaFromEntity, type SchemaFromEntityOptions } from \"./schemaFromEntity.js\";\n\nfunction deepMerge(a: any, b: any): any {\n if (Array.isArray(a) || Array.isArray(b)) return b ?? a;\n if (a && typeof a === \"object\" && b && typeof b === \"object\") {\n const out: any = { ...a };\n for (const [k, v] of Object.entries(b)) out[k] = deepMerge(out[k], v);\n return out;\n }\n return b ?? a;\n}\n\n/**\n * Options for registering Metal ORM entities.\n */\nexport interface RegisterMetalEntitiesOptions extends SchemaFromEntityOptions {\n /** How to handle existing schemas with the same name: \"override\" or \"merge\" (default: \"merge\") */\n merge?: \"override\" | \"merge\";\n}\n\n/**\n * Registers Metal ORM entity schemas in an OpenAPI document.\n * \n * @param openapi - The OpenAPI document to modify (will be mutated)\n * @param entities - Array of entity class constructors to register\n * @param opts - Optional configuration for schema generation and merging\n * \n * @example\n * ```ts\n * const openapi = { components: { schemas: {} } };\n * registerMetalEntities(openapi, [User, Post, Comment]);\n * ```\n */\nexport function registerMetalEntities(\n openapi: any,\n entities: Function[],\n opts: RegisterMetalEntitiesOptions = {}\n) {\n openapi.components ??= {};\n openapi.components.schemas ??= {};\n\n const mergeMode = opts.merge ?? \"merge\";\n\n for (const ctor of entities) {\n const s = schemaFromEntity(ctor, opts);\n if (!s) continue;\n\n const name = s.title || ctor.name;\n const existing = openapi.components.schemas[name];\n\n if (!existing || mergeMode === \"override\") {\n openapi.components.schemas[name] = s;\n } else {\n openapi.components.schemas[name] = deepMerge(existing, s);\n }\n }\n}\n","/**\n * Utility functions for applying list queries to Metal ORM query builders.\n * Includes pagination, sorting, and parsing utilities.\n */\nimport type { ListQuery } from \"./listQuery.js\";\nimport type { SelectQueryBuilder } from \"metal-orm\";\nimport type { OrmSession } from \"metal-orm\";\nimport type { PaginatedResult } from \"metal-orm\";\n\n/**\n * Applies a list query to a Metal ORM select query builder and executes a paginated query.\n * \n * @typeParam TEntity - The entity type being queried\n * @param qb - The Metal ORM select query builder\n * @param session - The ORM session to use for execution\n * @param query - Optional list query parameters (pagination, filtering, sorting)\n * @returns A promise resolving to a paginated result\n * \n * @example\n * ```ts\n * const result = await applyListQuery(\n * db.selectFrom(\"users\"),\n * session,\n * { page: 1, pageSize: 10, where: { name: { eq: \"John\" } } }\n * );\n * ```\n */\nexport async function applyListQuery<TEntity extends object>(\n qb: SelectQueryBuilder<TEntity>,\n session: OrmSession,\n query?: ListQuery<TEntity>\n): Promise<PaginatedResult<TEntity>> {\n return qb.executePaged(session, pagedOptions(query));\n}\n\n/**\n * Generates pagination options with defaults.\n * \n * @param query - Optional pagination parameters\n * @param query.page - Page number (1-indexed, defaults to 1)\n * @param query.pageSize - Items per page (defaults to 10)\n * @returns Pagination options object\n */\nexport function pagedOptions(query?: { page?: number; pageSize?: number }): {\n page: number;\n pageSize: number;\n} {\n return {\n page: query?.page ?? 1,\n pageSize: query?.pageSize ?? 10,\n };\n}\n\n/**\n * Normalizes sort input into an array of strings.\n * Accepts comma-separated strings or arrays.\n * \n * @param sort - Sort input (string, array of strings, or undefined)\n * @returns Array of sort field names\n * \n * @example\n * ```ts\n * normalizeSort(\"name,-age\") // [\"name\", \"-age\"]\n * normalizeSort([\"name\", \"-age\"]) // [\"name\", \"-age\"]\n * ```\n */\nexport function normalizeSort(sort: unknown): string[] {\n if (Array.isArray(sort)) {\n return sort.flatMap((v) => String(v).split(\",\"));\n }\n if (typeof sort === \"string\") {\n return sort.split(\",\");\n }\n return [];\n}\n\n/**\n * Sort direction indicator.\n * \"ASC\" for ascending order, \"DESC\" for descending order.\n */\nexport type SortDirection = \"ASC\" | \"DESC\";\n\n/**\n * Represents a parsed sort token with direction and field information.\n */\nexport type SortToken = {\n /** Original sort string */\n raw: string;\n /** Field name without direction prefix */\n field: string;\n /** Dot-separated path for nested fields */\n path: string[];\n /** Sort direction (ASC or DESC) */\n direction: SortDirection;\n /** Whether this field references a relation */\n isRelationField: boolean;\n};\n\n/**\n * Options for parsing sort tokens.\n */\nexport type ParseSortOptions = {\n /** Maximum number of sort tokens to return (default: 20) */\n max?: number;\n /** Whitelist of allowed field paths (supports wildcards like \"user.*\") */\n whitelist?: string[];\n};\n\nfunction matchWhitelist(path: string[], whitelist: string[]): boolean {\n const pathStr = path.join(\".\");\n\n for (const pattern of whitelist) {\n if (pattern === pathStr) return true;\n\n if (pattern.endsWith(\"*\")) {\n const prefix = pattern.slice(0, -1);\n if (pathStr.startsWith(prefix)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Parses sort input into structured SortToken objects.\n * \n * @param sort - Sort input (string, array, or undefined)\n * @param opts - Optional parsing configuration\n * @returns Array of parsed sort tokens\n * \n * @example\n * ```ts\n * parseSort(\"name,-age,address.city\")\n * // Returns tokens with direction, field, path, and isRelationField\n * ```\n */\nexport function parseSort(sort: unknown, opts?: ParseSortOptions): SortToken[] {\n const max = opts?.max ?? 20;\n const whitelist = opts?.whitelist;\n\n const tokens = normalizeSort(sort)\n .map((s) => s.trim())\n .filter(Boolean)\n .slice(0, max)\n .map((raw) => {\n const direction: SortDirection = raw.startsWith(\"-\") ? \"DESC\" : \"ASC\";\n const field = raw.replace(/^[-+]/, \"\").trim();\n const path = field.split(\".\").map((p) => p.trim()).filter(Boolean);\n\n return {\n raw,\n field,\n path,\n direction,\n isRelationField: path.length > 1,\n };\n })\n .filter((t) => t.field.length > 0);\n\n if (whitelist && whitelist.length > 0) {\n return tokens.filter((t) => matchWhitelist(t.path, whitelist));\n }\n\n return tokens;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a query for listing entities with optional filtering, sorting, and pagination.
|
|
3
|
+
*
|
|
4
|
+
* @typeParam TEntity - The entity type being queried
|
|
5
|
+
* @typeParam Depth - Maximum nesting depth for relations (default: 2)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* type UserListQuery = ListQuery<User, 2>;
|
|
10
|
+
* const query: UserListQuery = {
|
|
11
|
+
* where: { name: { contains: "John" } },
|
|
12
|
+
* sort: "-createdAt",
|
|
13
|
+
* page: 1,
|
|
14
|
+
* pageSize: 20
|
|
15
|
+
* };
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
1
18
|
import type { SearchWhereDepth } from "./searchWhere.js";
|
|
2
19
|
import type { QueryOptions } from "./queryOptions.js";
|
|
3
20
|
export type ListQuery<TEntity extends object, Depth extends SearchWhereDepth = 2> = QueryOptions<TEntity, Depth> & {
|
|
21
|
+
/** Page number (1-indexed) */
|
|
4
22
|
page?: number;
|
|
23
|
+
/** Number of items per page */
|
|
5
24
|
pageSize?: number;
|
|
6
25
|
};
|
|
7
26
|
//# sourceMappingURL=listQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listQuery.d.ts","sourceRoot":"","sources":["../../src/metal/listQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"listQuery.d.ts","sourceRoot":"","sources":["../../src/metal/listQuery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,MAAM,SAAS,CAAC,OAAO,SAAS,MAAM,EAAE,KAAK,SAAS,gBAAgB,GAAG,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG;IACjH,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA"}
|