metal-orm 1.0.89 → 1.0.91

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.
Files changed (57) hide show
  1. package/dist/index.cjs +2968 -2983
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +784 -251
  4. package/dist/index.d.ts +784 -251
  5. package/dist/index.js +2913 -2975
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -3
  8. package/src/codegen/typescript.ts +29 -40
  9. package/src/core/ast/expression-builders.ts +34 -53
  10. package/src/core/ast/expression-nodes.ts +51 -72
  11. package/src/core/ast/expression-visitor.ts +219 -252
  12. package/src/core/ast/expression.ts +20 -21
  13. package/src/core/ddl/introspect/utils.ts +45 -45
  14. package/src/core/dialect/abstract.ts +55 -81
  15. package/src/core/execution/db-executor.ts +4 -5
  16. package/src/core/execution/executors/mysql-executor.ts +7 -9
  17. package/src/decorators/bootstrap.ts +29 -26
  18. package/src/dto/apply-filter.ts +279 -0
  19. package/src/dto/dto-types.ts +229 -0
  20. package/src/dto/filter-types.ts +193 -0
  21. package/src/dto/index.ts +97 -0
  22. package/src/dto/openapi/generators/base.ts +29 -0
  23. package/src/dto/openapi/generators/column.ts +34 -0
  24. package/src/dto/openapi/generators/dto.ts +94 -0
  25. package/src/dto/openapi/generators/filter.ts +74 -0
  26. package/src/dto/openapi/generators/nested-dto.ts +532 -0
  27. package/src/dto/openapi/generators/pagination.ts +111 -0
  28. package/src/dto/openapi/generators/relation-filter.ts +210 -0
  29. package/src/dto/openapi/index.ts +17 -0
  30. package/src/dto/openapi/type-mappings.ts +191 -0
  31. package/src/dto/openapi/types.ts +90 -0
  32. package/src/dto/openapi/utilities.ts +45 -0
  33. package/src/dto/pagination-utils.ts +150 -0
  34. package/src/dto/transform.ts +197 -0
  35. package/src/index.ts +5 -3
  36. package/src/orm/entity-context.ts +9 -9
  37. package/src/orm/entity.ts +74 -74
  38. package/src/orm/orm-session.ts +159 -159
  39. package/src/orm/relation-change-processor.ts +3 -3
  40. package/src/orm/runtime-types.ts +5 -5
  41. package/src/orm/unit-of-work.ts +13 -25
  42. package/src/query-builder/query-ast-service.ts +287 -300
  43. package/src/query-builder/relation-filter-utils.ts +159 -160
  44. package/src/query-builder/select.ts +137 -192
  45. package/src/schema/column-types.ts +4 -4
  46. package/src/schema/types.ts +5 -1
  47. package/src/core/ast/ast-validation.ts +0 -19
  48. package/src/core/ast/param-proxy.ts +0 -47
  49. package/src/core/ast/query-visitor.ts +0 -273
  50. package/src/openapi/index.ts +0 -4
  51. package/src/openapi/query-parameters.ts +0 -207
  52. package/src/openapi/schema-extractor-input.ts +0 -193
  53. package/src/openapi/schema-extractor-output.ts +0 -427
  54. package/src/openapi/schema-extractor-utils.ts +0 -110
  55. package/src/openapi/schema-extractor.ts +0 -120
  56. package/src/openapi/schema-types.ts +0 -187
  57. package/src/openapi/type-mappers.ts +0 -227
