uql-orm 0.43.0 → 0.45.0

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 (56) hide show
  1. package/README.md +3 -2
  2. package/dist/browser/querier/httpQuerier.d.ts +6 -0
  3. package/dist/browser/querier/httpQuerier.js +1 -1
  4. package/dist/browser/uql-browser.min.js +2 -2
  5. package/dist/browser/uql-browser.min.js.map +4 -4
  6. package/dist/dialect/abstractDialect.js +5 -6
  7. package/dist/dialect/abstractSqlDialect.d.ts +2 -2
  8. package/dist/dialect/abstractSqlDialect.js +1 -1
  9. package/dist/dialect/mysqlLikeSqlDialect.d.ts +8 -1
  10. package/dist/dialect/mysqlLikeSqlDialect.js +8 -1
  11. package/dist/dialect/pgLikeSqlDialect.d.ts +1 -1
  12. package/dist/dialect/pgLikeSqlDialect.js +1 -1
  13. package/dist/entity/decorator/bag.d.ts +3 -0
  14. package/dist/entity/index.d.ts +1 -1
  15. package/dist/entity/index.js +1 -1
  16. package/dist/entity/metadata/definition.d.ts +15 -13
  17. package/dist/entity/metadata/definition.js +47 -16
  18. package/dist/http/handler.d.ts +8 -0
  19. package/dist/http/handler.js +5 -5
  20. package/dist/migrate/builder/migrationBuilder.js +1 -2
  21. package/dist/migrate/builder/tableBuilder.d.ts +1 -0
  22. package/dist/migrate/builder/tableBuilder.js +9 -10
  23. package/dist/migrate/builder/types.d.ts +3 -19
  24. package/dist/migrate/cli.d.ts +5 -0
  25. package/dist/migrate/cli.js +33 -16
  26. package/dist/migrate/codegen/entityTypes.d.ts +7 -0
  27. package/dist/migrate/codegen/entityTypes.js +69 -0
  28. package/dist/migrate/codegen/index.d.ts +1 -0
  29. package/dist/migrate/codegen/index.js +1 -0
  30. package/dist/migrate/generator/definitionToNode.js +2 -2
  31. package/dist/migrate/index.d.ts +1 -1
  32. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +2 -5
  33. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +2 -0
  34. package/dist/migrate/introspection/baseSqlIntrospector.js +4 -3
  35. package/dist/migrate/introspection/mysqlIntrospector.js +1 -2
  36. package/dist/migrate/introspection/postgresIntrospector.js +1 -2
  37. package/dist/migrate/introspection/sqliteIntrospector.js +1 -2
  38. package/dist/migrate/migrator.d.ts +34 -20
  39. package/dist/migrate/migrator.js +90 -35
  40. package/dist/migrate/schemaGenerator.d.ts +20 -5
  41. package/dist/migrate/schemaGenerator.js +105 -30
  42. package/dist/schema/schemaASTBuilder.d.ts +23 -2
  43. package/dist/schema/schemaASTBuilder.js +3 -2
  44. package/dist/schema/schemaASTDiffer.d.ts +11 -1
  45. package/dist/schema/schemaASTDiffer.js +23 -7
  46. package/dist/schema/types.d.ts +19 -4
  47. package/dist/sqlite/sqliteDialect.d.ts +1 -1
  48. package/dist/sqlite/sqliteDialect.js +1 -1
  49. package/dist/type/entity.d.ts +14 -1
  50. package/dist/type/migration.d.ts +55 -9
  51. package/dist/type/queryWhere.d.ts +13 -3
  52. package/dist/util/field.util.d.ts +7 -2
  53. package/dist/util/field.util.js +9 -12
  54. package/dist/util/object.util.d.ts +3 -3
  55. package/dist/util/object.util.js +3 -3
  56. package/package.json +3 -3
