metal-orm 1.0.33 → 1.0.35

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.
@@ -1,6 +1,6 @@
1
- /**
2
- * Supported column data types for database schema definitions
3
- */
1
+ /**
2
+ * Supported column data types for database schema definitions
3
+ */
4
4
  export type ColumnType =
5
5
  | 'INT'
6
6
  | 'INTEGER'
@@ -42,110 +42,112 @@ export type ColumnType =
42
42
  | 'timestamp'
43
43
  | 'timestamptz'
44
44
  | 'boolean';
45
-
46
- export type ReferentialAction =
47
- | 'NO ACTION'
48
- | 'RESTRICT'
49
- | 'CASCADE'
50
- | 'SET NULL'
51
- | 'SET DEFAULT';
52
-
53
- export interface RawDefaultValue {
54
- raw: string;
55
- }
56
-
57
- export type DefaultValue = unknown | RawDefaultValue;
58
-
59
- export interface ForeignKeyReference {
60
- /** Target table name */
61
- table: string;
62
- /** Target column name */
63
- column: string;
64
- /** Optional constraint name */
65
- name?: string;
66
- /** ON DELETE action */
67
- onDelete?: ReferentialAction;
68
- /** ON UPDATE action */
69
- onUpdate?: ReferentialAction;
70
- /** Whether the constraint is deferrable (Postgres) */
71
- deferrable?: boolean;
72
- }
73
-
74
- /**
75
- * Definition of a database column
76
- */
77
- export interface ColumnDef<T extends ColumnType = ColumnType> {
78
- /** Column name (filled at runtime by defineTable) */
79
- name: string;
80
- /** Data type of the column */
81
- type: T;
82
- /** Whether this column is a primary key */
83
- primary?: boolean;
84
- /** Whether this column cannot be null */
85
- notNull?: boolean;
86
- /** Whether this column must be unique (or name of the unique constraint) */
87
- unique?: boolean | string;
88
- /** Default value for the column */
89
- default?: DefaultValue;
90
- /** Whether the column auto-increments / identity */
91
- autoIncrement?: boolean;
92
- /** Identity strategy where supported */
93
- generated?: 'always' | 'byDefault';
94
- /** Inline check constraint expression */
95
- check?: string;
96
- /** Foreign key reference */
97
- references?: ForeignKeyReference;
98
- /** Column comment/description */
99
- comment?: string;
100
- /** Additional arguments for the column type (e.g., VARCHAR length) */
101
- args?: any[];
102
- /** Table name this column belongs to (filled at runtime by defineTable) */
103
- table?: string;
104
- }
105
-
106
- /**
107
- * Factory for creating column definitions with common data types
108
- */
109
- export const col = {
110
- /**
111
- * Creates an integer column definition
112
- * @returns ColumnDef with INT type
113
- */
114
- int: (): ColumnDef<'INT'> => ({ name: '', type: 'INT' }),
115
-
116
- /**
117
- * Creates a big integer column definition
118
- */
119
- bigint: (): ColumnDef<'BIGINT'> => ({ name: '', type: 'BIGINT' }),
120
-
121
- /**
122
- * Creates a variable character column definition
123
- * @param length - Maximum length of the string
124
- * @returns ColumnDef with VARCHAR type
125
- */
126
- varchar: (length: number): ColumnDef<'VARCHAR'> => ({ name: '', type: 'VARCHAR', args: [length] }),
127
-
128
- /**
129
- * Creates a fixed precision decimal column definition
130
- */
131
- decimal: (precision: number, scale = 0): ColumnDef<'DECIMAL'> => ({
132
- name: '',
133
- type: 'DECIMAL',
134
- args: [precision, scale]
135
- }),
136
-
137
- /**
138
- * Creates a floating point column definition
139
- */
140
- float: (precision?: number): ColumnDef<'FLOAT'> => ({
141
- name: '',
142
- type: 'FLOAT',
143
- args: precision !== undefined ? [precision] : undefined
144
- }),
145
-
146
- /**
147
- * Creates a UUID column definition
148
- */
45
+
46
+ export type ReferentialAction =
47
+ | 'NO ACTION'
48
+ | 'RESTRICT'
49
+ | 'CASCADE'
50
+ | 'SET NULL'
51
+ | 'SET DEFAULT';
52
+
53
+ export interface RawDefaultValue {
54
+ raw: string;
55
+ }
56
+
57
+ export type DefaultValue = unknown | RawDefaultValue;
58
+
59
+ export interface ForeignKeyReference {
60
+ /** Target table name */
61
+ table: string;
62
+ /** Target column name */
63
+ column: string;
64
+ /** Optional constraint name */
65
+ name?: string;
66
+ /** ON DELETE action */
67
+ onDelete?: ReferentialAction;
68
+ /** ON UPDATE action */
69
+ onUpdate?: ReferentialAction;
70
+ /** Whether the constraint is deferrable (Postgres) */
71
+ deferrable?: boolean;
72
+ }
73
+
74
+ /**
75
+ * Definition of a database column
76
+ */
77
+ export interface ColumnDef<T extends ColumnType = ColumnType, TRuntime = unknown> {
78
+ /** Column name (filled at runtime by defineTable) */
79
+ name: string;
80
+ /** Data type of the column */
81
+ type: T;
82
+ /** Optional override for the inferred TypeScript type */
83
+ tsType?: TRuntime;
84
+ /** Whether this column is a primary key */
85
+ primary?: boolean;
86
+ /** Whether this column cannot be null */
87
+ notNull?: boolean;
88
+ /** Whether this column must be unique (or name of the unique constraint) */
89
+ unique?: boolean | string;
90
+ /** Default value for the column */
91
+ default?: DefaultValue;
92
+ /** Whether the column auto-increments / identity */
93
+ autoIncrement?: boolean;
94
+ /** Identity strategy where supported */
95
+ generated?: 'always' | 'byDefault';
96
+ /** Inline check constraint expression */
97
+ check?: string;
98
+ /** Foreign key reference */
99
+ references?: ForeignKeyReference;
100
+ /** Column comment/description */
101
+ comment?: string;
102
+ /** Additional arguments for the column type (e.g., VARCHAR length) */
103
+ args?: any[];
104
+ /** Table name this column belongs to (filled at runtime by defineTable) */
105
+ table?: string;
106
+ }
107
+
108
+ /**
109
+ * Factory for creating column definitions with common data types
110
+ */
111
+ export const col = {
112
+ /**
113
+ * Creates an integer column definition
114
+ * @returns ColumnDef with INT type
115
+ */
116
+ int: (): ColumnDef<'INT'> => ({ name: '', type: 'INT' }),
117
+
118
+ /**
119
+ * Creates a big integer column definition
120
+ */
121
+ bigint: (): ColumnDef<'BIGINT'> => ({ name: '', type: 'BIGINT' }),
122
+
123
+ /**
124
+ * Creates a variable character column definition
125
+ * @param length - Maximum length of the string
126
+ * @returns ColumnDef with VARCHAR type
127
+ */
128
+ varchar: (length: number): ColumnDef<'VARCHAR'> => ({ name: '', type: 'VARCHAR', args: [length] }),
129
+
130
+ /**
131
+ * Creates a fixed precision decimal column definition
132
+ */
133
+ decimal: (precision: number, scale = 0): ColumnDef<'DECIMAL'> => ({
134
+ name: '',
135
+ type: 'DECIMAL',
136
+ args: [precision, scale]
137
+ }),
138
+
139
+ /**
140
+ * Creates a floating point column definition
141
+ */
142
+ float: (precision?: number): ColumnDef<'FLOAT'> => ({
143
+ name: '',
144
+ type: 'FLOAT',
145
+ args: precision !== undefined ? [precision] : undefined
146
+ }),
147
+
148
+ /**
149
+ * Creates a UUID column definition
150
+ */
149
151
  uuid: (): ColumnDef<'UUID'> => ({ name: '', type: 'UUID' }),
150
152
 
151
153
  /**
@@ -179,110 +181,110 @@ export const col = {
179
181
  /**
180
182
  * Creates a timestamp column definition
181
183
  */
182
- timestamp: (): ColumnDef<'TIMESTAMP'> => ({ name: '', type: 'TIMESTAMP' }),
183
-
184
- /**
185
- * Creates a timestamptz column definition
186
- */
187
- timestamptz: (): ColumnDef<'TIMESTAMPTZ'> => ({ name: '', type: 'TIMESTAMPTZ' }),
188
-
189
- /**
190
- * Creates a date column definition
191
- */
192
- date: (): ColumnDef<'DATE'> => ({ name: '', type: 'DATE' }),
193
-
194
- /**
195
- * Creates a datetime column definition
196
- */
197
- datetime: (): ColumnDef<'DATETIME'> => ({ name: '', type: 'DATETIME' }),
198
-
199
- /**
200
- * Creates a JSON column definition
201
- * @returns ColumnDef with JSON type
202
- */
203
- json: (): ColumnDef<'JSON'> => ({ name: '', type: 'JSON' }),
204
-
205
- /**
206
- * Creates a boolean column definition
207
- * @returns ColumnDef with BOOLEAN type
208
- */
209
- boolean: (): ColumnDef<'BOOLEAN'> => ({ name: '', type: 'BOOLEAN' }),
210
-
211
- /**
212
- * Creates an enum column definition
213
- * @param values - Enum values
214
- */
215
- enum: (values: string[]): ColumnDef<'ENUM'> => ({ name: '', type: 'ENUM', args: values }),
216
-
217
- /**
218
- * Marks a column definition as a primary key
219
- * @param def - Column definition to modify
220
- * @returns Modified ColumnDef with primary: true
221
- */
222
- primaryKey: <T extends ColumnType>(def: ColumnDef<T>): ColumnDef<T> =>
223
- ({ ...def, primary: true }),
224
-
225
- /**
226
- * Marks a column as NOT NULL
227
- */
228
- notNull: <T extends ColumnType>(def: ColumnDef<T>): ColumnDef<T> =>
229
- ({ ...def, notNull: true }),
230
-
231
- /**
232
- * Marks a column as UNIQUE
233
- */
234
- unique: <T extends ColumnType>(def: ColumnDef<T>, name?: string): ColumnDef<T> =>
235
- ({
236
- ...def,
237
- unique: name ?? true
238
- }),
239
-
240
- /**
241
- * Sets a default value for the column
242
- */
243
- default: <T extends ColumnType>(def: ColumnDef<T>, value: unknown): ColumnDef<T> =>
244
- ({
245
- ...def,
246
- default: value
247
- }),
248
-
249
- /**
250
- * Sets a raw SQL default value for the column
251
- */
252
- defaultRaw: <T extends ColumnType>(def: ColumnDef<T>, expression: string): ColumnDef<T> =>
253
- ({
254
- ...def,
255
- default: { raw: expression }
256
- }),
257
-
258
- /**
259
- * Marks a column as auto-increment / identity
260
- */
261
- autoIncrement: <T extends ColumnType>(
262
- def: ColumnDef<T>,
263
- strategy: ColumnDef['generated'] = 'byDefault'
264
- ): ColumnDef<T> =>
265
- ({
266
- ...def,
267
- autoIncrement: true,
268
- generated: strategy
269
- }),
270
-
271
- /**
272
- * Adds a foreign key reference
273
- */
274
- references: <T extends ColumnType>(def: ColumnDef<T>, ref: ForeignKeyReference): ColumnDef<T> =>
275
- ({
276
- ...def,
277
- references: ref
278
- }),
279
-
280
- /**
281
- * Adds a check constraint to the column
282
- */
283
- check: <T extends ColumnType>(def: ColumnDef<T>, expression: string): ColumnDef<T> =>
284
- ({
285
- ...def,
286
- check: expression
287
- })
288
- };
184
+ timestamp: <TRuntime = string>(): ColumnDef<'TIMESTAMP', TRuntime> => ({ name: '', type: 'TIMESTAMP' }),
185
+
186
+ /**
187
+ * Creates a timestamptz column definition
188
+ */
189
+ timestamptz: <TRuntime = string>(): ColumnDef<'TIMESTAMPTZ', TRuntime> => ({ name: '', type: 'TIMESTAMPTZ' }),
190
+
191
+ /**
192
+ * Creates a date column definition
193
+ */
194
+ date: <TRuntime = string>(): ColumnDef<'DATE', TRuntime> => ({ name: '', type: 'DATE' }),
195
+
196
+ /**
197
+ * Creates a datetime column definition
198
+ */
199
+ datetime: <TRuntime = string>(): ColumnDef<'DATETIME', TRuntime> => ({ name: '', type: 'DATETIME' }),
200
+
201
+ /**
202
+ * Creates a JSON column definition
203
+ * @returns ColumnDef with JSON type
204
+ */
205
+ json: (): ColumnDef<'JSON'> => ({ name: '', type: 'JSON' }),
206
+
207
+ /**
208
+ * Creates a boolean column definition
209
+ * @returns ColumnDef with BOOLEAN type
210
+ */
211
+ boolean: (): ColumnDef<'BOOLEAN'> => ({ name: '', type: 'BOOLEAN' }),
212
+
213
+ /**
214
+ * Creates an enum column definition
215
+ * @param values - Enum values
216
+ */
217
+ enum: (values: string[]): ColumnDef<'ENUM'> => ({ name: '', type: 'ENUM', args: values }),
218
+
219
+ /**
220
+ * Marks a column definition as a primary key
221
+ * @param def - Column definition to modify
222
+ * @returns Modified ColumnDef with primary: true
223
+ */
224
+ primaryKey: <T extends ColumnType>(def: ColumnDef<T>): ColumnDef<T> =>
225
+ ({ ...def, primary: true }),
226
+
227
+ /**
228
+ * Marks a column as NOT NULL
229
+ */
230
+ notNull: <T extends ColumnType>(def: ColumnDef<T>): ColumnDef<T> =>
231
+ ({ ...def, notNull: true }),
232
+
233
+ /**
234
+ * Marks a column as UNIQUE
235
+ */
236
+ unique: <T extends ColumnType>(def: ColumnDef<T>, name?: string): ColumnDef<T> =>
237
+ ({
238
+ ...def,
239
+ unique: name ?? true
240
+ }),
241
+
242
+ /**
243
+ * Sets a default value for the column
244
+ */
245
+ default: <T extends ColumnType>(def: ColumnDef<T>, value: unknown): ColumnDef<T> =>
246
+ ({
247
+ ...def,
248
+ default: value
249
+ }),
250
+
251
+ /**
252
+ * Sets a raw SQL default value for the column
253
+ */
254
+ defaultRaw: <T extends ColumnType>(def: ColumnDef<T>, expression: string): ColumnDef<T> =>
255
+ ({
256
+ ...def,
257
+ default: { raw: expression }
258
+ }),
259
+
260
+ /**
261
+ * Marks a column as auto-increment / identity
262
+ */
263
+ autoIncrement: <T extends ColumnType>(
264
+ def: ColumnDef<T>,
265
+ strategy: ColumnDef['generated'] = 'byDefault'
266
+ ): ColumnDef<T> =>
267
+ ({
268
+ ...def,
269
+ autoIncrement: true,
270
+ generated: strategy
271
+ }),
272
+
273
+ /**
274
+ * Adds a foreign key reference
275
+ */
276
+ references: <T extends ColumnType>(def: ColumnDef<T>, ref: ForeignKeyReference): ColumnDef<T> =>
277
+ ({
278
+ ...def,
279
+ references: ref
280
+ }),
281
+
282
+ /**
283
+ * Adds a check constraint to the column
284
+ */
285
+ check: <T extends ColumnType>(def: ColumnDef<T>, expression: string): ColumnDef<T> =>
286
+ ({
287
+ ...def,
288
+ check: expression
289
+ })
290
+ };
@@ -22,45 +22,47 @@ export type RelationTargetTable<TRel extends RelationDef> =
22
22
  * Maps a ColumnDef to its TypeScript type representation