@@ -1,187 +0,0 @@
1
- import type { TableDef } from '../schema/table.js';
2
-
3
- /**
4
- * OpenAPI 3.1 JSON Schema type representation
5
- */
6
- export type JsonSchemaType =
7
- | 'string'
8
- | 'number'
9
- | 'integer'
10
- | 'boolean'
11
- | 'object'
12
- | 'array'
13
- | 'null';
14
-
15
- /**
16
- * Common OpenAPI 3.1 JSON Schema formats
17
- */
18
- export type JsonSchemaFormat =
19
- | 'date-time'
20
- | 'date'
21
- | 'time'
22
- | 'email'
23
- | 'uuid'
24
- | 'uri'
25
- | 'binary'
26
- | 'base64';
27
-
28
- /**
29
- * OpenAPI 3.1 JSON Schema property definition
30
- */
31
- export interface JsonSchemaProperty {
32
- type?: JsonSchemaType | JsonSchemaType[];
33
- format?: JsonSchemaFormat;
34
- description?: string;
35
- nullable?: boolean;
36
- readOnly?: boolean;
37
- writeOnly?: boolean;
38
- minimum?: number;
39
- maximum?: number;
40
- minLength?: number;
41
- maxLength?: number;
42
- pattern?: string;
43
- enum?: (string | number | boolean)[];
44
- default?: unknown;
45
- example?: unknown;
46
- properties?: Record<string, JsonSchemaProperty>;
47
- required?: string[];
48
- items?: JsonSchemaProperty;
49
- $ref?: string;
50
- anyOf?: JsonSchemaProperty[];
51
- allOf?: JsonSchemaProperty[];
52
- oneOf?: JsonSchemaProperty[];
53
- [key: string]: unknown;
54
- }
55
-
56
- /**
57
- * OpenAPI 3.1 parameter definition
58
- */
59
- export interface OpenApiParameter {
60
- name: string;
61
- in: 'query' | 'path' | 'header' | 'cookie';
62
- description?: string;
63
- required?: boolean;
64
- deprecated?: boolean;
65
- allowEmptyValue?: boolean;
66
- style?: string;
67
- explode?: boolean;
68
- schema?: JsonSchemaProperty;
69
- [key: string]: unknown;
70
- }
71
-
72
- /**
73
- * Complete OpenAPI 3.1 Schema for an entity or query result
74
- */
75
- export interface OpenApiSchema {
76
- type: 'object';
77
- properties: Record<string, JsonSchemaProperty>;
78
- required: string[];
79
- description?: string;
80
- }
81
-
82
- /**
83
- * OpenAPI 3.1 components container
84
- */
85
- export interface OpenApiComponents {
86
- schemas: Record<string, OpenApiSchema>;
87
- }
88
-
89
- /**
90
- * Column-level schema flags
91
- */
92
- export interface ColumnSchemaOptions {
93
- /** Include description from column comments */
94
- includeDescriptions?: boolean;
95
- /** Include enum values for enum columns */
96
- includeEnums?: boolean;
97
- /** Include column examples if available */
98
- includeExamples?: boolean;
99
- /** Include column defaults */
100
- includeDefaults?: boolean;
101
- /** Include nullable flag when applicable */
102
- includeNullable?: boolean;
103
- }
104
-
105
- /**
106
- * Output schema generation options (query result)
107
- */
108
- export interface OutputSchemaOptions extends ColumnSchemaOptions {
109
- /** Use selected columns only (from select/include) vs full entity */
110
- mode?: 'selected' | 'full';
111
- /** Maximum depth for relation recursion */
112
- maxDepth?: number;
113
- /** Inline schemas vs $ref components */
114
- refMode?: 'inline' | 'components';
115
- /** Selected schemas inline vs components when refMode is components */
116
- selectedRefMode?: 'inline' | 'components';
117
- /** Customize component names */
118
- componentName?: (table: TableDef) => string;
119
- /** Emit output schema as a component $ref when refMode is components */
120
- outputAsRef?: boolean;
121
- }
122
-
123
- export type InputRelationMode = 'ids' | 'objects' | 'mixed';
124
- export type InputSchemaMode = 'create' | 'update';
125
-
126
- export interface RelationSelection {
127
- pick?: string[];
128
- omit?: string[];
129
- }
130
-
131
- /**
132
- * Input schema generation options (write payloads)
133
- */
134
- export interface InputSchemaOptions extends ColumnSchemaOptions {
135
- /** Create vs update payload shape */
136
- mode?: InputSchemaMode;
137
- /** Include relation payloads */
138
- includeRelations?: boolean;
139
- /** How relations are represented (ids, nested objects, or both) */
140
- relationMode?: InputRelationMode;
141
- /** Maximum depth for relation recursion */
142
- maxDepth?: number;
143
- /** Omit read-only/generated columns from input */
144
- omitReadOnly?: boolean;
145
- /** Exclude primary key columns from input */
146
- excludePrimaryKey?: boolean;
147
- /** Require primary key columns on update payloads */
148
- requirePrimaryKey?: boolean;
149
- /** Remove relation foreign keys pointing to the parent from nested inputs */
150
- excludeRelationForeignKeys?: boolean;
151
- /** Per-relation field selection for nested inputs */
152
- relationSelections?: Record<string, RelationSelection>;
153
- }
154
-
155
- /**
156
- * Schema generation options
157
- */
158
- export interface SchemaOptions extends OutputSchemaOptions {
159
- /** Input schema options, or false to skip input generation */
160
- input?: InputSchemaOptions | false;
161
- }
162
-
163
- /**
164
- * Input + output schema bundle
165
- */
166
- export interface OpenApiSchemaBundle {
167
- output: OpenApiSchema | JsonSchemaProperty;
168
- input?: OpenApiSchema;
169
- parameters?: OpenApiParameter[];
170
- components?: OpenApiComponents;
171
- }
172
-
173
- /**
174
- * Schema extraction context for handling circular references
175
- */
176
- export interface SchemaExtractionContext {
177
- /** Set of already visited tables to detect cycles */
178
- visitedTables: Set<string>;
179
- /** Map of table names to their generated schemas */
180
- schemaCache: Map<string, OpenApiSchema>;
181
- /** Current extraction depth */
182
- depth: number;
183
- /** Maximum depth to recurse */
184
- maxDepth: number;
185
- /** Component registry when using refMode=components */
186
- components?: OpenApiComponents;
187
- }
@@ -1,227 +0,0 @@
1
- import type { ColumnDef } from '../schema/column-types.js';
2
- import type { ColumnSchemaOptions, JsonSchemaProperty, JsonSchemaType, JsonSchemaFormat } from './schema-types.js';
3
-
4
- /**
5
- * Maps SQL column types to OpenAPI JSON Schema types
6
- */
7
- export const mapColumnType = (
8
- column: ColumnDef,
9
- options: ColumnSchemaOptions = {}
10
- ): JsonSchemaProperty => {
11
- const resolved = resolveColumnOptions(options);
12
- const sqlType = normalizeType(column.type);
13
- const baseSchema = mapSqlTypeToBaseSchema(sqlType, column);
14
-
15
- const schema: JsonSchemaProperty = {
16
- ...baseSchema,
17
- };
18
-
19
- if (resolved.includeDescriptions && column.comment) {
20
- schema.description = column.comment;
21
- }
22
-
23
- if (resolved.includeNullable) {
24
- schema.nullable = !column.notNull && !column.primary;
25
- }
26
-
27
- if ((sqlType === 'varchar' || sqlType === 'char') && column.args) {
28
- schema.maxLength = column.args[0] as number | undefined;
29
- }
30
-
31
- if ((sqlType === 'decimal' || sqlType === 'float') && column.args) {
32
- if (column.args.length >= 1) {
33
- schema.minimum = -(10 ** (column.args[0] as number));
34
- }
35
- }
36
-
37
- if (!resolved.includeEnums) {
38
- delete schema.enum;
39
- } else if (sqlType === 'enum' && column.args && column.args.length > 0) {
40
- schema.enum = column.args as (string | number | boolean)[];
41
- }
42
-
43
- if (resolved.includeDefaults && column.default !== undefined) {
44
- schema.default = column.default;
45
- }
46
-
47
- return schema;
48
- };
49
-
50
- const normalizeType = (type: string): string => {
51
- return type.toLowerCase();
52
- };
53
-
54
- const mapSqlTypeToBaseSchema = (
55
- sqlType: string,
56
- column: ColumnDef
57
- ): Omit<JsonSchemaProperty, 'nullable' | 'description'> => {
58
- const type = normalizeType(sqlType);
59
-
60
- const hasCustomTsType = column.tsType !== undefined;
61
-
62
- switch (type) {
63
- case 'int':
64
- case 'integer':
65
- case 'bigint':
66
- return {
67
- type: hasCustomTsType ? inferTypeFromTsType(column.tsType) : ('integer' as JsonSchemaType),
68
- format: type === 'bigint' ? 'int64' : 'int32',
69
- minimum: column.autoIncrement ? 1 : undefined,
70
- };
71
-
72
- case 'decimal':
73
- case 'float':
74
- case 'double':
75
- return {
76
- type: hasCustomTsType ? inferTypeFromTsType(column.tsType) : ('number' as JsonSchemaType),
77
- };
78
-
79
- case 'varchar':
80
- return {
81
- type: 'string' as JsonSchemaType,
82
- minLength: column.notNull ? 1 : undefined,
83
- maxLength: column.args?.[0] as number | undefined,
84
- };
85
-
86
- case 'text':
87
- return {
88
- type: 'string' as JsonSchemaType,
89
- minLength: column.notNull ? 1 : undefined,
90
- };
91
-
92
- case 'char':
93
- return {
94
- type: 'string' as JsonSchemaType,
95
- minLength: column.notNull ? column.args?.[0] as number || 1 : undefined,
96
- maxLength: column.args?.[0] as number,
97
- };
98
-
99
- case 'boolean':
100
- return {
101
- type: 'boolean' as JsonSchemaType,
102
- };
103
-
104
- case 'json':
105
- return {
106
- anyOf: [
107
- { type: 'object' as JsonSchemaType },
108
- { type: 'array' as JsonSchemaType },
109
- ],
110
- };
111
-
112
- case 'blob':
113
- case 'binary':
114
- case 'varbinary':
115
- return {
116
- type: 'string' as JsonSchemaType,
117
- format: 'base64' as JsonSchemaFormat,
118
- };
119
-
120
- case 'date':
121
- return {
122
- type: 'string' as JsonSchemaType,
123
- format: 'date' as JsonSchemaFormat,
124
- };
125
-
126
- case 'datetime':
127
- case 'timestamp':
128
- return {
129
- type: 'string' as JsonSchemaType,
130
- format: 'date-time' as JsonSchemaFormat,
131
- };
132
-
133
- case 'timestamptz':
134
- return {
135
- type: 'string' as JsonSchemaType,
136
- format: 'date-time' as JsonSchemaFormat,
137
- };
138
-
139
- case 'uuid':
140
- return {
141
- type: 'string' as JsonSchemaType,
142
- format: 'uuid' as JsonSchemaFormat,
143
- pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',
144
- };
145
-
146
- case 'enum':
147
- return {
148
- type: 'string' as JsonSchemaType,
149
- enum: (column.args as (string | number | boolean)[]) || [],
150
- };
151
-
152
- default:
153
- if (column.dialectTypes?.postgres && column.dialectTypes.postgres === 'bytea') {
154
- return {
155
- type: 'string' as JsonSchemaType,
156
- format: 'base64' as JsonSchemaFormat,
157
- };
158
- }
159
-
160
- return {
161
- type: 'string' as JsonSchemaType,
162
- };
163
- }
164
- };
165
-
166
- const inferTypeFromTsType = (tsType: unknown): JsonSchemaType => {
167
- if (typeof tsType === 'string') {
168
- if (tsType === 'number') return 'number' as JsonSchemaType;
169
- if (tsType === 'string') return 'string' as JsonSchemaType;
170
- if (tsType === 'boolean') return 'boolean' as JsonSchemaType;
171
- }
172
-
173
- if (typeof tsType === 'function') {
174
- const typeStr = tsType.name?.toLowerCase();
175
- if (typeStr === 'number') return 'number' as JsonSchemaType;
176
- if (typeStr === 'string') return 'string' as JsonSchemaType;
177
- if (typeStr === 'boolean') return 'boolean' as JsonSchemaType;
178
- if (typeStr === 'array') return 'array' as JsonSchemaType;
179
- if (typeStr === 'object') return 'object' as JsonSchemaType;
180
- }
181
-
182
- return 'string' as JsonSchemaType;
183
- };
184
-
185
- const resolveColumnOptions = (options: ColumnSchemaOptions): Required<ColumnSchemaOptions> => ({
186
- includeDescriptions: options.includeDescriptions ?? false,
187
- includeEnums: options.includeEnums ?? true,
188
- includeExamples: options.includeExamples ?? false,
189
- includeDefaults: options.includeDefaults ?? true,
190
- includeNullable: options.includeNullable ?? true
191
- });
192
-
193
- /**
194
- * Maps relation type to array or single object
195
- */
196
- export const mapRelationType = (
197
- relationType: string
198
- ): { type: 'object' | 'array'; isNullable: boolean } => {
199
- switch (relationType) {
200
- case 'HAS_MANY':
201
- case 'BELONGS_TO_MANY':
202
- return { type: 'array', isNullable: false };
203
- case 'HAS_ONE':
204
- case 'BELONGS_TO':
205
- return { type: 'object', isNullable: true };
206
- default:
207
- return { type: 'object', isNullable: true };
208
- }
209
- };
210
-
211
- /**
212
- * Gets the OpenAPI format for temporal columns
213
- */
214
- export const getTemporalFormat = (sqlType: string): JsonSchemaFormat | undefined => {
215
- const type = normalizeType(sqlType);
216
-
217
- switch (type) {
218
- case 'date':
219
- return 'date' as JsonSchemaFormat;
220
- case 'datetime':
221
- case 'timestamp':
222
- case 'timestamptz':
223
- return 'date-time' as JsonSchemaFormat;
224
- default:
225
- return undefined;
226
- }
227
- };