@@ -65,7 +65,9 @@ export function diffSchemas(source, target, options = {}) {
65
65
  const indexDiffs = tablesToAlter.flatMap((tableDiff) => tableDiff.indexDiffs ?? []);
66
66
  const primaryKeyDiffs = tablesToAlter.flatMap((tableDiff) => tableDiff.primaryKeyDiff ?? []);
67
67
  // Relationships span tables, so they are compared over the whole schema rather than per table.
68
- const relationshipDiffs = opts.compareRelationships ? diffRelationships(source, target, opts) : [];
68
+ const relationshipDiffs = opts.compareRelationships
69
+ ? diffRelationshipNodes(source.relationships, target.relationships, opts)
70
+ : [];
69
71
  const hasDifferences = tablesToCreate.length > 0 ||
70
72
  tablesToDrop.length > 0 ||
71
73
  tablesToAlter.length > 0 ||
@@ -167,7 +169,7 @@ function diffColumn(tableName, source, target, opts) {
167
169
  const differences = [];
168
170
  // Two things a key column implies rather than states, and catalogues report inconsistently: its
169
171
  // type, which is the dialect's serial spelling rather than one the entity chose and does not round
170
- // trip (`BIGINT UNSIGNED AUTO_INCREMENT` reads back as `BIGINT(20) UNSIGNED`), and its nullability,
172
+ // trip (`BIGINT AUTO_INCREMENT` reads back as `BIGINT(20)`), and its nullability,
171
173
  // which is NOT NULL in every engine whatever is reported - SQLite's `PRAGMA table_info` says
172
174
  // `notnull: 0` for the `INTEGER PRIMARY KEY` that is the table's own rowid. Comparing either asked
173
175
  // to rewrite the column on every sync, and on SQLite, which cannot alter one at all, failed
@@ -179,6 +181,14 @@ function diffColumn(tableName, source, target, opts) {
179
181
  if (typeChanged) {
180
182
  differences.push(`type: ${formatType(source.type)} → ${formatType(target.type)}`);
181
183
  }
184
+ // Signedness is the one thing compared on a generated key, because it is the one part of the serial
185
+ // spelling that does round trip - and a key left unsigned refuses every foreign key pointing at it,
186
+ // since the referencing column takes its type from the canonical one, which is signed. Without this
187
+ // a database created before the serial became signed could never gain a foreign key.
188
+ const signednessChanged = generatedType && !!source.type.unsigned !== !!target.type.unsigned;
189
+ if (signednessChanged) {
190
+ differences.push(`type: ${formatType(source.type)} → ${formatType(target.type)}`);
191
+ }
182
192
  if (!impliedNotNull && source.nullable !== target.nullable) {
183
193
  differences.push(`nullable: ${target.nullable} → ${source.nullable}`);
184
194
  }
@@ -206,7 +216,7 @@ function diffColumn(tableName, source, target, opts) {
206
216
  // Only the type this diff actually reports: a column altered for its default carries no data loss,
207
217
  // and a generated key's type - never compared above - reads as unsigned against an entity that
208
218
  // cannot say so.
209
- isBreaking: typeChanged && isBreakingTypeChange(target.type, source.type),
219
+ isBreaking: (typeChanged || signednessChanged) && isBreakingTypeChange(target.type, source.type),
210
220
  description: differences.join(', '),
211
221
  };
212
222
  }
@@ -228,11 +238,17 @@ function diffIndex(tableName, source, target, facets) {
228
238
  };
229
239
  }
230
240
  /**
231
- * Compare relationships at the schema level.
241
+ * Compare two lists of relationships.
242
+ *
243
+ * Lists rather than whole schemas, because a migration diffs one table: its two sides are that
244
+ * table's `outgoingRelations`, where `diffSchemas` passes the schema's every relationship.
245
+ *
246
+ * Matched by columns, never by name - the engine named every constraint that already exists, so
247
+ * pairing on names would report every hand-named one as a drop and an add.
232
248
  */
233
- function diffRelationships(source, target, opts) {
234
- const normalizeName = nameNormalizer(opts);
235
- const { created, dropped, matched } = matchByKey(source.relationships, target.relationships, (relation) => getRelationshipKey(relation, normalizeName));
249
+ export function diffRelationshipNodes(source, target, opts = {}) {
250
+ const normalizeName = nameNormalizer({ ...DEFAULT_OPTIONS, ...opts });
251
+ const { created, dropped, matched } = matchByKey(source, target, (relation) => getRelationshipKey(relation, normalizeName));
236
252
  return [
237
253
  ...created.map((relation) => ({
238
254
  ...relationEnds(relation),
@@ -272,14 +272,29 @@ export interface IndexDiff {
272
272
  /**
273
273
  * Difference between two relationship definitions.
274
274
  */
275
- export interface RelationshipDiff {
275
+ interface RelationshipDiffBase {
276
276
  readonly name: string;
277
277
  readonly fromTable: string;
278
278
  readonly toTable: string;
279
- readonly type: 'create' | 'drop' | 'alter';
280
- readonly expected?: RelationshipNode;
281
- readonly actual?: RelationshipNode;
282
279
  }
280
+ /**
281
+ * Difference between two relationships, shaped like {@link ColumnDiff} and for the same reason: which
282
+ * node is present follows from the kind of difference, so a reader never asserts its way past an
283
+ * `undefined` the kind had already ruled out.
284
+ */
285
+ export type RelationshipDiff = RelationshipDiffBase & ({
286
+ readonly type: 'create';
287
+ readonly expected: RelationshipNode;
288
+ readonly actual?: undefined;
289
+ } | {
290
+ readonly type: 'drop';
291
+ readonly expected?: undefined;
292
+ readonly actual: RelationshipNode;
293
+ } | {
294
+ readonly type: 'alter';
295
+ readonly expected: RelationshipNode;
296
+ readonly actual: RelationshipNode;
297
+ });
283
298
  /**
284
299
  * Complete diff between two schemas.
285
300
  */
@@ -5,7 +5,7 @@ export declare class SqliteDialect extends AbstractSqlDialect {
5
5
  protected readonly featureDefaults: DialectFeatures;
6
6
  readonly dialectName = "sqlite";
7
7
  readonly escapeIdChar = "`";
8
- readonly serialType = "INTEGER PRIMARY KEY AUTOINCREMENT";
8
+ readonly autoIncrementSuffix = "PRIMARY KEY AUTOINCREMENT";
9
9
  readonly serialDeclaresPrimaryKey = true;
10
10
  readonly tableOptions = "";
11
11
  readonly beginTransactionCommand = "BEGIN TRANSACTION";
@@ -22,7 +22,7 @@ export class SqliteDialect extends AbstractSqlDialect {
22
22
  };
23
23
  dialectName = 'sqlite';
24
24
  escapeIdChar = '`';
25
- serialType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
25
+ autoIncrementSuffix = 'PRIMARY KEY AUTOINCREMENT';
26
26
  // `AUTOINCREMENT` is only legal in that exact phrase, so the key cannot be lifted to table level.
27
27
  serialDeclaresPrimaryKey = true;
28
28
  tableOptions = '';
@@ -232,7 +232,7 @@ export type RelationValue<E> = E[RelationKey<E>];
232
232
  /**
233
233
  * SQL numeric column types
234
234
  */
235
- export type NumericColumnType = 'int' | 'integer' | 'tinyint' | 'smallint' | 'bigint' | 'float' | 'float4' | 'float8' | 'double' | 'double precision' | 'decimal' | 'numeric' | 'real' | 'serial' | 'smallserial' | 'bigserial';
235
+ export type NumericColumnType = 'int' | 'integer' | 'tinyint' | 'smallint' | 'bigint' | 'float' | 'float4' | 'float8' | 'double' | 'double precision' | 'decimal' | 'numeric' | 'real';
236
236
  /**
237
237
  * SQL string column types
238
238
  */
@@ -741,7 +741,10 @@ export type EntityIndexMeta = {
741
741
  } & VectorIndexOptions & IndexTypeOptions;
742
742
  export type EntityMeta<E> = {
743
743
  readonly entity: Type<E>;
744
+ /** The table, which is the class's own name where the entity named none - see {@link derivedName}. */
744
745
  name?: string;
746
+ /** Whether {@link name} came from the class rather than from the author, so a naming strategy applies. */
747
+ derivedName?: boolean;
745
748
  /** Set only when the entity named one; unset defers to the pool where it is used. See `AbstractDialect.resolveSchema`. */
746
749
  schema?: string;
747
750
  /**
@@ -794,6 +797,16 @@ export type CheckOptions = {
794
797
  readonly name?: string;
795
798
  readonly expression: QueryRaw;
796
799
  };
800
+ /**
801
+ * An entity's members as the registry takes them, keyed by plain strings - what a decorator bag, an
802
+ * {@link EntityOptions} and a decorator bag both reduce to before anything is registered: a member
803
+ * decorator has no class to key against, so by then the keys are plain strings either way.
804
+ */
805
+ export type EntityMembers = {
806
+ readonly fields?: Readonly<Record<string, FieldOptions | undefined>>;
807
+ readonly relations?: Readonly<Record<string, RelationOptions | undefined>>;
808
+ readonly hooks?: Readonly<Partial<Record<HookEvent, readonly string[]>>>;
809
+ };
797
810
  export type EntityOptions<E = unknown> = {
798
811
  readonly name?: string;
799
812
  /**
@@ -1,5 +1,5 @@
1
1
  import type { VectorCast } from '../dialect/vectorCast.js';
2
- import type { FullColumnDefinition, TableDefinition, TableForeignKeyDefinition } from '../migrate/builder/types.js';
2
+ import type { FullColumnDefinition, TableDefinition } from '../migrate/builder/types.js';
3
3
  import type { IndexFacet } from '../schema/indexDifferences.js';
4
4
  import type { SchemaAST } from '../schema/schemaAST.js';
5
5
  import type { ForeignKeyAction, IndexNode, IndexType, TableNode } from '../schema/types.js';
@@ -161,15 +161,25 @@ export interface IndexSchema extends VectorIndexOptions {
161
161
  readonly vectorType?: VectorCast;
162
162
  }
163
163
  /**
164
- * Represents a foreign key constraint
164
+ * A foreign key constraint, wherever one is described: read back by introspection, planned into a
165
+ * {@link SchemaDiff}, or declared through the migration builder. One shape for all three - they
166
+ * differed only in spelling, and the translation between them was pure overhead.
165
167
  */
166
168
  export interface ForeignKeySchema {
167
- readonly name: string;
169
+ /** Absent when nothing named it, which the generator fills in with `derivedForeignKeyName`. */
170
+ readonly name?: string;
168
171
  readonly columns: string[];
169
- readonly referencedTable: string;
170
- readonly referencedColumns: string[];
171
- readonly onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
172
- readonly onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
172
+ /**
173
+ * The far end, as one thing. Same shape and same name as everywhere else a relationship's target is
174
+ * described - `@Field({ references })`, `addForeignKey`'s `target`, a `RelationshipNode`'s `to` -
175
+ * so nothing has to be destructured on the way between them.
176
+ */
177
+ readonly references: {
178
+ readonly table: string;
179
+ readonly columns: string[];
180
+ };
181
+ readonly onDelete?: ForeignKeyAction;
182
+ readonly onUpdate?: ForeignKeyAction;
173
183
  }
174
184
  /**
175
185
  * Represents a difference between current and desired schema
@@ -204,7 +214,30 @@ export interface SchemaDiff {
204
214
  readonly indexesToAdd?: IndexSchema[];
205
215
  readonly indexesToDrop?: string[];
206
216
  readonly foreignKeysToAdd?: ForeignKeySchema[];
217
+ /** Dropped under the name the *database* reported, which is the only name a `DROP` can use. */
207
218
  readonly foreignKeysToDrop?: string[];
219
+ /**
220
+ * A constraint whose referential actions changed. Its own field rather than a pair of entries in
221
+ * the two above, because no engine alters an action in place: it is a drop and an add that have to
222
+ * travel together, and safe mode has to hold back both or neither.
223
+ */
224
+ readonly foreignKeysToAlter?: {
225
+ readonly from: ForeignKeySchema;
226
+ readonly to: ForeignKeySchema;
227
+ }[];
228
+ }
229
+ /**
230
+ * What every sync entry point takes: `safe` keeps it additive, `drop` lets it remove a column, and
231
+ * `logging` reports each statement. A plan ignores `logging`, having nothing to run.
232
+ */
233
+ export interface SyncOptions {
234
+ readonly safe?: boolean;
235
+ readonly drop?: boolean;
236
+ readonly logging?: boolean;
237
+ /** One entity instead of every registered one, for a schema that grows while the process runs. */
238
+ readonly entity?: Type<unknown>;
239
+ /** Drop every table and recreate it. Development only: it is the one option that loses data. */
240
+ readonly force?: boolean;
208
241
  }
209
242
  export interface CreateSchemaOptions {
210
243
  readonly ifNotExists?: boolean;
@@ -265,8 +298,21 @@ export interface SchemaGenerator {
265
298
  getSqlType(fieldOptions: FieldOptions): string;
266
299
  /**
267
300
  * Compare an entity with a database table node and return the differences.
301
+ *
302
+ * `desiredAst` is the entity side, from {@link buildAST}, and must span every entity a foreign key
303
+ * on this table points at: a relation whose target is absent resolves to nothing, so the constraint
304
+ * reads as missing from both sides, which is a match and no statement. Defaults to this entity
305
+ * alone, which is right only where it has no relations.
306
+ */
307
+ diffSchema<E>(entity: Type<E>, currentTable: TableNode | undefined, desiredAst?: SchemaAST): SchemaDiff | undefined;
308
+ /**
309
+ * The entity side as an AST, to hand to every {@link diffSchema} of one run - building it per
310
+ * entity instead is quadratic in the number of entities.
311
+ *
312
+ * Optional because not every generator compares one: MongoDB has no foreign keys and diffs only
313
+ * indexes, so it neither implements this nor reads the argument.
268
314
  */
269
- diffSchema<E>(entity: Type<E>, currentTable: TableNode | undefined): SchemaDiff | undefined;
315
+ buildAST?(entities: readonly Type<unknown>[]): SchemaAST;
270
316
  /**
271
317
  * The table's key: {@link resolveTableAlias} behind {@link resolveSchema}, which is how a
272
318
  * `SchemaAST` stores it and how a diff finds it again.
@@ -313,7 +359,7 @@ export interface SqlDdlGenerator extends SchemaGenerator {
313
359
  /** Generate RENAME COLUMN statement */
314
360
  generateRenameColumnSql(tableName: string, oldName: string, newName: string): string;
315
361
  /** Generate ADD FOREIGN KEY statement */
316
- generateAddForeignKeySql(tableName: string, foreignKey: TableForeignKeyDefinition): string;
362
+ generateAddForeignKeySql(tableName: string, foreignKey: ForeignKeySchema): string;
317
363
  /** Generate DROP FOREIGN KEY statement */
318
364
  generateDropForeignKeySql(tableName: string, constraintName: string): string;
319
365
  }
@@ -296,10 +296,20 @@ type QueryCommonOp = Exclude<keyof QueryWhereFieldOperatorMap<unknown>, QueryStr
296
296
  type QueryAllowedOp<T> = QueryCommonOp | ([NonNullable<T>] extends [QueryComparableScalar] ? QueryOrderedOp : never) | ([NonNullable<T>] extends [string] ? QueryStringOp : never) | ([NonNullable<T>] extends [readonly number[] | Uint8Array] ? QueryVectorOp : never) | (IsMany<T> extends true ? QueryArrayOp : never);
297
297
  /**
298
298
  * Operators applicable to a field of type `T`: string operators require string fields, ordering
299
- * operators comparable fields, array operators array fields. `unknown` stays fully permissive
300
- * (untyped JSON dot-paths, erased dialect shapes).
299
+ * operators comparable fields, array operators array fields.
300
+ *
301
+ * Two shapes stay fully permissive, because neither says anything to check against: `unknown`
302
+ * (untyped JSON dot-paths, erased dialect shapes), and a field typed as every scalar at once - the
303
+ * column of a content type defined at runtime. Narrowing to what they share would leave a dynamic
304
+ * row with equality alone, since no operator applies to a boolean and a blob both.
305
+ */
306
+ export type QueryWhereFieldOperators<T> = unknown extends T ? QueryWhereFieldOperatorMap<T> : IsUntypedColumn<T> extends true ? QueryWhereFieldOperatorMap<T> : Pick<QueryWhereFieldOperatorMap<T>, QueryAllowedOp<T>>;
307
+ /**
308
+ * Whether a column admits every scalar at once, which is what an entity keyed by an index signature
309
+ * says about all of its columns. `Scalar` is the yardstick rather than a parameter: the question is
310
+ * whether `T` is at least that wide, and nothing narrower than the whole union answers it.
301
311
  */
302
- export type QueryWhereFieldOperators<T> = unknown extends T ? QueryWhereFieldOperatorMap<T> : Pick<QueryWhereFieldOperatorMap<T>, QueryAllowedOp<T>>;
312
+ type IsUntypedColumn<T> = [Scalar] extends [NonNullable<T>] ? true : false;
303
313
  /**
304
314
  * Value for a field comparison. A bare array is an implicit `$in` for scalar fields only:
305
315
  * on array-typed fields (e.g. a vector `number[]`) an array of arrays is ambiguous, so
@@ -12,7 +12,7 @@ export type ColumnFamily = 'string' | 'numeric' | 'boolean' | 'date' | 'json' |
12
12
  * restates the unions: the compile-time side of the same question reads them directly.
13
13
  */
14
14
  export declare const COLUMN_TYPES_BY_FAMILY: {
15
- readonly numeric: readonly ["int", "integer", "tinyint", "smallint", "bigint", "float", "float4", "float8", "double", "double precision", "decimal", "numeric", "real", "serial", "smallserial", "bigserial"];
15
+ readonly numeric: readonly ["int", "integer", "tinyint", "smallint", "bigint", "float", "float4", "float8", "double", "double precision", "decimal", "numeric", "real"];
16
16
  readonly string: readonly ["char", "varchar", "text", "uuid"];
17
17
  readonly date: readonly ["date", "time", "datetime", "timestamp", "timestamptz"];
18
18
  readonly json: readonly ["json", "jsonb"];
@@ -33,6 +33,11 @@ export declare function columnFamily(type: unknown): ColumnFamily | undefined;
33
33
  */
34
34
  export declare function isSoleIdField<E>(meta: EntityMeta<E>, field: FieldOptions): boolean;
35
35
  /**
36
- * Checks if a field should be treated as auto-incrementing.
36
+ * Whether the database generates this column's value.
37
+ *
38
+ * The only answer: the schema AST asked it separately and disagreed on three counts - it ignored
39
+ * `onInsert`, so a key the application generates was still emitted `AUTO_INCREMENT`, and it ignored
40
+ * `columnType`, where this one used to let *any* declared width suppress the whole inference. A key
41
+ * that states its width is still a generated key; one that states how it is filled is not.
37
42
  */
38
43
  export declare function isAutoIncrement(field: FieldOptions, isPrimaryKey: boolean): boolean;
@@ -20,9 +20,6 @@ export const COLUMN_TYPES_BY_FAMILY = {
20
20
  'decimal',
21
21
  'numeric',
22
22
  'real',
23
- 'serial',
24
- 'smallserial',
25
- 'bigserial',
26
23
  ],
27
24
  string: ['char', 'varchar', 'text', 'uuid'],
28
25
  date: ['date', 'time', 'datetime', 'timestamp', 'timestamptz'],
@@ -62,15 +59,15 @@ export function isSoleIdField(meta, field) {
62
59
  return field.isId === true && meta.ids.length === 1;
63
60
  }
64
61
  /**
65
- * Checks if a field should be treated as auto-incrementing.
62
+ * Whether the database generates this column's value.
63
+ *
64
+ * The only answer: the schema AST asked it separately and disagreed on three counts - it ignored
65
+ * `onInsert`, so a key the application generates was still emitted `AUTO_INCREMENT`, and it ignored
66
+ * `columnType`, where this one used to let *any* declared width suppress the whole inference. A key
67
+ * that states its width is still a generated key; one that states how it is filled is not.
66
68
  */
67
69
  export function isAutoIncrement(field, isPrimaryKey) {
68
- if (field.autoIncrement === false)
69
- return false;
70
- if (field.autoIncrement)
71
- return true;
72
- const colType = field.columnType?.toLowerCase();
73
- if (colType === 'serial' || colType === 'smallserial' || colType === 'bigserial')
74
- return true;
75
- return isPrimaryKey && columnFamily(field.type) === 'numeric' && !field.onInsert && !field.columnType;
70
+ if (field.autoIncrement !== undefined)
71
+ return field.autoIncrement;
72
+ return isPrimaryKey && columnFamily(field.type) === 'numeric' && !field.onInsert;
76
73
  }
@@ -21,9 +21,9 @@ export declare function isOperatorObject(value: unknown): value is Record<string
21
21
  export declare function isOperatorOnlyObject(value: unknown): value is Record<string, unknown>;
22
22
  export declare function getKeys<T extends object>(obj: T): (keyof T & string)[];
23
23
  /**
24
- * The entity's own name for a message to carry, declared or its class's. `defineEntity` always sets
25
- * one, so the fallback is for a meta a decorator is still building - which is why the sites spelling
26
- * this out reached for three different fallbacks, `?? ''` among them, and named nothing at all.
24
+ * The entity's own name, declared or its class's. `meta.name` holds only what the author wrote, so
25
+ * the fallback is what an entity that named no table is called - which is why the sites spelling this
26
+ * out reached for three different fallbacks, `?? ''` among them, and named nothing at all.
27
27
  */
28
28
  export declare function entityName<E>(meta: EntityMeta<E>): string;
29
29
  export declare function getFieldKeys<E>(fields: {
@@ -53,9 +53,9 @@ export function getKeys(obj) {
53
53
  return obj ? Object.keys(obj) : [];
54
54
  }
55
55
  /**
56
- * The entity's own name for a message to carry, declared or its class's. `defineEntity` always sets
57
- * one, so the fallback is for a meta a decorator is still building - which is why the sites spelling
58
- * this out reached for three different fallbacks, `?? ''` among them, and named nothing at all.
56
+ * The entity's own name, declared or its class's. `meta.name` holds only what the author wrote, so
57
+ * the fallback is what an entity that named no table is called - which is why the sites spelling this
58
+ * out reached for three different fallbacks, `?? ''` among them, and named nothing at all.
59
59
  */
60
60
  export function entityName(meta) {
61
61
  return meta.name ?? meta.entity.name;
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "uql-orm",
3
3
  "homepage": "https://uql-orm.dev",
4
- "description": "JSON-native TypeScript ORM for Node.js, Bun and Deno. Supports PostgreSQL, PGlite, MySQL, MariaDB, SQLite, CockroachDB, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.",
4
+ "description": "The JSON-native TypeScript ORM for Bun, Browsers, Edge, Deno, Node, Workers. Supports PostgreSQL, PGlite, MySQL, MariaDB, SQLite, CockroachDB, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.",
5
5
  "license": "MIT",
6
- "version": "0.43.0",
6
+ "version": "0.45.0",
7
7
  "type": "module",
8
8
  "engines": {
9
9
  "node": ">=24"
@@ -145,7 +145,7 @@
145
145
  "express": "^5.2.1",
146
146
  "mariadb": "^3.5.4",
147
147
  "mongodb": "^7.6.0",
148
- "mysql2": "^3.24.3",
148
+ "mysql2": "^3.24.4",
149
149
  "pg": "^8.23.0",
150
150
  "pg-query-stream": "^4.17.0",
151
151
  "rxjs": "^7.8.2",