metal-orm 1.0.90 → 1.0.92

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 (37) hide show
  1. package/dist/index.cjs +214 -118
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +71 -32
  4. package/dist/index.d.ts +71 -32
  5. package/dist/index.js +206 -118
  6. package/dist/index.js.map +1 -1
  7. package/package.json +4 -2
  8. package/scripts/generate-entities/render.mjs +16 -3
  9. package/src/core/ddl/introspect/utils.ts +45 -45
  10. package/src/decorators/bootstrap.ts +37 -37
  11. package/src/decorators/column-decorator.ts +3 -1
  12. package/src/dto/apply-filter.ts +279 -281
  13. package/src/dto/dto-types.ts +229 -229
  14. package/src/dto/filter-types.ts +193 -193
  15. package/src/dto/index.ts +97 -97
  16. package/src/dto/openapi/generators/base.ts +29 -29
  17. package/src/dto/openapi/generators/column.ts +37 -34
  18. package/src/dto/openapi/generators/dto.ts +94 -94
  19. package/src/dto/openapi/generators/filter.ts +75 -74
  20. package/src/dto/openapi/generators/nested-dto.ts +618 -532
  21. package/src/dto/openapi/generators/pagination.ts +111 -111
  22. package/src/dto/openapi/generators/relation-filter.ts +228 -210
  23. package/src/dto/openapi/index.ts +17 -17
  24. package/src/dto/openapi/type-mappings.ts +191 -191
  25. package/src/dto/openapi/types.ts +101 -83
  26. package/src/dto/openapi/utilities.ts +90 -45
  27. package/src/dto/pagination-utils.ts +150 -150
  28. package/src/dto/transform.ts +197 -193
  29. package/src/index.ts +69 -69
  30. package/src/orm/entity-context.ts +9 -9
  31. package/src/orm/entity-metadata.ts +14 -14
  32. package/src/orm/entity.ts +74 -74
  33. package/src/orm/orm-session.ts +159 -159
  34. package/src/orm/relation-change-processor.ts +3 -3
  35. package/src/orm/runtime-types.ts +5 -5
  36. package/src/schema/column-types.ts +4 -4
  37. package/src/schema/types.ts +5 -1