23
23
  */
24
24
  export type ColumnToTs<T extends ColumnDef> =
25
- T['type'] extends 'INT' | 'INTEGER' | 'int' | 'integer' ? number :
26
- T['type'] extends 'BIGINT' | 'bigint' ? number | bigint :
27
- T['type'] extends 'DECIMAL' | 'decimal' | 'FLOAT' | 'float' | 'DOUBLE' | 'double' ? number :
28
- T['type'] extends 'BOOLEAN' | 'boolean' ? boolean :
29
- T['type'] extends 'JSON' | 'json' ? unknown :
30
- T['type'] extends 'BLOB' | 'blob' | 'BINARY' | 'binary' | 'VARBINARY' | 'varbinary' | 'BYTEA' | 'bytea' ? Buffer :
31
- T['type'] extends 'DATE' | 'date' | 'DATETIME' | 'datetime' | 'TIMESTAMP' | 'timestamp' | 'TIMESTAMPTZ' | 'timestamptz' ? string :
32
- string;
33
-
34
- /**
35
- * Infers a row shape from a table definition
36
- */
37
- export type InferRow<TTable extends TableDef> = {
38
- [K in keyof TTable['columns']]: ColumnToTs<TTable['columns'][K]>;
39
- };
40
-
25
+ T['tsType'] extends undefined
26
+ ? T['type'] extends 'INT' | 'INTEGER' | 'int' | 'integer' ? number :
27
+ T['type'] extends 'BIGINT' | 'bigint' ? number | bigint :
28
+ T['type'] extends 'DECIMAL' | 'decimal' | 'FLOAT' | 'float' | 'DOUBLE' | 'double' ? number :
29
+ T['type'] extends 'BOOLEAN' | 'boolean' ? boolean :
30
+ T['type'] extends 'JSON' | 'json' ? unknown :
31
+ T['type'] extends 'BLOB' | 'blob' | 'BINARY' | 'binary' | 'VARBINARY' | 'varbinary' | 'BYTEA' | 'bytea' ? Buffer :
32
+ T['type'] extends 'DATE' | 'date' | 'DATETIME' | 'datetime' | 'TIMESTAMP' | 'timestamp' | 'TIMESTAMPTZ' | 'timestamptz' ? string :
33
+ string
34
+ : Exclude<T['tsType'], undefined>;
35
+
36
+ /**
37
+ * Infers a row shape from a table definition
38
+ */
39
+ export type InferRow<TTable extends TableDef> = {
40
+ [K in keyof TTable['columns']]: ColumnToTs<TTable['columns'][K]>;
41
+ };
42
+
41
43
  type RelationResult<T extends RelationDef> =
