adorn-api 1.0.19 → 1.0.21
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/cli.cjs +537 -25
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +537 -25
- package/dist/cli.js.map +1 -1
- package/dist/compiler/schema/objectHandler.d.ts +40 -0
- package/dist/compiler/schema/objectHandler.d.ts.map +1 -1
- package/dist/compiler/schema/openapi.d.ts.map +1 -1
- package/dist/compiler/schema/queryBuilderAnalyzer.d.ts +43 -0
- package/dist/compiler/schema/queryBuilderAnalyzer.d.ts.map +1 -0
- package/dist/compiler/schema/queryBuilderSchemaBuilder.d.ts +13 -0
- package/dist/compiler/schema/queryBuilderSchemaBuilder.d.ts.map +1 -0
- package/dist/compiler/schema/types.d.ts +1 -0
- package/dist/compiler/schema/types.d.ts.map +1 -1
- package/dist/metal/applyListQuery.d.ts +1 -1
- package/dist/metal/applyListQuery.d.ts.map +1 -1
- package/dist/metal/index.cjs.map +1 -1
- package/dist/metal/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -4,6 +4,46 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import ts from "typescript";
|
|
6
6
|
import type { JsonSchema, SchemaContext } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Checks if a type is a type parameter (generic type variable like T, U, etc.)
|
|
9
|
+
*
|
|
10
|
+
* @param type - The type to check
|
|
11
|
+
* @returns True if the type is a type parameter
|
|
12
|
+
*/
|
|
13
|
+
export declare function isTypeParameter(type: ts.Type): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the name of a type parameter if the type is one
|
|
16
|
+
*
|
|
17
|
+
* @param type - The type to check
|
|
18
|
+
* @returns The type parameter name, or null if not a type parameter
|
|
19
|
+
*/
|
|
20
|
+
export declare function getTypeParameterName(type: ts.Type): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Extracts type arguments from a generic type reference
|
|
23
|
+
*
|
|
24
|
+
* @param type - The type to extract from
|
|
25
|
+
* @returns Array of type arguments, or undefined if not a generic type
|
|
26
|
+
*/
|
|
27
|
+
export declare function getTypeArguments(type: ts.Type): ts.Type[] | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a type parameter substitution map from a generic type
|
|
30
|
+
* For interface Foo<T, U>, creates Map("T" -> arg1, "U" -> arg2)
|
|
31
|
+
*
|
|
32
|
+
* @param type - The generic type
|
|
33
|
+
* @param typeNode - Optional type node for extracting type parameter names
|
|
34
|
+
* @param checker - TypeScript type checker
|
|
35
|
+
* @returns Map of type parameter names to actual types
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTypeParameterSubstitutions(type: ts.Type, typeNode: ts.TypeNode | undefined, checker: ts.TypeChecker): Map<string, ts.Type> | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves a type parameter to its actual type if a substitution is available
|
|
40
|
+
*
|
|
41
|
+
* @param type - The type to resolve
|
|
42
|
+
* @param substitutions - Map of type parameter names to actual types
|
|
43
|
+
* @param _checker - TypeScript type checker (unused, for future extensions)
|
|
44
|
+
* @returns The resolved type if the type is a type parameter with a substitution, otherwise null
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveTypeParameter(type: ts.Type, substitutions: Map<string, ts.Type> | undefined, _checker: ts.TypeChecker): ts.Type | null;
|
|
7
47
|
/**
|
|
8
48
|
* Handles TypeScript object types and converts them to JSON Schema.
|
|
9
49
|
* Manages named schemas, component registration, and cycle detection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectHandler.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/objectHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG5D;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,EAAE,CAAC,UAAU,EACnB,GAAG,EAAE,aAAa,EAClB,QAAQ,CAAC,EAAE,EAAE,CAAC,QAAQ,GACrB,UAAU,
|
|
1
|
+
{"version":3,"file":"objectHandler.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/objectHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG5D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,GAAG,IAAI,CAMjE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,SAAS,CAKrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,EACjC,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,SAAS,CA0BlC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,SAAS,EAC/C,QAAQ,EAAE,EAAE,CAAC,WAAW,GACvB,EAAE,CAAC,IAAI,GAAG,IAAI,CAQhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,EAAE,CAAC,UAAU,EACnB,GAAG,EAAE,aAAa,EAClB,QAAQ,CAAC,EAAE,EAAE,CAAC,QAAQ,GACrB,UAAU,CAiDZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,EAAE,CAAC,UAAU,EACnB,GAAG,EAAE,aAAa,EAClB,SAAS,CAAC,EAAE,EAAE,CAAC,QAAQ,GACtB,UAAU,CAyDZ;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,WAAW,GAAG,OAAO,CAQnF;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,GAAG,IAAI,CAchG;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,GAAG,OAAO,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAGnD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAKlG;AA0ID,UAAU,mBAAmB;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACvC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,mBAAmB,GAAG,IAAI,CAwB5B;AAwBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,WAAW,GAAG,MAAM,GAAG,IAAI,CAKzF;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,UAAU,CAsDzF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/openapi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAsC,MAAM,+BAA+B,CAAC;AAG3G,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/openapi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAsC,MAAM,+BAA+B,CAAC;AAG3G,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,YAAY,CAAC;AAY5D;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KACrC,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,EAAE,CAAC,WAAW,EACvB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,uBAAuB,CAAA;CAAO,GACvF,SAAS,CAkDX"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Builder Schema Analyzer
|
|
3
|
+
* Parses method bodies to detect selectFromEntity patterns and extract schema information
|
|
4
|
+
* Supports variable reassignment patterns (e.g., let qb = selectFromEntity(); qb = qb.select())
|
|
5
|
+
*
|
|
6
|
+
* Improvements made:
|
|
7
|
+
* - Fixed variable tracking to support reassignments like "let qb = selectFromEntity(Entity); qb = qb.select(...)"
|
|
8
|
+
* - Enhanced `extractChainedOperation` to detect both direct calls and method chains
|
|
9
|
+
* - Added proper handling for selectFromEntity/selectFrom patterns in variable initialization
|
|
10
|
+
* - Fixed PaginatedResult schema filtering to properly filter items array instead of wrapper
|
|
11
|
+
*/
|
|
12
|
+
import ts from "typescript";
|
|
13
|
+
/**
|
|
14
|
+
* Represents a schema extracted from a query builder chain
|
|
15
|
+
*/
|
|
16
|
+
export interface QueryBuilderSchema {
|
|
17
|
+
/** Entity class name (e.g., "BlogPost") */
|
|
18
|
+
entityName: string;
|
|
19
|
+
/** Fields selected via .select() calls */
|
|
20
|
+
selectedFields: string[];
|
|
21
|
+
/** Relations included via .include() calls */
|
|
22
|
+
includes: Record<string, QueryBuilderSchema | boolean>;
|
|
23
|
+
/** Whether query ends with .executePaged() instead of .execute() */
|
|
24
|
+
isPaged: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Analysis options for query builder detection
|
|
28
|
+
*/
|
|
29
|
+
export interface QueryBuilderAnalyzerOptions {
|
|
30
|
+
/** Maximum depth to traverse for nested includes */
|
|
31
|
+
maxDepth?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Analyzes a method declaration to detect query builder patterns and extract schema
|
|
35
|
+
* Supports variable reassignment patterns (e.g., let qb = selectFromEntity(); qb = qb.select())
|
|
36
|
+
*
|
|
37
|
+
* @param methodDeclaration - The method declaration to analyze
|
|
38
|
+
* @param checker - TypeScript type checker
|
|
39
|
+
* @param options - Analyzer options
|
|
40
|
+
* @returns Query builder schema if pattern detected, null otherwise
|
|
41
|
+
*/
|
|
42
|
+
export declare function analyzeQueryBuilderForSchema(methodDeclaration: ts.MethodDeclaration, checker: ts.TypeChecker, options?: QueryBuilderAnalyzerOptions): QueryBuilderSchema | null;
|
|
43
|
+
//# sourceMappingURL=queryBuilderAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryBuilderAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/queryBuilderAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC;IACvD,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,EACvC,OAAO,EAAE,EAAE,CAAC,WAAW,EACvB,OAAO,GAAE,2BAAgC,GACxC,kBAAkB,GAAG,IAAI,CAyB3B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Builder from Query Builder Analysis
|
|
3
|
+
* Converts QueryBuilderSchema into minimal OpenAPI 3.1 schemas
|
|
4
|
+
*/
|
|
5
|
+
import type { JsonSchema, SchemaContext } from "./types.js";
|
|
6
|
+
import type { QueryBuilderSchema } from "./queryBuilderAnalyzer.js";
|
|
7
|
+
import ts from "typescript";
|
|
8
|
+
export declare function buildSchemaFromQueryBuilder(querySchema: QueryBuilderSchema, entityType: ts.ObjectType, ctx: SchemaContext): JsonSchema | null;
|
|
9
|
+
/**
|
|
10
|
+
* Wraps a schema in PaginatedResult if needed
|
|
11
|
+
*/
|
|
12
|
+
export declare function wrapInPaginatedResult(schema: JsonSchema): JsonSchema;
|
|
13
|
+
//# sourceMappingURL=queryBuilderSchemaBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryBuilderSchemaBuilder.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/queryBuilderSchemaBuilder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,kBAAkB,EAC/B,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,GAAG,EAAE,aAAa,GACjB,UAAU,GAAG,IAAI,CAiBnB;AA4ED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAcpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,oBAAoB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,qBAAqB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC;IACxB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/compiler/schema/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,oBAAoB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,qBAAqB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC;IACxB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;CACnD"}
|
|
@@ -24,7 +24,7 @@ import type { PaginatedResult } from "metal-orm";
|
|
|
24
24
|
* );
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
|
-
export declare function applyListQuery<TEntity extends object>(qb: SelectQueryBuilder<
|
|
27
|
+
export declare function applyListQuery<TEntity extends object>(qb: SelectQueryBuilder<any, any>, session: OrmSession, query?: ListQuery<TEntity>): Promise<PaginatedResult<TEntity>>;
|
|
28
28
|
/**
|
|
29
29
|
* Generates pagination options with defaults.
|
|
30
30
|
*
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,GAAG,EAAE,GAAG,CAAC,EAChC,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.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":["/**\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":[]}
|
|
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<any, any>,\n session: OrmSession,\n query?: ListQuery<TEntity>\n): Promise<PaginatedResult<TEntity>> {\n return qb.executePaged(session, pagedOptions(query)) as Promise<PaginatedResult<TEntity>>;\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.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":["/**\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
|
+
{"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<any, any>,\n session: OrmSession,\n query?: ListQuery<TEntity>\n): Promise<PaginatedResult<TEntity>> {\n return qb.executePaged(session, pagedOptions(query)) as Promise<PaginatedResult<TEntity>>;\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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adorn-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "Stage-3 decorator-first OpenAPI + routing toolkit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"ajv": "^8.17.1",
|
|
66
66
|
"ajv-formats": "^3.0.1",
|
|
67
67
|
"cors": "^2.8.5",
|
|
68
|
-
"metal-orm": "^1.0.
|
|
68
|
+
"metal-orm": "^1.0.80",
|
|
69
69
|
"swagger-ui-express": "^5.0.0",
|
|
70
70
|
"typescript": "^5.9.0"
|
|
71
71
|
},
|