@@ -1,17 +1,17 @@
1
- export * from './types.js';
2
- export * from './type-mappings.js';
3
- export * from './utilities.js';
4
- export * from './generators/base.js';
5
- export * from './generators/column.js';
6
- export * from './generators/dto.js';
7
- export * from './generators/filter.js';
8
- export * from './generators/relation-filter.js';
9
- export * from './generators/nested-dto.js';
10
- export type {
11
- PaginationParams,
12
- } from './generators/pagination.js';
13
- export {
14
- paginationParamsSchema,
15
- toPaginationParams,
16
- pagedResponseToOpenApiSchema
17
- } from './generators/pagination.js';
1
+ export * from './types.js';
2
+ export * from './type-mappings.js';
3
+ export * from './utilities.js';
4
+ export * from './generators/base.js';
5
+ export * from './generators/column.js';
6
+ export * from './generators/dto.js';
7
+ export * from './generators/filter.js';
8
+ export * from './generators/relation-filter.js';
9
+ export * from './generators/nested-dto.js';
10
+ export type {
11
+ PaginationParams,
12
+ } from './generators/pagination.js';
13
+ export {
14
+ paginationParamsSchema,
15
+ toPaginationParams,
16
+ pagedResponseToOpenApiSchema
17
+ } from './generators/pagination.js';
@@ -1,191 +1,191 @@
1
- import type { ColumnDef } from '../../schema/column-types.js';
2
- import type { OpenApiType } from './types.js';
3
-
4
- export interface TypeMappingStrategy {
5
- supports(columnType: string): boolean;
6
- getOpenApiType(): OpenApiType;
7
- getFormat(columnType: string): string | undefined;
8
- }
9
-
10
- export class IntegerTypeStrategy implements TypeMappingStrategy {
11
- private readonly types = ['INT', 'INTEGER'];
12
-
13
- supports(type: string): boolean {
14
- return this.types.includes(type.toUpperCase());
15
- }
16
-
17
- getOpenApiType(): OpenApiType {
18
- return 'integer';
19
- }
20
-
21
- getFormat(): string | undefined {
22
- return 'int32';
23
- }
24
- }
25
-
26
- export class BigIntTypeStrategy implements TypeMappingStrategy {
27
- private readonly types = ['BIGINT'];
28
-
29
- supports(type: string): boolean {
30
- return this.types.includes(type.toUpperCase());
31
- }
32
-
33
- getOpenApiType(): OpenApiType {
34
- return 'integer';
35
- }
36
-
37
- getFormat(): string | undefined {
38
- return 'int64';
39
- }
40
- }
41
-
42
- export class DecimalTypeStrategy implements TypeMappingStrategy {
43
- private readonly types = ['DECIMAL', 'FLOAT', 'DOUBLE'];
44
-
45
- supports(type: string): boolean {
46
- return this.types.includes(type.toUpperCase());
47
- }
48
-
49
- getOpenApiType(): OpenApiType {
50
- return 'number';
51
- }
52
-
53
- getFormat(): string | undefined {
54
- return 'double';
55
- }
56
- }
57
-
58
- export class BooleanTypeStrategy implements TypeMappingStrategy {
59
- private readonly types = ['BOOLEAN'];
60
-
61
- supports(type: string): boolean {
62
- return this.types.includes(type.toUpperCase());
63
- }
64
-
65
- getOpenApiType(): OpenApiType {
66
- return 'boolean';
67
- }
68
-
69
- getFormat(): undefined {
70
- return undefined;
71
- }
72
- }
73
-
74
- export class UuidTypeStrategy implements TypeMappingStrategy {
75
- private readonly types = ['UUID'];
76
-
77
- supports(type: string): boolean {
78
- return this.types.includes(type.toUpperCase());
79
- }
80
-
81
- getOpenApiType(): OpenApiType {
82
- return 'string';
83
- }
84
-
85
- getFormat(): string {
86
- return 'uuid';
87
- }
88
- }
89
-
90
- export class DateTimeTypeStrategy implements TypeMappingStrategy {
91
- private readonly types = ['DATE', 'DATETIME', 'TIMESTAMP', 'TIMESTAMPTZ'];
92
-
93
- supports(type: string): boolean {
94
- return this.types.includes(type.toUpperCase());
95
- }
96
-
97
- getOpenApiType(): OpenApiType {
98
- return 'string';
99
- }
100
-
101
- getFormat(columnType: string = 'DATETIME'): string {
102
- return columnType.toUpperCase() === 'DATE' ? 'date' : 'date-time';
103
- }
104
- }
105
-
106
- export class StringTypeStrategy implements TypeMappingStrategy {
107
- private readonly types = [
108
- 'JSON', 'TEXT', 'VARCHAR', 'CHAR', 'BINARY',
109
- 'VARBINARY', 'BLOB', 'ENUM'
110
- ];
111
-
112
- supports(type: string): boolean {
113
- return this.types.includes(type.toUpperCase());
114
- }
115
-
116
- getOpenApiType(): OpenApiType {
117
- return 'string';
118
- }
119
-
120
- getFormat(): undefined {
121
- return undefined;
122
- }
123
- }
124
-
125
- export class DefaultTypeStrategy implements TypeMappingStrategy {
126
- supports(): boolean {
127
- return true;
128
- }
129
-
130
- getOpenApiType(): OpenApiType {
131
- return 'string';
132
- }
133
-
134
- getFormat(): undefined {
135
- return undefined;
136
- }
137
- }
138
-
139
- export class TypeMappingService {
140
- private readonly strategies: TypeMappingStrategy[];
141
-
142
- constructor() {
143
- this.strategies = [
144
- new IntegerTypeStrategy(),
145
- new BigIntTypeStrategy(),
146
- new DecimalTypeStrategy(),
147
- new BooleanTypeStrategy(),
148
- new DateTimeTypeStrategy(),
149
- new UuidTypeStrategy(),
150
- new StringTypeStrategy(),
151
- new DefaultTypeStrategy(),
152
- ];
153
- }
154
-
155
- getOpenApiType(column: ColumnDef): OpenApiType {
156
- const strategy = this.findStrategy(column.type);
157
- return strategy.getOpenApiType();
158
- }
159
-
160
- getFormat(column: ColumnDef): string | undefined {
161
- const strategy = this.findStrategy(column.type);
162
- return strategy.getFormat(column.type);
163
- }
164
-
165
- private findStrategy(columnType: string): TypeMappingStrategy {
166
- for (const strategy of this.strategies) {
167
- if (strategy.supports(columnType)) {
168
- return strategy;
169
- }
170
- }
171
- return this.strategies[this.strategies.length - 1];
172
- }
173
-
174
- registerStrategy(strategy: TypeMappingStrategy, index?: number): void {
175
- if (index !== undefined) {
176
- this.strategies.splice(index, 0, strategy);
177
- } else {
178
- this.strategies.push(strategy);
179
- }
180
- }
181
- }
182
-
183
- export const typeMappingService = new TypeMappingService();
184
-
185
- export function columnTypeToOpenApiType(col: ColumnDef): OpenApiType {
186
- return typeMappingService.getOpenApiType(col);
187
- }
188
-
189
- export function columnTypeToOpenApiFormat(col: ColumnDef): string | undefined {
190
- return typeMappingService.getFormat(col);
191
- }
1
+ import type { ColumnDef } from '../../schema/column-types.js';
2
+ import type { OpenApiType } from './types.js';
3
+
4
+ export interface TypeMappingStrategy {
5
+ supports(columnType: string): boolean;
6
+ getOpenApiType(): OpenApiType;
7
+ getFormat(columnType: string): string | undefined;
8
+ }
9
+
10
+ export class IntegerTypeStrategy implements TypeMappingStrategy {
11
+ private readonly types = ['INT', 'INTEGER'];
12
+
13
+ supports(type: string): boolean {
14
+ return this.types.includes(type.toUpperCase());
15
+ }
16
+
17
+ getOpenApiType(): OpenApiType {
18
+ return 'integer';
19
+ }
20
+
21
+ getFormat(): string | undefined {
22
+ return 'int32';
23
+ }
24
+ }
25
+
26
+ export class BigIntTypeStrategy implements TypeMappingStrategy {
27
+ private readonly types = ['BIGINT'];
28
+
29
+ supports(type: string): boolean {
30
+ return this.types.includes(type.toUpperCase());
31
+ }
32
+
33
+ getOpenApiType(): OpenApiType {
34
+ return 'integer';
35
+ }
36
+
37
+ getFormat(): string | undefined {
38
+ return 'int64';
39
+ }
40
+ }
41
+
42
+ export class DecimalTypeStrategy implements TypeMappingStrategy {
43
+ private readonly types = ['DECIMAL', 'FLOAT', 'DOUBLE'];
44
+
45
+ supports(type: string): boolean {
46
+ return this.types.includes(type.toUpperCase());
47
+ }
48
+
49
+ getOpenApiType(): OpenApiType {
50
+ return 'number';
51
+ }
52
+
53
+ getFormat(): string | undefined {
54
+ return 'double';
55
+ }
56
+ }
57
+
58
+ export class BooleanTypeStrategy implements TypeMappingStrategy {
59
+ private readonly types = ['BOOLEAN'];
60
+
61
+ supports(type: string): boolean {
62
+ return this.types.includes(type.toUpperCase());
63
+ }
64
+
65
+ getOpenApiType(): OpenApiType {
66
+ return 'boolean';
67
+ }
68
+
69
+ getFormat(): undefined {
70
+ return undefined;
71
+ }
72
+ }
73
+
74
+ export class UuidTypeStrategy implements TypeMappingStrategy {
75
+ private readonly types = ['UUID'];
76
+
77
+ supports(type: string): boolean {
78
+ return this.types.includes(type.toUpperCase());
79
+ }
80
+
81
+ getOpenApiType(): OpenApiType {
82
+ return 'string';
83
+ }
84
+
85
+ getFormat(): string {
86
+ return 'uuid';
87
+ }
88
+ }
89
+
90
+ export class DateTimeTypeStrategy implements TypeMappingStrategy {
91
+ private readonly types = ['DATE', 'DATETIME', 'TIMESTAMP', 'TIMESTAMPTZ'];
92
+
93
+ supports(type: string): boolean {
94
+ return this.types.includes(type.toUpperCase());
95
+ }
96
+
97
+ getOpenApiType(): OpenApiType {
98
+ return 'string';
99
+ }
100
+
101
+ getFormat(columnType: string = 'DATETIME'): string {
102
+ return columnType.toUpperCase() === 'DATE' ? 'date' : 'date-time';
103
+ }
104
+ }
105
+
106
+ export class StringTypeStrategy implements TypeMappingStrategy {
107
+ private readonly types = [
108
+ 'JSON', 'TEXT', 'VARCHAR', 'CHAR', 'BINARY',
109
+ 'VARBINARY', 'BLOB', 'ENUM'
110
+ ];
111
+
112
+ supports(type: string): boolean {
113
+ return this.types.includes(type.toUpperCase());
114
+ }
115
+
116
+ getOpenApiType(): OpenApiType {
117
+ return 'string';
118
+ }
119
+
120
+ getFormat(): undefined {
121
+ return undefined;
122
+ }
123
+ }
124
+
125
+ export class DefaultTypeStrategy implements TypeMappingStrategy {
126
+ supports(): boolean {
127
+ return true;
128
+ }
129
+
130
+ getOpenApiType(): OpenApiType {
131
+ return 'string';
132
+ }
133
+
134
+ getFormat(): undefined {
135
+ return undefined;
136
+ }
137
+ }
138
+
139
+ export class TypeMappingService {
140
+ private readonly strategies: TypeMappingStrategy[];
141
+
142
+ constructor() {
143
+ this.strategies = [
144
+ new IntegerTypeStrategy(),
145
+ new BigIntTypeStrategy(),
146
+ new DecimalTypeStrategy(),
147
+ new BooleanTypeStrategy(),
148
+ new DateTimeTypeStrategy(),
149
+ new UuidTypeStrategy(),
150
+ new StringTypeStrategy(),
151
+ new DefaultTypeStrategy(),
152
+ ];
153
+ }
154
+
155
+ getOpenApiType(column: ColumnDef): OpenApiType {
156
+ const strategy = this.findStrategy(column.type);
157
+ return strategy.getOpenApiType();
158
+ }
159
+
160
+ getFormat(column: ColumnDef): string | undefined {
161
+ const strategy = this.findStrategy(column.type);
162
+ return strategy.getFormat(column.type);
163
+ }
164
+
165
+ private findStrategy(columnType: string): TypeMappingStrategy {
166
+ for (const strategy of this.strategies) {
167
+ if (strategy.supports(columnType)) {
168
+ return strategy;
169
+ }
170
+ }
171
+ return this.strategies[this.strategies.length - 1];
172
+ }
173
+
174
+ registerStrategy(strategy: TypeMappingStrategy, index?: number): void {
175
+ if (index !== undefined) {
176
+ this.strategies.splice(index, 0, strategy);
177
+ } else {
178
+ this.strategies.push(strategy);
179
+ }
180
+ }
181
+ }
182
+
183
+ export const typeMappingService = new TypeMappingService();
184
+
185
+ export function columnTypeToOpenApiType(col: ColumnDef): OpenApiType {
186
+ return typeMappingService.getOpenApiType(col);
187
+ }
188
+
189
+ export function columnTypeToOpenApiFormat(col: ColumnDef): string | undefined {
190
+ return typeMappingService.getFormat(col);
191
+ }
@@ -1,83 +1,101 @@
1
- export type OpenApiType =
2
- | 'string'
3
- | 'number'
4
- | 'integer'
5
- | 'boolean'
6
- | 'array'
7
- | 'object'
8
- | 'null';
9
-
10
- export interface OpenApiSchema {
11
- type?: OpenApiType | OpenApiType[];
12
- properties?: Record<string, OpenApiSchema>;
13
- items?: OpenApiSchema;
14
- required?: string[];
15
- enum?: unknown[];
16
- format?: string;
17
- description?: string;
18
- example?: unknown;
19
- nullable?: boolean;
20
- minimum?: number;
21
- maximum?: number;
22
- default?: unknown;
23
- $ref?: string;
24
- allOf?: OpenApiSchema[];
25
- oneOf?: OpenApiSchema[];
26
- }
27
-
28
- export interface OpenApiParameter {
29
- name: string;
30
- in: 'query' | 'path' | 'header' | 'cookie';
31
- required?: boolean;
32
- schema?: OpenApiSchema;
33
- description?: string;
34
- }
35
-
36
- export interface OpenApiOperation {
37
- summary?: string;
38
- description?: string;
39
- parameters?: OpenApiParameter[];
40
- requestBody?: {
41
- description?: string;
42
- required?: boolean;
43
- content: {
44
- 'application/json': {
45
- schema: OpenApiSchema;
46
- };
47
- };
48
- };
49
- responses?: Record<string, {
50
- description: string;
51
- content?: {
52
- 'application/json': {
53
- schema: OpenApiSchema;
54
- };
55
- };
56
- }>;
57
- }
58
-
59
- export interface OpenApiDocumentInfo {
60
- title: string;
61
- version: string;
62
- description?: string;
63
- }
64
-
65
- export interface ApiRouteDefinition {
66
- path: string;
67
- method: 'get' | 'post' | 'put' | 'patch' | 'delete';
68
- operation: OpenApiOperation;
69
- }
70
-
71
- export interface PaginationParams {
72
- page?: number;
73
- pageSize?: number;
74
- sortBy?: string;
75
- sortOrder?: 'asc' | 'desc';
76
- }
77
-
78
- export interface OpenApiComponent {
79
- schemas?: Record<string, OpenApiSchema>;
80
- parameters?: Record<string, OpenApiSchema>;
81
- responses?: Record<string, OpenApiSchema>;
82
- securitySchemes?: Record<string, unknown>;
83
- }
1
+ export type OpenApiType =
2
+ | 'string'
3
+ | 'number'
4
+ | 'integer'
5
+ | 'boolean'
6
+ | 'array'
7
+ | 'object'
8
+ | 'null';
9
+
10
+ export interface OpenApiSchema {
11
+ type?: OpenApiType | OpenApiType[];
12
+ properties?: Record<string, OpenApiSchema>;
13
+ items?: OpenApiSchema;
14
+ required?: string[];
15
+ enum?: unknown[];
16
+ format?: string;
17
+ description?: string;
18
+ example?: unknown;
19
+ nullable?: boolean;
20
+ minimum?: number;
21
+ maximum?: number;
22
+ default?: unknown;
23
+ $ref?: string;
24
+ allOf?: OpenApiSchema[];
25
+ oneOf?: OpenApiSchema[];
26
+ }
27
+
28
+ export interface OpenApiParameterObject {
29
+ name: string;
30
+ in: 'query' | 'path' | 'header' | 'cookie';
31
+ required?: boolean;
32
+ schema?: OpenApiSchema;
33
+ description?: string;
34
+ }
35
+
36
+ export interface OpenApiResponseObject {
37
+ description: string;
38
+ content?: {
39
+ 'application/json': {
40
+ schema: OpenApiSchema;
41
+ };
42
+ };
43
+ }
44
+
45
+ export interface OpenApiOperation {
46
+ summary?: string;
47
+ description?: string;
48
+ parameters?: OpenApiParameterObject[];
49
+ requestBody?: {
50
+ description?: string;
51
+ required?: boolean;
52
+ content: {
53
+ 'application/json': {
54
+ schema: OpenApiSchema;
55
+ };
56
+ };
57
+ };
58
+ responses?: Record<string, OpenApiResponseObject>;
59
+ }
60
+
61
+ export interface OpenApiDocumentInfo {
62
+ title: string;
63
+ version: string;
64
+ description?: string;
65
+ }
66
+
67
+ export interface ApiRouteDefinition {
68
+ path: string;
69
+ method: 'get' | 'post' | 'put' | 'patch' | 'delete';
70
+ operation: OpenApiOperation;
71
+ }
72
+
73
+ export interface PaginationParams {
74
+ page?: number;
75
+ pageSize?: number;
76
+ sortBy?: string;
77
+ sortOrder?: 'asc' | 'desc';
78
+ }
79
+
80
+ export interface OpenApiComponent {
81
+ schemas?: Record<string, OpenApiSchema>;
82
+ parameters?: Record<string, OpenApiParameterObject>;
83
+ responses?: Record<string, OpenApiResponseObject>;
84
+ securitySchemes?: Record<string, unknown>;
85
+ }
86
+
87
+ export interface OpenApiDocument {
88
+ openapi: string;
89
+ info: OpenApiDocumentInfo;
90
+ paths: Record<string, Record<string, OpenApiOperation>>;
91
+ components?: OpenApiComponent;
92
+ }
93
+
94
+ export type OpenApiDialect = 'openapi-3.0' | 'openapi-3.1';
95
+
96
+ export interface OpenApiDocumentOptions {
97
+ dialect?: OpenApiDialect;
98
+ allowScalarEquals?: boolean;
99
+ }
100
+
101
+ export type OpenApiParameter = OpenApiParameterObject;