42
44
  T extends HasManyRelation<infer TTarget> ? InferRow<TTarget>[] :
43
45
  T extends HasOneRelation<infer TTarget> ? InferRow<TTarget> | null :
44
46
  T extends BelongsToRelation<infer TTarget> ? InferRow<TTarget> | null :
45
47
  T extends BelongsToManyRelation<infer TTarget> ? (InferRow<TTarget> & { _pivot?: any })[] :
46
48
  never;
47
-
48
- /**
49
- * Maps relation names to the expected row results
50
- */
51
- export type RelationMap<TTable extends TableDef> = {
52
- [K in keyof TTable['relations']]: RelationResult<TTable['relations'][K]>;
53
- };
54
-
55
- export interface HasManyCollection<TChild> {
56
- load(): Promise<TChild[]>;
57
- getItems(): TChild[];
58
- add(data: Partial<TChild>): TChild;
59
- attach(entity: TChild): void;
60
- remove(entity: TChild): void;
61
- clear(): void;
62
- }
63
-
49
+
50
+ /**
51
+ * Maps relation names to the expected row results
52
+ */
53
+ export type RelationMap<TTable extends TableDef> = {
54
+ [K in keyof TTable['relations']]: RelationResult<TTable['relations'][K]>;
55
+ };
56
+
57
+ export interface HasManyCollection<TChild> {
58
+ load(): Promise<TChild[]>;
59
+ getItems(): TChild[];
60
+ add(data: Partial<TChild>): TChild;
61
+ attach(entity: TChild): void;
62
+ remove(entity: TChild): void;
63
+ clear(): void;
64
+ }
65
+
64
66
  export interface BelongsToReference<TParent> {
65
67
  load(): Promise<TParent | null>;
66
68
  get(): TParent | null;
@@ -72,28 +74,28 @@ export interface HasOneReference<TChild> {
72
74
  get(): TChild | null;
73
75
  set(data: Partial<TChild> | TChild | null): TChild | null;
74
76
  }
75
-
76
- export interface ManyToManyCollection<TTarget> {
77
- load(): Promise<TTarget[]>;
78
- getItems(): TTarget[];
79
- attach(target: TTarget | number | string): void;
80
- detach(target: TTarget | number | string): void;
81
- syncByIds(ids: (number | string)[]): Promise<void>;
82
- }
83
-
84
- export type Entity<
77
+
78
+ export interface ManyToManyCollection<TTarget> {
79
+ load(): Promise<TTarget[]>;
80
+ getItems(): TTarget[];
81
+ attach(target: TTarget | number | string): void;
82
+ detach(target: TTarget | number | string): void;
83
+ syncByIds(ids: (number | string)[]): Promise<void>;
84
+ }
85
+
86
+ export type EntityInstance<
85
87
  TTable extends TableDef,
86
88
  TRow = InferRow<TTable>
87
89
  > = TRow & {
88
90
  [K in keyof RelationMap<TTable>]:
89
91
  TTable['relations'][K] extends HasManyRelation<infer TTarget>
90
- ? HasManyCollection<Entity<TTarget>>
92
+ ? HasManyCollection<EntityInstance<TTarget>>
91
93
  : TTable['relations'][K] extends HasOneRelation<infer TTarget>
92
- ? HasOneReference<Entity<TTarget>>
94
+ ? HasOneReference<EntityInstance<TTarget>>
93
95
  : TTable['relations'][K] extends BelongsToManyRelation<infer TTarget>
94
- ? ManyToManyCollection<Entity<TTarget>>
96
+ ? ManyToManyCollection<EntityInstance<TTarget>>
95
97
  : TTable['relations'][K] extends BelongsToRelation<infer TTarget>
96
- ? BelongsToReference<Entity<TTarget>>
98
+ ? BelongsToReference<EntityInstance<TTarget>>
97
99
  : never;
98
100
  } & {
99
101
  $load<K extends keyof RelationMap<TTable>>(relation: K): Promise<RelationMap<TTable>[K]>;