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.
- package/README.md +3 -2
- package/dist/browser/querier/httpQuerier.d.ts +6 -0
- package/dist/browser/querier/httpQuerier.js +1 -1
- package/dist/browser/uql-browser.min.js +2 -2
- package/dist/browser/uql-browser.min.js.map +4 -4
- package/dist/dialect/abstractDialect.js +5 -6
- package/dist/dialect/abstractSqlDialect.d.ts +2 -2
- package/dist/dialect/abstractSqlDialect.js +1 -1
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +8 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +8 -1
- package/dist/dialect/pgLikeSqlDialect.d.ts +1 -1
- package/dist/dialect/pgLikeSqlDialect.js +1 -1
- package/dist/entity/decorator/bag.d.ts +3 -0
- package/dist/entity/index.d.ts +1 -1
- package/dist/entity/index.js +1 -1
- package/dist/entity/metadata/definition.d.ts +15 -13
- package/dist/entity/metadata/definition.js +47 -16
- package/dist/http/handler.d.ts +8 -0
- package/dist/http/handler.js +5 -5
- package/dist/migrate/builder/migrationBuilder.js +1 -2
- package/dist/migrate/builder/tableBuilder.d.ts +1 -0
- package/dist/migrate/builder/tableBuilder.js +9 -10
- package/dist/migrate/builder/types.d.ts +3 -19
- package/dist/migrate/cli.d.ts +5 -0
- package/dist/migrate/cli.js +33 -16
- package/dist/migrate/codegen/entityTypes.d.ts +7 -0
- package/dist/migrate/codegen/entityTypes.js +69 -0
- package/dist/migrate/codegen/index.d.ts +1 -0
- package/dist/migrate/codegen/index.js +1 -0
- package/dist/migrate/generator/definitionToNode.js +2 -2
- package/dist/migrate/index.d.ts +1 -1
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +2 -5
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +2 -0
- package/dist/migrate/introspection/baseSqlIntrospector.js +4 -3
- package/dist/migrate/introspection/mysqlIntrospector.js +1 -2
- package/dist/migrate/introspection/postgresIntrospector.js +1 -2
- package/dist/migrate/introspection/sqliteIntrospector.js +1 -2
- package/dist/migrate/migrator.d.ts +34 -20
- package/dist/migrate/migrator.js +90 -35
- package/dist/migrate/schemaGenerator.d.ts +20 -5
- package/dist/migrate/schemaGenerator.js +105 -30
- package/dist/schema/schemaASTBuilder.d.ts +23 -2
- package/dist/schema/schemaASTBuilder.js +3 -2
- package/dist/schema/schemaASTDiffer.d.ts +11 -1
- package/dist/schema/schemaASTDiffer.js +23 -7
- package/dist/schema/types.d.ts +19 -4
- package/dist/sqlite/sqliteDialect.d.ts +1 -1
- package/dist/sqlite/sqliteDialect.js +1 -1
- package/dist/type/entity.d.ts +14 -1
- package/dist/type/migration.d.ts +55 -9
- package/dist/type/queryWhere.d.ts +13 -3
- package/dist/util/field.util.d.ts +7 -2
- package/dist/util/field.util.js +9 -12
- package/dist/util/object.util.d.ts +3 -3
- package/dist/util/object.util.js +3 -3
- 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
|
|
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
|
|
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
|
|
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
|
|
234
|
-
const normalizeName = nameNormalizer(opts);
|
|
235
|
-
const { created, dropped, matched } = matchByKey(source
|
|
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),
|
package/dist/schema/types.d.ts
CHANGED
|
@@ -272,14 +272,29 @@ export interface IndexDiff {
|
|
|
272
272
|
/**
|
|
273
273
|
* Difference between two relationship definitions.
|
|
274
274
|
*/
|
|
275
|
-
|
|
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
|
|
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
|
-
|
|
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 = '';
|
package/dist/type/entity.d.ts
CHANGED
|
@@ -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'
|
|
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
|
/**
|
package/dist/type/migration.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { VectorCast } from '../dialect/vectorCast.js';
|
|
2
|
-
import type { FullColumnDefinition, TableDefinition
|
|
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
|
-
*
|
|
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
|
-
|
|
169
|
+
/** Absent when nothing named it, which the generator fills in with `derivedForeignKeyName`. */
|
|
170
|
+
readonly name?: string;
|
|
168
171
|
readonly columns: string[];
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
300
|
-
*
|
|
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
|
-
|
|
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"
|
|
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
|
-
*
|
|
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;
|
package/dist/util/field.util.js
CHANGED
|
@@ -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
|
-
*
|
|
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
|
|
69
|
-
return
|
|
70
|
-
|
|
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
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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: {
|
package/dist/util/object.util.js
CHANGED
|
@@ -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
|
|
57
|
-
*
|
|
58
|
-
*
|
|
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
|
|
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.
|
|
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.
|
|
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",
|