litedbmodel 2.2.6 → 2.2.8
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 +146 -86
- package/dist/Column.d.ts +30 -6
- package/dist/Column.d.ts.map +1 -1
- package/dist/Column.js +30 -10
- package/dist/Column.js.map +1 -1
- package/dist/DBModel.d.ts +28 -16
- package/dist/DBModel.d.ts.map +1 -1
- package/dist/DBModel.js +60 -46
- package/dist/DBModel.js.map +1 -1
- package/dist/LazyRelation.d.ts +2 -2
- package/dist/LazyRelation.js +2 -2
- package/dist/TypeCast.d.ts +2 -2
- package/dist/TypeCast.d.ts.map +1 -1
- package/dist/TypeCast.js +7 -9
- package/dist/TypeCast.js.map +1 -1
- package/dist/decorators.d.ts +128 -60
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +393 -251
- package/dist/decorators.js.map +1 -1
- package/dist/drivers/MysqlHelper.d.ts +3 -3
- package/dist/drivers/MysqlHelper.d.ts.map +1 -1
- package/dist/drivers/MysqlHelper.js +3 -17
- package/dist/drivers/MysqlHelper.js.map +1 -1
- package/dist/drivers/MysqlSqlBuilder.d.ts.map +1 -1
- package/dist/drivers/MysqlSqlBuilder.js +2 -13
- package/dist/drivers/MysqlSqlBuilder.js.map +1 -1
- package/dist/drivers/PostgresHelper.d.ts +3 -2
- package/dist/drivers/PostgresHelper.d.ts.map +1 -1
- package/dist/drivers/PostgresHelper.js +3 -16
- package/dist/drivers/PostgresHelper.js.map +1 -1
- package/dist/drivers/PostgresSqlBuilder.d.ts.map +1 -1
- package/dist/drivers/PostgresSqlBuilder.js +2 -14
- package/dist/drivers/PostgresSqlBuilder.js.map +1 -1
- package/dist/drivers/SqliteHelper.d.ts +4 -2
- package/dist/drivers/SqliteHelper.d.ts.map +1 -1
- package/dist/drivers/SqliteHelper.js +4 -2
- package/dist/drivers/SqliteHelper.js.map +1 -1
- package/dist/drivers/SqliteSqlBuilder.d.ts.map +1 -1
- package/dist/drivers/SqliteSqlBuilder.js +2 -13
- package/dist/drivers/SqliteSqlBuilder.js.map +1 -1
- package/dist/index.cjs +861 -816
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/scp/coltype.d.ts +14 -5
- package/dist/scp/coltype.d.ts.map +1 -1
- package/dist/scp/coltype.js +35 -36
- package/dist/scp/coltype.js.map +1 -1
- package/dist/scp/decorator-adapter.d.ts +12 -15
- package/dist/scp/decorator-adapter.d.ts.map +1 -1
- package/dist/scp/decorator-adapter.js +13 -15
- package/dist/scp/decorator-adapter.js.map +1 -1
- package/dist/scp/index.cjs +237 -233
- package/dist/scp/index.mjs +237 -233
- package/dist/scp/makesql/json-array.d.ts +6 -0
- package/dist/scp/makesql/json-array.d.ts.map +1 -1
- package/dist/scp/makesql/json-array.js +17 -2
- package/dist/scp/makesql/json-array.js.map +1 -1
- package/dist/scp/makesql/tx.d.ts.map +1 -1
- package/dist/scp/makesql/tx.js +1 -3
- package/dist/scp/makesql/tx.js.map +1 -1
- package/dist/scp/relation.d.ts.map +1 -1
- package/dist/scp/relation.js +8 -10
- package/dist/scp/relation.js.map +1 -1
- package/docs/BENCHMARK.md +3 -3
- package/docs/COMPARISON.md +7 -7
- package/docs/api/README.md +18 -18
- package/docs/api/classes/Conditions.md +10 -10
- package/docs/api/classes/DBHandler.md +1 -1
- package/docs/api/classes/DBModel.md +84 -84
- package/docs/api/classes/LimitExceededError.md +1 -1
- package/docs/api/classes/Middleware.md +1 -1
- package/docs/api/classes/SqlRaw.md +1 -1
- package/docs/api/classes/SqlRef.md +1 -1
- package/docs/api/classes/Values.md +6 -6
- package/docs/api/classes/WriteInReadOnlyContextError.md +1 -1
- package/docs/api/classes/WriteOutsideTransactionError.md +1 -1
- package/docs/api/functions/belongsTo.md +10 -4
- package/docs/api/functions/closeAllPools.md +1 -1
- package/docs/api/functions/condsToRecord.md +4 -3
- package/docs/api/functions/createMiddleware.md +1 -1
- package/docs/api/functions/createPostgresDriver.md +1 -1
- package/docs/api/functions/createSqliteDriver.md +1 -1
- package/docs/api/functions/dbCast.md +1 -1
- package/docs/api/functions/dbCastIn.md +1 -1
- package/docs/api/functions/dbDynamic.md +1 -1
- package/docs/api/functions/dbFalse.md +1 -1
- package/docs/api/functions/dbImmediate.md +1 -1
- package/docs/api/functions/dbIn.md +1 -1
- package/docs/api/functions/dbNotNull.md +1 -1
- package/docs/api/functions/dbNow.md +1 -1
- package/docs/api/functions/dbNull.md +1 -1
- package/docs/api/functions/dbRaw.md +1 -1
- package/docs/api/functions/dbTrue.md +1 -1
- package/docs/api/functions/dbUuid.md +1 -1
- package/docs/api/functions/dbUuidIn.md +1 -1
- package/docs/api/functions/formatLocalDate.md +2 -2
- package/docs/api/functions/formatUTCDate.md +2 -2
- package/docs/api/functions/getDBConfig.md +1 -1
- package/docs/api/functions/getDBHandler.md +1 -1
- package/docs/api/functions/getTransactionConnection.md +2 -2
- package/docs/api/functions/getTransactionContext.md +2 -2
- package/docs/api/functions/hasMany.md +11 -5
- package/docs/api/functions/hasOne.md +10 -4
- package/docs/api/functions/initDBHandler.md +1 -1
- package/docs/api/functions/isAnySqlFragment.md +1 -1
- package/docs/api/functions/isConnectionError.md +1 -1
- package/docs/api/functions/isSqlCondition.md +1 -1
- package/docs/api/functions/isSqlFragment.md +1 -1
- package/docs/api/functions/isSqlRaw.md +1 -1
- package/docs/api/functions/isSqlRef.md +1 -1
- package/docs/api/functions/isSqlTypedFragment.md +1 -1
- package/docs/api/functions/model.md +8 -155
- package/docs/api/functions/parentRef.md +1 -1
- package/docs/api/functions/sql.md +1 -1
- package/docs/api/globals.md +99 -58
- package/docs/api/interfaces/Column.md +32 -31
- package/docs/api/interfaces/ColumnDecorator.md +81 -0
- package/docs/api/interfaces/ColumnOptions.md +6 -10
- package/docs/api/interfaces/CreatedMiddlewareClass.md +1 -1
- package/docs/api/interfaces/DBConfig.md +1 -1
- package/docs/api/interfaces/DBConfigOptions.md +1 -1
- package/docs/api/interfaces/DeleteOptions.md +1 -1
- package/docs/api/interfaces/InsertOptions.md +1 -1
- package/docs/api/interfaces/LimitConfig.md +1 -1
- package/docs/api/interfaces/MiddlewareConfig.md +1 -1
- package/docs/api/interfaces/ModelClassDecorator.md +64 -0
- package/docs/api/interfaces/ModelOptions.md +1 -1
- package/docs/api/interfaces/PkeyResult.md +1 -1
- package/docs/api/interfaces/RelationDecorator.md +72 -0
- package/docs/api/interfaces/SelectOptions.md +1 -1
- package/docs/api/interfaces/SqlCondition.md +1 -1
- package/docs/api/interfaces/SqlFragment.md +1 -1
- package/docs/api/interfaces/SqlTypedFragment.md +1 -1
- package/docs/api/interfaces/TransactionOptions.md +1 -1
- package/docs/api/interfaces/UpdateManyOptions.md +1 -1
- package/docs/api/interfaces/UpdateOptions.md +1 -1
- package/docs/api-guide.md +17 -17
- package/docs/architecture.md +14 -10
- package/docs/sql-tagged-template.md +5 -5
- package/eslint-plugin/rules/require-declare-for-relations.js +59 -4
- package/package.json +8 -7
package/dist/scp/index.mjs
CHANGED
|
@@ -2054,12 +2054,14 @@ function tupleInPredicate(dialect, table, columns, pgElementTypes) {
|
|
|
2054
2054
|
function encodeJsonArrayParam(dialect, values) {
|
|
2055
2055
|
return encodeJsonParam(dialect, values);
|
|
2056
2056
|
}
|
|
2057
|
+
var BIGINT_SENTINEL = "\0int:";
|
|
2057
2058
|
function encodeJsonParam(dialect, payload) {
|
|
2058
|
-
|
|
2059
|
-
if (typeof v === "bigint") return
|
|
2059
|
+
const tagged = JSON.stringify(payload, (_key, v) => {
|
|
2060
|
+
if (typeof v === "bigint") return `${BIGINT_SENTINEL}${v.toString()}`;
|
|
2060
2061
|
if (dialect === "mysql" && typeof v === "boolean") return v ? 1 : 0;
|
|
2061
2062
|
return v;
|
|
2062
2063
|
});
|
|
2064
|
+
return tagged.replace(/"\\u0000int:(-?\d+)"/g, "$1");
|
|
2063
2065
|
}
|
|
2064
2066
|
var JsonArrayConditions = class extends DBConditions {
|
|
2065
2067
|
_dialect;
|
|
@@ -2106,6 +2108,11 @@ function andTrailing(head, tails) {
|
|
|
2106
2108
|
return [head, ...guardedTails];
|
|
2107
2109
|
}
|
|
2108
2110
|
|
|
2111
|
+
// src/drivers/PostgresHelper.ts
|
|
2112
|
+
function castToJson(val) {
|
|
2113
|
+
return val ?? null;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2109
2116
|
// src/TypeCast.ts
|
|
2110
2117
|
var defaultTypeCast = {
|
|
2111
2118
|
castToDatetime(val) {
|
|
@@ -2230,17 +2237,15 @@ var defaultTypeCast = {
|
|
|
2230
2237
|
}
|
|
2231
2238
|
return [];
|
|
2232
2239
|
},
|
|
2240
|
+
// A string is JSON text to decode; any other value is already a JSON value
|
|
2233
2241
|
castToJson(val) {
|
|
2234
2242
|
if (val === null || val === void 0) return null;
|
|
2235
|
-
if (typeof val
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
return null;
|
|
2241
|
-
}
|
|
2243
|
+
if (typeof val !== "string") return val;
|
|
2244
|
+
try {
|
|
2245
|
+
return JSON.parse(val);
|
|
2246
|
+
} catch {
|
|
2247
|
+
return null;
|
|
2242
2248
|
}
|
|
2243
|
-
return null;
|
|
2244
2249
|
}
|
|
2245
2250
|
};
|
|
2246
2251
|
function parsePostgresArray(literal) {
|
|
@@ -2297,7 +2302,7 @@ function castToBooleanArray(val) {
|
|
|
2297
2302
|
function castToDatetimeArray(val) {
|
|
2298
2303
|
return currentTypeCast.castToDatetimeArray(val);
|
|
2299
2304
|
}
|
|
2300
|
-
function
|
|
2305
|
+
function castToJson2(val) {
|
|
2301
2306
|
return currentTypeCast.castToJson(val);
|
|
2302
2307
|
}
|
|
2303
2308
|
function formatLocalDate(d) {
|
|
@@ -2341,16 +2346,7 @@ var postgresTypeCast = {
|
|
|
2341
2346
|
return JSON.stringify(val);
|
|
2342
2347
|
},
|
|
2343
2348
|
deserializeJson(val) {
|
|
2344
|
-
|
|
2345
|
-
if (typeof val === "object") return val;
|
|
2346
|
-
if (typeof val === "string") {
|
|
2347
|
-
try {
|
|
2348
|
-
return JSON.parse(val);
|
|
2349
|
-
} catch {
|
|
2350
|
-
return null;
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
return null;
|
|
2349
|
+
return castToJson(val);
|
|
2354
2350
|
},
|
|
2355
2351
|
serializeBooleanArray(val) {
|
|
2356
2352
|
if (val === null || val === void 0) return null;
|
|
@@ -2654,6 +2650,11 @@ var postgresSqlBuilder = {
|
|
|
2654
2650
|
inferPgType
|
|
2655
2651
|
};
|
|
2656
2652
|
|
|
2653
|
+
// src/drivers/MysqlHelper.ts
|
|
2654
|
+
function castToJson3(val) {
|
|
2655
|
+
return val ?? null;
|
|
2656
|
+
}
|
|
2657
|
+
|
|
2657
2658
|
// src/drivers/MysqlSqlBuilder.ts
|
|
2658
2659
|
var mysqlTypeCast = {
|
|
2659
2660
|
driverName: "mysql",
|
|
@@ -2679,16 +2680,7 @@ var mysqlTypeCast = {
|
|
|
2679
2680
|
return JSON.stringify(val);
|
|
2680
2681
|
},
|
|
2681
2682
|
deserializeJson(val) {
|
|
2682
|
-
|
|
2683
|
-
if (typeof val === "object") return val;
|
|
2684
|
-
if (typeof val === "string") {
|
|
2685
|
-
try {
|
|
2686
|
-
return JSON.parse(val);
|
|
2687
|
-
} catch {
|
|
2688
|
-
return null;
|
|
2689
|
-
}
|
|
2690
|
-
}
|
|
2691
|
-
return null;
|
|
2683
|
+
return castToJson3(val);
|
|
2692
2684
|
},
|
|
2693
2685
|
serializeBooleanArray(val) {
|
|
2694
2686
|
if (val === null || val === void 0) return null;
|
|
@@ -2856,6 +2848,24 @@ var mysqlSqlBuilder = {
|
|
|
2856
2848
|
}
|
|
2857
2849
|
};
|
|
2858
2850
|
|
|
2851
|
+
// src/drivers/SqliteHelper.ts
|
|
2852
|
+
function castToJson4(val) {
|
|
2853
|
+
if (val === null || val === void 0) {
|
|
2854
|
+
return null;
|
|
2855
|
+
}
|
|
2856
|
+
if (typeof val === "object" || typeof val === "number") {
|
|
2857
|
+
return val;
|
|
2858
|
+
}
|
|
2859
|
+
if (typeof val === "string") {
|
|
2860
|
+
try {
|
|
2861
|
+
return JSON.parse(val);
|
|
2862
|
+
} catch {
|
|
2863
|
+
return null;
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
return null;
|
|
2867
|
+
}
|
|
2868
|
+
|
|
2859
2869
|
// src/drivers/SqliteSqlBuilder.ts
|
|
2860
2870
|
var sqliteTypeCast = {
|
|
2861
2871
|
driverName: "sqlite",
|
|
@@ -2881,16 +2891,7 @@ var sqliteTypeCast = {
|
|
|
2881
2891
|
return JSON.stringify(val);
|
|
2882
2892
|
},
|
|
2883
2893
|
deserializeJson(val) {
|
|
2884
|
-
|
|
2885
|
-
if (typeof val === "object") return val;
|
|
2886
|
-
if (typeof val === "string") {
|
|
2887
|
-
try {
|
|
2888
|
-
return JSON.parse(val);
|
|
2889
|
-
} catch {
|
|
2890
|
-
return null;
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
return null;
|
|
2894
|
+
return castToJson4(val);
|
|
2894
2895
|
},
|
|
2895
2896
|
serializeBooleanArray(val) {
|
|
2896
2897
|
if (val === null || val === void 0) return null;
|
|
@@ -3426,8 +3427,8 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
3426
3427
|
return "passthrough";
|
|
3427
3428
|
}
|
|
3428
3429
|
switch (t) {
|
|
3429
|
-
//
|
|
3430
|
-
//
|
|
3430
|
+
// Integer family. The PostgreSQL SERIAL types are the same integers under an auto-increment
|
|
3431
|
+
// default (SERIAL/SERIAL4=int4, SMALLSERIAL/SERIAL2=int2, BIGSERIAL/SERIAL8=int8).
|
|
3431
3432
|
case "INTEGER":
|
|
3432
3433
|
case "INT":
|
|
3433
3434
|
case "SMALLINT":
|
|
@@ -3439,13 +3440,11 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
3439
3440
|
case "SERIAL4":
|
|
3440
3441
|
case "SMALLSERIAL":
|
|
3441
3442
|
case "SERIAL2":
|
|
3442
|
-
return "int32";
|
|
3443
|
-
// 64-bit int: needs JS bigint for exactness.
|
|
3444
3443
|
case "BIGINT":
|
|
3445
3444
|
case "INT8":
|
|
3446
3445
|
case "BIGSERIAL":
|
|
3447
3446
|
case "SERIAL8":
|
|
3448
|
-
return "
|
|
3447
|
+
return "int";
|
|
3449
3448
|
case "BOOLEAN":
|
|
3450
3449
|
case "BOOL":
|
|
3451
3450
|
return "bool";
|
|
@@ -3482,44 +3481,45 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
3482
3481
|
}
|
|
3483
3482
|
function keyArrayElemScalar(sqlType) {
|
|
3484
3483
|
switch (sqlTypeToMaterializeClass(sqlType)) {
|
|
3485
|
-
case "
|
|
3486
|
-
return "
|
|
3487
|
-
// materializes to a JS
|
|
3488
|
-
case "int64":
|
|
3484
|
+
case "int":
|
|
3485
|
+
return "int";
|
|
3486
|
+
// materializes to a JS bigint → bc int
|
|
3489
3487
|
case "date":
|
|
3490
3488
|
return "string";
|
|
3491
|
-
// materializes to a
|
|
3489
|
+
// materializes to a TZ string → bc string
|
|
3492
3490
|
case "bool":
|
|
3493
3491
|
return "bool";
|
|
3494
3492
|
case "passthrough":
|
|
3495
3493
|
return sqlTypeToBcScalar(sqlType) === "float" ? "float" : "string";
|
|
3496
3494
|
}
|
|
3497
3495
|
}
|
|
3496
|
+
var I64_MIN = -(2n ** 63n);
|
|
3497
|
+
var I64_MAX = 2n ** 63n - 1n;
|
|
3498
|
+
function checkI64(v) {
|
|
3499
|
+
if (v < I64_MIN || v > I64_MAX) {
|
|
3500
|
+
throw new Error(`materialize int: ${v} is outside the i64 range behavior-contracts' \`int\` admits`);
|
|
3501
|
+
}
|
|
3502
|
+
return v;
|
|
3503
|
+
}
|
|
3498
3504
|
function materializeCell(value, klass) {
|
|
3499
3505
|
if (value === null || value === void 0) return value;
|
|
3500
3506
|
switch (klass) {
|
|
3501
|
-
case "
|
|
3502
|
-
if (typeof value === "bigint") return value
|
|
3507
|
+
case "int": {
|
|
3508
|
+
if (typeof value === "bigint") return checkI64(value);
|
|
3503
3509
|
if (typeof value === "string") {
|
|
3504
|
-
if (!/^-?\d+$/.test(value)) throw new Error(`materialize
|
|
3505
|
-
return value;
|
|
3510
|
+
if (!/^-?\d+$/.test(value)) throw new Error(`materialize int: driver returned a non-integer string '${value}'`);
|
|
3511
|
+
return checkI64(BigInt(value));
|
|
3506
3512
|
}
|
|
3507
3513
|
if (typeof value === "number") {
|
|
3508
|
-
if (!Number.isInteger(value)) throw new Error(`materialize
|
|
3514
|
+
if (!Number.isInteger(value)) throw new Error(`materialize int: driver returned a non-integer number ${value} for an integer column`);
|
|
3509
3515
|
if (!Number.isSafeInteger(value)) {
|
|
3510
3516
|
throw new Error(
|
|
3511
|
-
`materialize
|
|
3517
|
+
`materialize int: driver returned an UNSAFE JS number ${value} for an integer column \u2014 precision was already lost before materialization (the driver must return integers as bigint/string, not a rounded double). Configure the driver (better-sqlite3 safeIntegers / mysql2 supportBigNumbers+bigNumberStrings / pg int-as-bigint).`
|
|
3512
3518
|
);
|
|
3513
3519
|
}
|
|
3514
|
-
return value
|
|
3520
|
+
return BigInt(value);
|
|
3515
3521
|
}
|
|
3516
|
-
throw new Error(`materialize
|
|
3517
|
-
}
|
|
3518
|
-
case "int32": {
|
|
3519
|
-
if (typeof value === "number") return value;
|
|
3520
|
-
if (typeof value === "bigint") return Number(value);
|
|
3521
|
-
if (typeof value === "string" && /^-?\d+$/.test(value)) return Number(value);
|
|
3522
|
-
throw new Error(`materialize int32: unexpected driver JS type ${typeof value} (${String(value)})`);
|
|
3522
|
+
throw new Error(`materialize int: unexpected driver JS type ${typeof value}`);
|
|
3523
3523
|
}
|
|
3524
3524
|
case "date": {
|
|
3525
3525
|
if (typeof value === "string") return value;
|
|
@@ -5008,8 +5008,7 @@ function onConflictTail(dialect, ports, cols) {
|
|
|
5008
5008
|
}
|
|
5009
5009
|
function pgTypeSpecimen(sqlType) {
|
|
5010
5010
|
const klass = sqlTypeToMaterializeClass(sqlType);
|
|
5011
|
-
if (klass === "
|
|
5012
|
-
if (klass === "int64") return 0n;
|
|
5011
|
+
if (klass === "int") return 0n;
|
|
5013
5012
|
if (klass === "bool") return false;
|
|
5014
5013
|
if (klass === "date") return /* @__PURE__ */ new Date(0);
|
|
5015
5014
|
const scalar = sqlTypeToBcScalar(sqlType);
|
|
@@ -5601,10 +5600,6 @@ function materializeChildRows(rows, cols) {
|
|
|
5601
5600
|
row[key] = materializeCell(row[key], klass);
|
|
5602
5601
|
continue;
|
|
5603
5602
|
}
|
|
5604
|
-
if (typeof row[key] === "bigint") {
|
|
5605
|
-
const v = row[key];
|
|
5606
|
-
row[key] = v >= BigInt(Number.MIN_SAFE_INTEGER) && v <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(v) : v.toString();
|
|
5607
|
-
}
|
|
5608
5603
|
}
|
|
5609
5604
|
}
|
|
5610
5605
|
return rows;
|
|
@@ -5744,133 +5739,116 @@ function compileDeleteManyBundle(name, options, dialectName = "sqlite") {
|
|
|
5744
5739
|
var import_reflect_metadata = __toESM(require_Reflect());
|
|
5745
5740
|
var COLUMNS_KEY = /* @__PURE__ */ Symbol("litedbmodel:columns");
|
|
5746
5741
|
var RELATIONS_KEY = /* @__PURE__ */ Symbol("litedbmodel:relations");
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
return materializeCell(v, "date");
|
|
5765
|
-
},
|
|
5766
|
-
// Delegate to driver-specific serializeDatetime
|
|
5767
|
-
serialize: (val, typeCast) => {
|
|
5768
|
-
if (val === null || val === void 0) return null;
|
|
5769
|
-
if (val instanceof Date) {
|
|
5770
|
-
return typeCast?.serializeDatetime(val) ?? val;
|
|
5771
|
-
}
|
|
5772
|
-
return val;
|
|
5773
|
-
},
|
|
5774
|
-
sqlCast: "timestamp"
|
|
5775
|
-
};
|
|
5776
|
-
case Number:
|
|
5777
|
-
return {
|
|
5778
|
-
typeCast: (v) => {
|
|
5779
|
-
if (v === void 0) return void 0;
|
|
5780
|
-
if (v === null) return null;
|
|
5781
|
-
const n = Number(v);
|
|
5782
|
-
return isNaN(n) ? null : n;
|
|
5783
|
-
}
|
|
5784
|
-
};
|
|
5785
|
-
case BigInt:
|
|
5786
|
-
return {
|
|
5787
|
-
// v2 read contract: BIGINT/INT8 → EXACT decimal STRING (no i64 rounding, JSON-safe), via the
|
|
5788
|
-
// shared materializer. NOTE: the TS field type stays `bigint` in existing models for source
|
|
5789
|
-
// compat, but the VALUE is now the exact string — the whole point of the #9 realignment.
|
|
5790
|
-
typeCast: (v) => {
|
|
5791
|
-
if (v === void 0) return void 0;
|
|
5792
|
-
return materializeCell(v, "int64");
|
|
5793
|
-
},
|
|
5794
|
-
sqlCast: "bigint"
|
|
5795
|
-
};
|
|
5796
|
-
// Array, Object, String, and other types require explicit specification
|
|
5797
|
-
default:
|
|
5798
|
-
return void 0;
|
|
5799
|
-
}
|
|
5800
|
-
}
|
|
5801
|
-
function inferBaseSqlTypeFromDesignType(target, propertyKey) {
|
|
5802
|
-
const designType = Reflect.getMetadata("design:type", target, propertyKey);
|
|
5803
|
-
if (!designType) return void 0;
|
|
5804
|
-
switch (designType) {
|
|
5805
|
-
case String:
|
|
5806
|
-
return "TEXT";
|
|
5807
|
-
case Number:
|
|
5808
|
-
return "INTEGER";
|
|
5809
|
-
case Boolean:
|
|
5810
|
-
return "BOOLEAN";
|
|
5811
|
-
case Date:
|
|
5812
|
-
return "TIMESTAMP";
|
|
5813
|
-
case BigInt:
|
|
5814
|
-
return "BIGINT";
|
|
5815
|
-
default:
|
|
5816
|
-
return void 0;
|
|
5742
|
+
if (typeof Symbol === "function" && !Symbol.metadata) {
|
|
5743
|
+
Object.defineProperty(Symbol, "metadata", {
|
|
5744
|
+
value: /* @__PURE__ */ Symbol.for("Symbol.metadata"),
|
|
5745
|
+
writable: false,
|
|
5746
|
+
enumerable: false,
|
|
5747
|
+
configurable: true
|
|
5748
|
+
});
|
|
5749
|
+
}
|
|
5750
|
+
function isStandardContext(second) {
|
|
5751
|
+
return typeof second === "object" && second !== null && typeof second.kind === "string";
|
|
5752
|
+
}
|
|
5753
|
+
function classMetadataBag(context, propertyKey) {
|
|
5754
|
+
const bag = context.metadata;
|
|
5755
|
+
if (bag === void 0) {
|
|
5756
|
+
throw new Error(
|
|
5757
|
+
`litedbmodel: the standard-decorator context for '${propertyKey}' carries no \`context.metadata\`. litedbmodel defines \`Symbol.metadata\` on import, which every current emit needs to create the bag \u2014 import litedbmodel (or 'litedbmodel/decorators') BEFORE the module that defines the model.`
|
|
5758
|
+
);
|
|
5817
5759
|
}
|
|
5760
|
+
return bag;
|
|
5818
5761
|
}
|
|
5819
|
-
function
|
|
5820
|
-
const
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
if (!finalSqlCast) finalSqlCast = inferred.sqlCast;
|
|
5831
|
-
}
|
|
5762
|
+
function legacyColumnMap(constructor) {
|
|
5763
|
+
const own = Reflect.getOwnMetadata(COLUMNS_KEY, constructor);
|
|
5764
|
+
if (own !== void 0) return own;
|
|
5765
|
+
const inherited = Reflect.getMetadata(COLUMNS_KEY, constructor);
|
|
5766
|
+
const map = new Map(inherited);
|
|
5767
|
+
Reflect.defineMetadata(COLUMNS_KEY, map, constructor);
|
|
5768
|
+
return map;
|
|
5769
|
+
}
|
|
5770
|
+
function standardColumnMap(bag) {
|
|
5771
|
+
if (!Object.prototype.hasOwnProperty.call(bag, COLUMNS_KEY)) {
|
|
5772
|
+
bag[COLUMNS_KEY] = new Map(bag[COLUMNS_KEY]);
|
|
5832
5773
|
}
|
|
5833
|
-
|
|
5774
|
+
return bag[COLUMNS_KEY];
|
|
5775
|
+
}
|
|
5776
|
+
function registerColumn(columns, propertyKey, options) {
|
|
5834
5777
|
columns.set(propertyKey, {
|
|
5835
5778
|
columnName: options.columnName,
|
|
5836
|
-
typeCast:
|
|
5837
|
-
serialize:
|
|
5779
|
+
typeCast: options.typeCast,
|
|
5780
|
+
serialize: options.serialize,
|
|
5838
5781
|
primaryKey: options.primaryKey,
|
|
5839
5782
|
autoIncrement: options.autoIncrement,
|
|
5840
|
-
sqlCast:
|
|
5841
|
-
...baseSqlType !== void 0 ? { baseSqlType } : {}
|
|
5783
|
+
sqlCast: options.sqlCast,
|
|
5784
|
+
...options.baseSqlType !== void 0 ? { baseSqlType: options.baseSqlType } : {}
|
|
5842
5785
|
});
|
|
5843
|
-
Reflect.defineMetadata(COLUMNS_KEY, columns, constructor);
|
|
5844
5786
|
}
|
|
5845
|
-
function
|
|
5787
|
+
function parseColumnOptions(columnNameOrOptions, propKey) {
|
|
5788
|
+
if (typeof columnNameOrOptions === "string") return { columnName: columnNameOrOptions };
|
|
5789
|
+
if (columnNameOrOptions) {
|
|
5790
|
+
return {
|
|
5791
|
+
columnName: columnNameOrOptions.columnName || propKey,
|
|
5792
|
+
primaryKey: columnNameOrOptions.primaryKey,
|
|
5793
|
+
autoIncrement: columnNameOrOptions.autoIncrement
|
|
5794
|
+
};
|
|
5795
|
+
}
|
|
5796
|
+
return { columnName: propKey };
|
|
5797
|
+
}
|
|
5798
|
+
function rejectNonText(family, val) {
|
|
5799
|
+
if (val === null || val === void 0) return null;
|
|
5800
|
+
if (val instanceof Date) {
|
|
5801
|
+
throw new Error(
|
|
5802
|
+
`litedbmodel: @column.${family}() received a Date. A text column cannot serialize one \u2014 the driver would store an object literal. Use @column.datetime() / @column.date() for a date column, or format the value yourself.`
|
|
5803
|
+
);
|
|
5804
|
+
}
|
|
5805
|
+
if (typeof val === "object") {
|
|
5806
|
+
throw new Error(
|
|
5807
|
+
`litedbmodel: @column.${family}() received an object. Use @column.json<T>() for a JSON column, or @column.custom() with a serializer.`
|
|
5808
|
+
);
|
|
5809
|
+
}
|
|
5810
|
+
return val;
|
|
5811
|
+
}
|
|
5812
|
+
function materializeString(family, v) {
|
|
5813
|
+
if (v === void 0 || v === null) return v;
|
|
5814
|
+
if (typeof v === "string") return v;
|
|
5815
|
+
if (typeof v === "number" || typeof v === "bigint" || typeof v === "boolean") return String(v);
|
|
5816
|
+
throw new Error(
|
|
5817
|
+
`materialize ${family}: driver returned ${typeof v} for a ${family} column. Use @column.passthrough() for a BYTEA/BLOB column, or @column.json<T>() for JSON.`
|
|
5818
|
+
);
|
|
5819
|
+
}
|
|
5820
|
+
function createColumnDecorator(typeCast, serialize, sqlCast, baseSqlType) {
|
|
5846
5821
|
return function(columnNameOrOptions) {
|
|
5847
|
-
return function(
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
} else {
|
|
5860
|
-
columnName = propKey;
|
|
5822
|
+
return function(targetOrValue, keyOrContext) {
|
|
5823
|
+
if (isStandardContext(keyOrContext)) {
|
|
5824
|
+
const propKey2 = String(keyOrContext.name);
|
|
5825
|
+
const parsed2 = parseColumnOptions(columnNameOrOptions, propKey2);
|
|
5826
|
+
registerColumn(standardColumnMap(classMetadataBag(keyOrContext, propKey2)), propKey2, {
|
|
5827
|
+
...parsed2,
|
|
5828
|
+
typeCast,
|
|
5829
|
+
serialize,
|
|
5830
|
+
sqlCast,
|
|
5831
|
+
baseSqlType
|
|
5832
|
+
});
|
|
5833
|
+
return;
|
|
5861
5834
|
}
|
|
5862
|
-
|
|
5863
|
-
|
|
5835
|
+
const propKey = String(keyOrContext);
|
|
5836
|
+
const parsed = parseColumnOptions(columnNameOrOptions, propKey);
|
|
5837
|
+
registerColumn(legacyColumnMap(targetOrValue.constructor), propKey, {
|
|
5838
|
+
...parsed,
|
|
5864
5839
|
typeCast,
|
|
5865
5840
|
serialize,
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
autoIncrement,
|
|
5869
|
-
sqlCast
|
|
5841
|
+
sqlCast,
|
|
5842
|
+
baseSqlType
|
|
5870
5843
|
});
|
|
5871
5844
|
};
|
|
5872
5845
|
};
|
|
5873
5846
|
}
|
|
5847
|
+
function requireColumnFamily() {
|
|
5848
|
+
throw new Error(
|
|
5849
|
+
"litedbmodel: `@column()` no longer declares a column \u2014 a column must state its type with a family: @column.text() / .decimal() / .number() / .boolean() / .bigint() / .datetime() / .date() / .uuid() / .json() / .stringArray() / .intArray() / .numericArray() / .booleanArray() / .datetimeArray() / .passthrough() / .custom(). Every family takes the same argument as `@column()` did (`@column.text('db_name')`, `@column.number({ primaryKey: true })`). The bare form inferred the type from `emitDecoratorMetadata`, which esbuild (tsx/vite/vitest) never emits and standard decorators do not have, so it silently produced untyped reads."
|
|
5850
|
+
);
|
|
5851
|
+
}
|
|
5874
5852
|
function serializeArray(val, typeCast) {
|
|
5875
5853
|
if (val === null || val === void 0) return null;
|
|
5876
5854
|
if (!Array.isArray(val)) return val;
|
|
@@ -5908,19 +5886,47 @@ function serializeJson(val, typeCast) {
|
|
|
5908
5886
|
return JSON.stringify(val);
|
|
5909
5887
|
}
|
|
5910
5888
|
var column = Object.assign(
|
|
5911
|
-
//
|
|
5912
|
-
|
|
5889
|
+
// The bare `@column()` declared no type — it is rejected, with the migration in the message.
|
|
5890
|
+
(_columnNameOrOptions) => requireColumnFamily(),
|
|
5913
5891
|
{
|
|
5914
5892
|
// ============================================
|
|
5915
5893
|
// Primitive Types
|
|
5916
5894
|
// ============================================
|
|
5895
|
+
/**
|
|
5896
|
+
* Text type (TEXT / VARCHAR / CHAR / ENUM / citext) — the driver value is already a string, so no
|
|
5897
|
+
* cast is applied. The family still DECLARES the column so the typed read types it as `TEXT`.
|
|
5898
|
+
* @example @column.text() name?: string;
|
|
5899
|
+
* @example @column.text('user_name') name?: string;
|
|
5900
|
+
*/
|
|
5901
|
+
text: (columnNameOrOptions) => createColumnDecorator(
|
|
5902
|
+
(v) => materializeString("text", v),
|
|
5903
|
+
// the family DECLARES `string`, so it hands back one
|
|
5904
|
+
(val) => rejectNonText("text", val),
|
|
5905
|
+
// …and it cannot SERIALIZE a Date or an object
|
|
5906
|
+
void 0,
|
|
5907
|
+
// no sqlCast family (a text literal needs no SQL cast)
|
|
5908
|
+
"TEXT"
|
|
5909
|
+
// §4.1 token: types the SCP typed read
|
|
5910
|
+
)(columnNameOrOptions),
|
|
5911
|
+
/**
|
|
5912
|
+
* Exact decimal type (NUMERIC / DECIMAL) — read back as its exact decimal STRING (a JS number
|
|
5913
|
+
* rounds past 2^53). The family states the column is `numeric`, so a write binds the string as a
|
|
5914
|
+
* numeric — a batch write (`createMany` / `updateMany`) included.
|
|
5915
|
+
* @example @column.decimal() price?: string;
|
|
5916
|
+
*/
|
|
5917
|
+
decimal: (columnNameOrOptions) => createColumnDecorator(
|
|
5918
|
+
(v) => materializeString("decimal", v),
|
|
5919
|
+
(val) => rejectNonText("decimal", val),
|
|
5920
|
+
"numeric"
|
|
5921
|
+
// sqlCast for WHERE / INSERT / batch-write type casting
|
|
5922
|
+
)(columnNameOrOptions),
|
|
5917
5923
|
/**
|
|
5918
5924
|
* Boolean type conversion
|
|
5919
5925
|
* Converts 't'/'f', 'true'/'false', 1/0 to boolean
|
|
5920
5926
|
* Preserves null for nullable columns, undefined stays undefined
|
|
5921
5927
|
* @example @column.boolean() is_active?: boolean;
|
|
5922
5928
|
*/
|
|
5923
|
-
boolean: (
|
|
5929
|
+
boolean: (columnNameOrOptions) => createColumnDecorator(
|
|
5924
5930
|
// v2 read contract: BOOLEAN → boolean, via the shared materializer (issue #9).
|
|
5925
5931
|
(v) => {
|
|
5926
5932
|
if (v === void 0) return void 0;
|
|
@@ -5928,42 +5934,38 @@ var column = Object.assign(
|
|
|
5928
5934
|
},
|
|
5929
5935
|
void 0,
|
|
5930
5936
|
// no custom serialize
|
|
5931
|
-
false,
|
|
5932
|
-
// allow auto-inference
|
|
5933
5937
|
"boolean"
|
|
5934
5938
|
// sqlCast for updateMany type inference
|
|
5935
|
-
)(
|
|
5939
|
+
)(columnNameOrOptions),
|
|
5936
5940
|
/**
|
|
5937
5941
|
* Number type conversion (from string)
|
|
5938
5942
|
* Preserves null for nullable columns, undefined stays undefined
|
|
5939
5943
|
* @example @column.number() amount?: number;
|
|
5940
5944
|
*/
|
|
5941
|
-
number: (
|
|
5945
|
+
number: (columnNameOrOptions) => createColumnDecorator((v) => {
|
|
5942
5946
|
if (v === void 0) return void 0;
|
|
5943
5947
|
if (v === null) return null;
|
|
5944
5948
|
const n = Number(v);
|
|
5945
5949
|
return isNaN(n) ? null : n;
|
|
5946
|
-
})(
|
|
5950
|
+
})(columnNameOrOptions),
|
|
5947
5951
|
/**
|
|
5948
5952
|
* BigInt type conversion
|
|
5949
5953
|
* Preserves null for nullable columns, undefined stays undefined
|
|
5950
|
-
* @example @column.bigint() large_id?: bigint;
|
|
5954
|
+
* @example @column.bigint() large_id?: bigint; // bc `int` — a JS bigint, checked i64
|
|
5951
5955
|
*/
|
|
5952
|
-
bigint: (
|
|
5953
|
-
//
|
|
5954
|
-
//
|
|
5955
|
-
//
|
|
5956
|
+
bigint: (columnNameOrOptions) => createColumnDecorator(
|
|
5957
|
+
// An integer column reads back as a JS `bigint` — behavior-contracts' `int` value model
|
|
5958
|
+
// (`int` = bigint, checked i64), which is what the drivers already hand over. `JSON.stringify`
|
|
5959
|
+
// does not serialize a bigint: give the field a `toJSON`, or convert at the boundary.
|
|
5956
5960
|
(v) => {
|
|
5957
5961
|
if (v === void 0) return void 0;
|
|
5958
|
-
return materializeCell(v, "
|
|
5962
|
+
return materializeCell(v, "int");
|
|
5959
5963
|
},
|
|
5960
5964
|
void 0,
|
|
5961
5965
|
// no custom serialize
|
|
5962
|
-
false,
|
|
5963
|
-
// allow auto-inference
|
|
5964
5966
|
"bigint"
|
|
5965
5967
|
// sqlCast for WHERE/INSERT type casting
|
|
5966
|
-
)(
|
|
5968
|
+
)(columnNameOrOptions),
|
|
5967
5969
|
// ============================================
|
|
5968
5970
|
// Date/Time Types
|
|
5969
5971
|
// ============================================
|
|
@@ -5975,9 +5977,9 @@ var column = Object.assign(
|
|
|
5975
5977
|
* - PostgreSQL: Serializes to ISO 8601 UTC string with 'Z' suffix for explicit timezone
|
|
5976
5978
|
* - MySQL/SQLite: Passes Date object to driver (driver-dependent timezone handling)
|
|
5977
5979
|
*
|
|
5978
|
-
* @example @column.datetime() created_at?: Date
|
|
5980
|
+
* @example @column.datetime() created_at?: string; // TZ-attached string, NOT a JS Date
|
|
5979
5981
|
*/
|
|
5980
|
-
datetime: (
|
|
5982
|
+
datetime: (columnNameOrOptions) => createColumnDecorator(
|
|
5981
5983
|
// v2 read contract: DATE/TIMESTAMP/TIMESTAMPTZ/DATETIME/TIME → TZ-attached STRING (NOT a
|
|
5982
5984
|
// TZ-shifted JS Date), via the shared materializer (issue #9). A driver already returning the
|
|
5983
5985
|
// native textual form passes through; a JS Date is rendered to its lossless ISO instant.
|
|
@@ -5993,11 +5995,9 @@ var column = Object.assign(
|
|
|
5993
5995
|
}
|
|
5994
5996
|
return val;
|
|
5995
5997
|
},
|
|
5996
|
-
false,
|
|
5997
|
-
// allow auto-inference
|
|
5998
5998
|
"timestamp"
|
|
5999
5999
|
// sqlCast for updateMany type inference
|
|
6000
|
-
)(
|
|
6000
|
+
)(columnNameOrOptions),
|
|
6001
6001
|
/**
|
|
6002
6002
|
* Date type conversion — returns YYYY-MM-DD string.
|
|
6003
6003
|
* Preserves null for nullable columns, undefined stays undefined.
|
|
@@ -6005,9 +6005,9 @@ var column = Object.assign(
|
|
|
6005
6005
|
* DB values (Date object or string) are normalized to 'YYYY-MM-DD' string.
|
|
6006
6006
|
* On write, string values are passed through; Date objects are formatted as 'YYYY-MM-DD'.
|
|
6007
6007
|
*
|
|
6008
|
-
* @example @column.date() birth_date?: string;
|
|
6008
|
+
* @example @column.date() birth_date?: string; // 'YYYY-MM-DD'
|
|
6009
6009
|
*/
|
|
6010
|
-
date: (
|
|
6010
|
+
date: (columnNameOrOptions) => createColumnDecorator(
|
|
6011
6011
|
(v) => {
|
|
6012
6012
|
if (v === void 0) return void 0;
|
|
6013
6013
|
if (v === null) return null;
|
|
@@ -6032,11 +6032,9 @@ var column = Object.assign(
|
|
|
6032
6032
|
}
|
|
6033
6033
|
return val;
|
|
6034
6034
|
},
|
|
6035
|
-
false,
|
|
6036
|
-
// allow auto-inference
|
|
6037
6035
|
"date"
|
|
6038
6036
|
// sqlCast for updateMany type inference
|
|
6039
|
-
)(
|
|
6037
|
+
)(columnNameOrOptions),
|
|
6040
6038
|
// ============================================
|
|
6041
6039
|
// Array Types
|
|
6042
6040
|
// ============================================
|
|
@@ -6045,71 +6043,71 @@ var column = Object.assign(
|
|
|
6045
6043
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6046
6044
|
* @example @column.stringArray() tags?: string[];
|
|
6047
6045
|
*/
|
|
6048
|
-
stringArray: (
|
|
6046
|
+
stringArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6049
6047
|
(v) => {
|
|
6050
6048
|
if (v === void 0) return void 0;
|
|
6051
6049
|
if (v === null) return null;
|
|
6052
6050
|
return castToStringArray(v);
|
|
6053
6051
|
},
|
|
6054
6052
|
serializeArray,
|
|
6055
|
-
false,
|
|
6056
6053
|
"text[]"
|
|
6057
|
-
)(
|
|
6054
|
+
)(columnNameOrOptions),
|
|
6058
6055
|
/**
|
|
6059
6056
|
* Integer array type conversion (integer[])
|
|
6060
6057
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6061
6058
|
* @example @column.intArray() scores?: number[];
|
|
6062
6059
|
*/
|
|
6063
|
-
intArray: (
|
|
6060
|
+
intArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6064
6061
|
(v) => {
|
|
6065
6062
|
if (v === void 0) return void 0;
|
|
6066
6063
|
if (v === null) return null;
|
|
6067
6064
|
return castToIntegerArray(v);
|
|
6068
6065
|
},
|
|
6069
6066
|
serializeArray,
|
|
6070
|
-
false,
|
|
6071
6067
|
"int[]"
|
|
6072
|
-
)(
|
|
6068
|
+
)(columnNameOrOptions),
|
|
6073
6069
|
/**
|
|
6074
6070
|
* Numeric array type conversion (numeric[], allows null elements)
|
|
6075
6071
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6076
6072
|
* @example @column.numericArray() values?: (number | null)[];
|
|
6077
6073
|
*/
|
|
6078
|
-
numericArray: (
|
|
6074
|
+
numericArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6079
6075
|
(v) => {
|
|
6080
6076
|
if (v === void 0) return void 0;
|
|
6081
6077
|
if (v === null) return null;
|
|
6082
6078
|
return castToNumericArray(v);
|
|
6083
6079
|
},
|
|
6084
6080
|
serializeArray,
|
|
6085
|
-
false,
|
|
6086
6081
|
"numeric[]"
|
|
6087
|
-
)(
|
|
6082
|
+
)(columnNameOrOptions),
|
|
6088
6083
|
/**
|
|
6089
6084
|
* Boolean array type conversion (boolean[])
|
|
6090
6085
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6091
6086
|
* @example @column.booleanArray() flags?: (boolean | null)[];
|
|
6092
6087
|
*/
|
|
6093
|
-
booleanArray: (
|
|
6088
|
+
booleanArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6094
6089
|
(v) => {
|
|
6095
6090
|
if (v === void 0) return void 0;
|
|
6096
6091
|
if (v === null) return null;
|
|
6097
6092
|
return castToBooleanArray(v);
|
|
6098
6093
|
},
|
|
6099
6094
|
serializeBooleanArray,
|
|
6100
|
-
false,
|
|
6101
6095
|
"boolean[]"
|
|
6102
|
-
)(
|
|
6096
|
+
)(columnNameOrOptions),
|
|
6103
6097
|
/**
|
|
6104
6098
|
* DateTime array type conversion (timestamp[])
|
|
6105
6099
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6106
|
-
* @example @column.datetimeArray() event_dates?: (
|
|
6100
|
+
* @example @column.datetimeArray() event_dates?: (string | null)[];
|
|
6107
6101
|
*/
|
|
6108
|
-
datetimeArray: (
|
|
6102
|
+
datetimeArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6103
|
+
// Element-wise the SAME contract as `@column.datetime()`: a TZ-attached STRING, never a
|
|
6104
|
+
// TZ-shifted JS Date. The array family used to be the one place a `Date` still came back, so
|
|
6105
|
+
// `JSON.stringify` of a row silently re-rendered those elements in UTC — the exact hazard #9
|
|
6106
|
+
// closed for the scalar.
|
|
6109
6107
|
(v) => {
|
|
6110
6108
|
if (v === void 0) return void 0;
|
|
6111
6109
|
if (v === null) return null;
|
|
6112
|
-
return castToDatetimeArray(v);
|
|
6110
|
+
return castToDatetimeArray(v).map((d) => d === null ? null : materializeCell(d, "date"));
|
|
6113
6111
|
},
|
|
6114
6112
|
// DateTime arrays serialize each Date to ISO string
|
|
6115
6113
|
(val) => {
|
|
@@ -6118,7 +6116,7 @@ var column = Object.assign(
|
|
|
6118
6116
|
const mapped = val.map((v) => v === null ? "NULL" : v instanceof Date ? v.toISOString() : String(v));
|
|
6119
6117
|
return `{${mapped.join(",")}}`;
|
|
6120
6118
|
}
|
|
6121
|
-
)(
|
|
6119
|
+
)(columnNameOrOptions),
|
|
6122
6120
|
// ============================================
|
|
6123
6121
|
// JSON Types
|
|
6124
6122
|
// ============================================
|
|
@@ -6128,16 +6126,15 @@ var column = Object.assign(
|
|
|
6128
6126
|
* @example @column.json() metadata?: Record<string, unknown>;
|
|
6129
6127
|
* @example @column.json<UserSettings>() settings?: UserSettings;
|
|
6130
6128
|
*/
|
|
6131
|
-
json: (
|
|
6129
|
+
json: (columnNameOrOptions) => createColumnDecorator(
|
|
6132
6130
|
(v) => {
|
|
6133
6131
|
if (v === void 0) return void 0;
|
|
6134
6132
|
if (v === null) return null;
|
|
6135
|
-
return
|
|
6133
|
+
return castToJson2(v);
|
|
6136
6134
|
},
|
|
6137
6135
|
serializeJson,
|
|
6138
|
-
false,
|
|
6139
6136
|
"jsonb"
|
|
6140
|
-
)(
|
|
6137
|
+
)(columnNameOrOptions),
|
|
6141
6138
|
// ============================================
|
|
6142
6139
|
// UUID Type (PostgreSQL)
|
|
6143
6140
|
// ============================================
|
|
@@ -6166,22 +6163,28 @@ var column = Object.assign(
|
|
|
6166
6163
|
if (v === null) return null;
|
|
6167
6164
|
return String(v);
|
|
6168
6165
|
},
|
|
6169
|
-
|
|
6170
|
-
//
|
|
6171
|
-
true,
|
|
6172
|
-
// Skip auto-inference
|
|
6166
|
+
(val) => rejectNonText("uuid", val),
|
|
6167
|
+
// the ::uuid cast handles the rest
|
|
6173
6168
|
"uuid"
|
|
6174
6169
|
// SQL type for casting
|
|
6175
6170
|
)(columnNameOrOptions),
|
|
6176
6171
|
// ============================================
|
|
6177
6172
|
// Custom Type Conversion
|
|
6178
6173
|
// ============================================
|
|
6174
|
+
/**
|
|
6175
|
+
* The driver's value, UNCAST — for a column whose type the library has no cast for (`BYTEA` /
|
|
6176
|
+
* `BLOB` arrives as a driver Buffer, a vendor type as whatever the driver decodes). It states
|
|
6177
|
+
* "this column is passed through", which is a DECLARATION; the removed bare `@column()` was the
|
|
6178
|
+
* absence of one, and produced this same passthrough by accident for every unresolvable type.
|
|
6179
|
+
* @example @column.passthrough() payload?: unknown;
|
|
6180
|
+
*/
|
|
6181
|
+
passthrough: (columnNameOrOptions) => createColumnDecorator()(columnNameOrOptions),
|
|
6179
6182
|
/**
|
|
6180
6183
|
* Custom type conversion with user-provided function
|
|
6181
6184
|
* @example @column.custom((v) => String(v).toUpperCase()) status?: string;
|
|
6182
6185
|
* @example @column.custom((v) => v, (v) => JSON.stringify(v)) data?: MyType; // with serializer
|
|
6183
6186
|
*/
|
|
6184
|
-
custom: (castFn, serializeFn,
|
|
6187
|
+
custom: (castFn, serializeFn, columnNameOrOptions) => createColumnDecorator(castFn, serializeFn)(columnNameOrOptions)
|
|
6185
6188
|
}
|
|
6186
6189
|
);
|
|
6187
6190
|
function getRelationMeta(modelClass) {
|
|
@@ -6225,6 +6228,7 @@ function getPrimaryKey(modelClass) {
|
|
|
6225
6228
|
// src/scp/decorator-adapter.ts
|
|
6226
6229
|
var COLUMN_FAMILY_SQL_TYPE = {
|
|
6227
6230
|
boolean: "BOOLEAN",
|
|
6231
|
+
numeric: "NUMERIC",
|
|
6228
6232
|
bigint: "BIGINT",
|
|
6229
6233
|
timestamp: "TIMESTAMP",
|
|
6230
6234
|
date: "DATE",
|