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.cjs
CHANGED
|
@@ -2230,12 +2230,14 @@ function tupleInPredicate(dialect, table, columns, pgElementTypes) {
|
|
|
2230
2230
|
function encodeJsonArrayParam(dialect, values) {
|
|
2231
2231
|
return encodeJsonParam(dialect, values);
|
|
2232
2232
|
}
|
|
2233
|
+
var BIGINT_SENTINEL = "\0int:";
|
|
2233
2234
|
function encodeJsonParam(dialect, payload) {
|
|
2234
|
-
|
|
2235
|
-
if (typeof v === "bigint") return
|
|
2235
|
+
const tagged = JSON.stringify(payload, (_key, v) => {
|
|
2236
|
+
if (typeof v === "bigint") return `${BIGINT_SENTINEL}${v.toString()}`;
|
|
2236
2237
|
if (dialect === "mysql" && typeof v === "boolean") return v ? 1 : 0;
|
|
2237
2238
|
return v;
|
|
2238
2239
|
});
|
|
2240
|
+
return tagged.replace(/"\\u0000int:(-?\d+)"/g, "$1");
|
|
2239
2241
|
}
|
|
2240
2242
|
var JsonArrayConditions = class extends DBConditions {
|
|
2241
2243
|
_dialect;
|
|
@@ -2282,6 +2284,11 @@ function andTrailing(head, tails) {
|
|
|
2282
2284
|
return [head, ...guardedTails];
|
|
2283
2285
|
}
|
|
2284
2286
|
|
|
2287
|
+
// src/drivers/PostgresHelper.ts
|
|
2288
|
+
function castToJson(val) {
|
|
2289
|
+
return val ?? null;
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2285
2292
|
// src/TypeCast.ts
|
|
2286
2293
|
var defaultTypeCast = {
|
|
2287
2294
|
castToDatetime(val) {
|
|
@@ -2406,17 +2413,15 @@ var defaultTypeCast = {
|
|
|
2406
2413
|
}
|
|
2407
2414
|
return [];
|
|
2408
2415
|
},
|
|
2416
|
+
// A string is JSON text to decode; any other value is already a JSON value
|
|
2409
2417
|
castToJson(val) {
|
|
2410
2418
|
if (val === null || val === void 0) return null;
|
|
2411
|
-
if (typeof val
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
return null;
|
|
2417
|
-
}
|
|
2419
|
+
if (typeof val !== "string") return val;
|
|
2420
|
+
try {
|
|
2421
|
+
return JSON.parse(val);
|
|
2422
|
+
} catch {
|
|
2423
|
+
return null;
|
|
2418
2424
|
}
|
|
2419
|
-
return null;
|
|
2420
2425
|
}
|
|
2421
2426
|
};
|
|
2422
2427
|
function parsePostgresArray(literal) {
|
|
@@ -2473,7 +2478,7 @@ function castToBooleanArray(val) {
|
|
|
2473
2478
|
function castToDatetimeArray(val) {
|
|
2474
2479
|
return currentTypeCast.castToDatetimeArray(val);
|
|
2475
2480
|
}
|
|
2476
|
-
function
|
|
2481
|
+
function castToJson2(val) {
|
|
2477
2482
|
return currentTypeCast.castToJson(val);
|
|
2478
2483
|
}
|
|
2479
2484
|
function formatLocalDate(d) {
|
|
@@ -2517,16 +2522,7 @@ var postgresTypeCast = {
|
|
|
2517
2522
|
return JSON.stringify(val);
|
|
2518
2523
|
},
|
|
2519
2524
|
deserializeJson(val) {
|
|
2520
|
-
|
|
2521
|
-
if (typeof val === "object") return val;
|
|
2522
|
-
if (typeof val === "string") {
|
|
2523
|
-
try {
|
|
2524
|
-
return JSON.parse(val);
|
|
2525
|
-
} catch {
|
|
2526
|
-
return null;
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
return null;
|
|
2525
|
+
return castToJson(val);
|
|
2530
2526
|
},
|
|
2531
2527
|
serializeBooleanArray(val) {
|
|
2532
2528
|
if (val === null || val === void 0) return null;
|
|
@@ -2830,6 +2826,11 @@ var postgresSqlBuilder = {
|
|
|
2830
2826
|
inferPgType
|
|
2831
2827
|
};
|
|
2832
2828
|
|
|
2829
|
+
// src/drivers/MysqlHelper.ts
|
|
2830
|
+
function castToJson3(val) {
|
|
2831
|
+
return val ?? null;
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2833
2834
|
// src/drivers/MysqlSqlBuilder.ts
|
|
2834
2835
|
var mysqlTypeCast = {
|
|
2835
2836
|
driverName: "mysql",
|
|
@@ -2855,16 +2856,7 @@ var mysqlTypeCast = {
|
|
|
2855
2856
|
return JSON.stringify(val);
|
|
2856
2857
|
},
|
|
2857
2858
|
deserializeJson(val) {
|
|
2858
|
-
|
|
2859
|
-
if (typeof val === "object") return val;
|
|
2860
|
-
if (typeof val === "string") {
|
|
2861
|
-
try {
|
|
2862
|
-
return JSON.parse(val);
|
|
2863
|
-
} catch {
|
|
2864
|
-
return null;
|
|
2865
|
-
}
|
|
2866
|
-
}
|
|
2867
|
-
return null;
|
|
2859
|
+
return castToJson3(val);
|
|
2868
2860
|
},
|
|
2869
2861
|
serializeBooleanArray(val) {
|
|
2870
2862
|
if (val === null || val === void 0) return null;
|
|
@@ -3032,6 +3024,24 @@ var mysqlSqlBuilder = {
|
|
|
3032
3024
|
}
|
|
3033
3025
|
};
|
|
3034
3026
|
|
|
3027
|
+
// src/drivers/SqliteHelper.ts
|
|
3028
|
+
function castToJson4(val) {
|
|
3029
|
+
if (val === null || val === void 0) {
|
|
3030
|
+
return null;
|
|
3031
|
+
}
|
|
3032
|
+
if (typeof val === "object" || typeof val === "number") {
|
|
3033
|
+
return val;
|
|
3034
|
+
}
|
|
3035
|
+
if (typeof val === "string") {
|
|
3036
|
+
try {
|
|
3037
|
+
return JSON.parse(val);
|
|
3038
|
+
} catch {
|
|
3039
|
+
return null;
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
return null;
|
|
3043
|
+
}
|
|
3044
|
+
|
|
3035
3045
|
// src/drivers/SqliteSqlBuilder.ts
|
|
3036
3046
|
var sqliteTypeCast = {
|
|
3037
3047
|
driverName: "sqlite",
|
|
@@ -3057,16 +3067,7 @@ var sqliteTypeCast = {
|
|
|
3057
3067
|
return JSON.stringify(val);
|
|
3058
3068
|
},
|
|
3059
3069
|
deserializeJson(val) {
|
|
3060
|
-
|
|
3061
|
-
if (typeof val === "object") return val;
|
|
3062
|
-
if (typeof val === "string") {
|
|
3063
|
-
try {
|
|
3064
|
-
return JSON.parse(val);
|
|
3065
|
-
} catch {
|
|
3066
|
-
return null;
|
|
3067
|
-
}
|
|
3068
|
-
}
|
|
3069
|
-
return null;
|
|
3070
|
+
return castToJson4(val);
|
|
3070
3071
|
},
|
|
3071
3072
|
serializeBooleanArray(val) {
|
|
3072
3073
|
if (val === null || val === void 0) return null;
|
|
@@ -3941,8 +3942,8 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
3941
3942
|
return "passthrough";
|
|
3942
3943
|
}
|
|
3943
3944
|
switch (t) {
|
|
3944
|
-
//
|
|
3945
|
-
//
|
|
3945
|
+
// Integer family. The PostgreSQL SERIAL types are the same integers under an auto-increment
|
|
3946
|
+
// default (SERIAL/SERIAL4=int4, SMALLSERIAL/SERIAL2=int2, BIGSERIAL/SERIAL8=int8).
|
|
3946
3947
|
case "INTEGER":
|
|
3947
3948
|
case "INT":
|
|
3948
3949
|
case "SMALLINT":
|
|
@@ -3954,13 +3955,11 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
3954
3955
|
case "SERIAL4":
|
|
3955
3956
|
case "SMALLSERIAL":
|
|
3956
3957
|
case "SERIAL2":
|
|
3957
|
-
return "int32";
|
|
3958
|
-
// 64-bit int: needs JS bigint for exactness.
|
|
3959
3958
|
case "BIGINT":
|
|
3960
3959
|
case "INT8":
|
|
3961
3960
|
case "BIGSERIAL":
|
|
3962
3961
|
case "SERIAL8":
|
|
3963
|
-
return "
|
|
3962
|
+
return "int";
|
|
3964
3963
|
case "BOOLEAN":
|
|
3965
3964
|
case "BOOL":
|
|
3966
3965
|
return "bool";
|
|
@@ -3997,44 +3996,45 @@ function sqlTypeToMaterializeClass(sqlType) {
|
|
|
3997
3996
|
}
|
|
3998
3997
|
function keyArrayElemScalar(sqlType) {
|
|
3999
3998
|
switch (sqlTypeToMaterializeClass(sqlType)) {
|
|
4000
|
-
case "
|
|
4001
|
-
return "
|
|
4002
|
-
// materializes to a JS
|
|
4003
|
-
case "int64":
|
|
3999
|
+
case "int":
|
|
4000
|
+
return "int";
|
|
4001
|
+
// materializes to a JS bigint → bc int
|
|
4004
4002
|
case "date":
|
|
4005
4003
|
return "string";
|
|
4006
|
-
// materializes to a
|
|
4004
|
+
// materializes to a TZ string → bc string
|
|
4007
4005
|
case "bool":
|
|
4008
4006
|
return "bool";
|
|
4009
4007
|
case "passthrough":
|
|
4010
4008
|
return sqlTypeToBcScalar(sqlType) === "float" ? "float" : "string";
|
|
4011
4009
|
}
|
|
4012
4010
|
}
|
|
4011
|
+
var I64_MIN2 = -(2n ** 63n);
|
|
4012
|
+
var I64_MAX2 = 2n ** 63n - 1n;
|
|
4013
|
+
function checkI642(v) {
|
|
4014
|
+
if (v < I64_MIN2 || v > I64_MAX2) {
|
|
4015
|
+
throw new Error(`materialize int: ${v} is outside the i64 range behavior-contracts' \`int\` admits`);
|
|
4016
|
+
}
|
|
4017
|
+
return v;
|
|
4018
|
+
}
|
|
4013
4019
|
function materializeCell(value, klass) {
|
|
4014
4020
|
if (value === null || value === void 0) return value;
|
|
4015
4021
|
switch (klass) {
|
|
4016
|
-
case "
|
|
4017
|
-
if (typeof value === "bigint") return value
|
|
4022
|
+
case "int": {
|
|
4023
|
+
if (typeof value === "bigint") return checkI642(value);
|
|
4018
4024
|
if (typeof value === "string") {
|
|
4019
|
-
if (!/^-?\d+$/.test(value)) throw new Error(`materialize
|
|
4020
|
-
return value;
|
|
4025
|
+
if (!/^-?\d+$/.test(value)) throw new Error(`materialize int: driver returned a non-integer string '${value}'`);
|
|
4026
|
+
return checkI642(BigInt(value));
|
|
4021
4027
|
}
|
|
4022
4028
|
if (typeof value === "number") {
|
|
4023
|
-
if (!Number.isInteger(value)) throw new Error(`materialize
|
|
4029
|
+
if (!Number.isInteger(value)) throw new Error(`materialize int: driver returned a non-integer number ${value} for an integer column`);
|
|
4024
4030
|
if (!Number.isSafeInteger(value)) {
|
|
4025
4031
|
throw new Error(
|
|
4026
|
-
`materialize
|
|
4032
|
+
`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).`
|
|
4027
4033
|
);
|
|
4028
4034
|
}
|
|
4029
|
-
return value
|
|
4035
|
+
return BigInt(value);
|
|
4030
4036
|
}
|
|
4031
|
-
throw new Error(`materialize
|
|
4032
|
-
}
|
|
4033
|
-
case "int32": {
|
|
4034
|
-
if (typeof value === "number") return value;
|
|
4035
|
-
if (typeof value === "bigint") return Number(value);
|
|
4036
|
-
if (typeof value === "string" && /^-?\d+$/.test(value)) return Number(value);
|
|
4037
|
-
throw new Error(`materialize int32: unexpected driver JS type ${typeof value} (${String(value)})`);
|
|
4037
|
+
throw new Error(`materialize int: unexpected driver JS type ${typeof value}`);
|
|
4038
4038
|
}
|
|
4039
4039
|
case "date": {
|
|
4040
4040
|
if (typeof value === "string") return value;
|
|
@@ -5523,8 +5523,7 @@ function onConflictTail(dialect, ports, cols) {
|
|
|
5523
5523
|
}
|
|
5524
5524
|
function pgTypeSpecimen(sqlType) {
|
|
5525
5525
|
const klass = sqlTypeToMaterializeClass(sqlType);
|
|
5526
|
-
if (klass === "
|
|
5527
|
-
if (klass === "int64") return 0n;
|
|
5526
|
+
if (klass === "int") return 0n;
|
|
5528
5527
|
if (klass === "bool") return false;
|
|
5529
5528
|
if (klass === "date") return /* @__PURE__ */ new Date(0);
|
|
5530
5529
|
const scalar = sqlTypeToBcScalar(sqlType);
|
|
@@ -6156,10 +6155,6 @@ function materializeChildRows(rows, cols) {
|
|
|
6156
6155
|
row[key] = materializeCell(row[key], klass);
|
|
6157
6156
|
continue;
|
|
6158
6157
|
}
|
|
6159
|
-
if (typeof row[key] === "bigint") {
|
|
6160
|
-
const v = row[key];
|
|
6161
|
-
row[key] = v >= BigInt(Number.MIN_SAFE_INTEGER) && v <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(v) : v.toString();
|
|
6162
|
-
}
|
|
6163
6158
|
}
|
|
6164
6159
|
}
|
|
6165
6160
|
return rows;
|
|
@@ -6299,133 +6294,116 @@ function compileDeleteManyBundle(name, options, dialectName = "sqlite") {
|
|
|
6299
6294
|
var import_reflect_metadata = __toESM(require_Reflect());
|
|
6300
6295
|
var COLUMNS_KEY = /* @__PURE__ */ Symbol("litedbmodel:columns");
|
|
6301
6296
|
var RELATIONS_KEY = /* @__PURE__ */ Symbol("litedbmodel:relations");
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
return materializeCell(v, "date");
|
|
6320
|
-
},
|
|
6321
|
-
// Delegate to driver-specific serializeDatetime
|
|
6322
|
-
serialize: (val, typeCast) => {
|
|
6323
|
-
if (val === null || val === void 0) return null;
|
|
6324
|
-
if (val instanceof Date) {
|
|
6325
|
-
return typeCast?.serializeDatetime(val) ?? val;
|
|
6326
|
-
}
|
|
6327
|
-
return val;
|
|
6328
|
-
},
|
|
6329
|
-
sqlCast: "timestamp"
|
|
6330
|
-
};
|
|
6331
|
-
case Number:
|
|
6332
|
-
return {
|
|
6333
|
-
typeCast: (v) => {
|
|
6334
|
-
if (v === void 0) return void 0;
|
|
6335
|
-
if (v === null) return null;
|
|
6336
|
-
const n = Number(v);
|
|
6337
|
-
return isNaN(n) ? null : n;
|
|
6338
|
-
}
|
|
6339
|
-
};
|
|
6340
|
-
case BigInt:
|
|
6341
|
-
return {
|
|
6342
|
-
// v2 read contract: BIGINT/INT8 → EXACT decimal STRING (no i64 rounding, JSON-safe), via the
|
|
6343
|
-
// shared materializer. NOTE: the TS field type stays `bigint` in existing models for source
|
|
6344
|
-
// compat, but the VALUE is now the exact string — the whole point of the #9 realignment.
|
|
6345
|
-
typeCast: (v) => {
|
|
6346
|
-
if (v === void 0) return void 0;
|
|
6347
|
-
return materializeCell(v, "int64");
|
|
6348
|
-
},
|
|
6349
|
-
sqlCast: "bigint"
|
|
6350
|
-
};
|
|
6351
|
-
// Array, Object, String, and other types require explicit specification
|
|
6352
|
-
default:
|
|
6353
|
-
return void 0;
|
|
6354
|
-
}
|
|
6355
|
-
}
|
|
6356
|
-
function inferBaseSqlTypeFromDesignType(target, propertyKey) {
|
|
6357
|
-
const designType = Reflect.getMetadata("design:type", target, propertyKey);
|
|
6358
|
-
if (!designType) return void 0;
|
|
6359
|
-
switch (designType) {
|
|
6360
|
-
case String:
|
|
6361
|
-
return "TEXT";
|
|
6362
|
-
case Number:
|
|
6363
|
-
return "INTEGER";
|
|
6364
|
-
case Boolean:
|
|
6365
|
-
return "BOOLEAN";
|
|
6366
|
-
case Date:
|
|
6367
|
-
return "TIMESTAMP";
|
|
6368
|
-
case BigInt:
|
|
6369
|
-
return "BIGINT";
|
|
6370
|
-
default:
|
|
6371
|
-
return void 0;
|
|
6297
|
+
if (typeof Symbol === "function" && !Symbol.metadata) {
|
|
6298
|
+
Object.defineProperty(Symbol, "metadata", {
|
|
6299
|
+
value: /* @__PURE__ */ Symbol.for("Symbol.metadata"),
|
|
6300
|
+
writable: false,
|
|
6301
|
+
enumerable: false,
|
|
6302
|
+
configurable: true
|
|
6303
|
+
});
|
|
6304
|
+
}
|
|
6305
|
+
function isStandardContext(second) {
|
|
6306
|
+
return typeof second === "object" && second !== null && typeof second.kind === "string";
|
|
6307
|
+
}
|
|
6308
|
+
function classMetadataBag(context, propertyKey) {
|
|
6309
|
+
const bag = context.metadata;
|
|
6310
|
+
if (bag === void 0) {
|
|
6311
|
+
throw new Error(
|
|
6312
|
+
`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.`
|
|
6313
|
+
);
|
|
6372
6314
|
}
|
|
6315
|
+
return bag;
|
|
6373
6316
|
}
|
|
6374
|
-
function
|
|
6375
|
-
const
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
if (!finalSqlCast) finalSqlCast = inferred.sqlCast;
|
|
6386
|
-
}
|
|
6317
|
+
function legacyColumnMap(constructor) {
|
|
6318
|
+
const own = Reflect.getOwnMetadata(COLUMNS_KEY, constructor);
|
|
6319
|
+
if (own !== void 0) return own;
|
|
6320
|
+
const inherited = Reflect.getMetadata(COLUMNS_KEY, constructor);
|
|
6321
|
+
const map = new Map(inherited);
|
|
6322
|
+
Reflect.defineMetadata(COLUMNS_KEY, map, constructor);
|
|
6323
|
+
return map;
|
|
6324
|
+
}
|
|
6325
|
+
function standardColumnMap(bag) {
|
|
6326
|
+
if (!Object.prototype.hasOwnProperty.call(bag, COLUMNS_KEY)) {
|
|
6327
|
+
bag[COLUMNS_KEY] = new Map(bag[COLUMNS_KEY]);
|
|
6387
6328
|
}
|
|
6388
|
-
|
|
6329
|
+
return bag[COLUMNS_KEY];
|
|
6330
|
+
}
|
|
6331
|
+
function registerColumn(columns, propertyKey, options) {
|
|
6389
6332
|
columns.set(propertyKey, {
|
|
6390
6333
|
columnName: options.columnName,
|
|
6391
|
-
typeCast:
|
|
6392
|
-
serialize:
|
|
6334
|
+
typeCast: options.typeCast,
|
|
6335
|
+
serialize: options.serialize,
|
|
6393
6336
|
primaryKey: options.primaryKey,
|
|
6394
6337
|
autoIncrement: options.autoIncrement,
|
|
6395
|
-
sqlCast:
|
|
6396
|
-
...baseSqlType !== void 0 ? { baseSqlType } : {}
|
|
6338
|
+
sqlCast: options.sqlCast,
|
|
6339
|
+
...options.baseSqlType !== void 0 ? { baseSqlType: options.baseSqlType } : {}
|
|
6397
6340
|
});
|
|
6398
|
-
Reflect.defineMetadata(COLUMNS_KEY, columns, constructor);
|
|
6399
6341
|
}
|
|
6400
|
-
function
|
|
6342
|
+
function parseColumnOptions(columnNameOrOptions, propKey) {
|
|
6343
|
+
if (typeof columnNameOrOptions === "string") return { columnName: columnNameOrOptions };
|
|
6344
|
+
if (columnNameOrOptions) {
|
|
6345
|
+
return {
|
|
6346
|
+
columnName: columnNameOrOptions.columnName || propKey,
|
|
6347
|
+
primaryKey: columnNameOrOptions.primaryKey,
|
|
6348
|
+
autoIncrement: columnNameOrOptions.autoIncrement
|
|
6349
|
+
};
|
|
6350
|
+
}
|
|
6351
|
+
return { columnName: propKey };
|
|
6352
|
+
}
|
|
6353
|
+
function rejectNonText(family, val) {
|
|
6354
|
+
if (val === null || val === void 0) return null;
|
|
6355
|
+
if (val instanceof Date) {
|
|
6356
|
+
throw new Error(
|
|
6357
|
+
`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.`
|
|
6358
|
+
);
|
|
6359
|
+
}
|
|
6360
|
+
if (typeof val === "object") {
|
|
6361
|
+
throw new Error(
|
|
6362
|
+
`litedbmodel: @column.${family}() received an object. Use @column.json<T>() for a JSON column, or @column.custom() with a serializer.`
|
|
6363
|
+
);
|
|
6364
|
+
}
|
|
6365
|
+
return val;
|
|
6366
|
+
}
|
|
6367
|
+
function materializeString(family, v) {
|
|
6368
|
+
if (v === void 0 || v === null) return v;
|
|
6369
|
+
if (typeof v === "string") return v;
|
|
6370
|
+
if (typeof v === "number" || typeof v === "bigint" || typeof v === "boolean") return String(v);
|
|
6371
|
+
throw new Error(
|
|
6372
|
+
`materialize ${family}: driver returned ${typeof v} for a ${family} column. Use @column.passthrough() for a BYTEA/BLOB column, or @column.json<T>() for JSON.`
|
|
6373
|
+
);
|
|
6374
|
+
}
|
|
6375
|
+
function createColumnDecorator(typeCast, serialize, sqlCast, baseSqlType) {
|
|
6401
6376
|
return function(columnNameOrOptions) {
|
|
6402
|
-
return function(
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
} else {
|
|
6415
|
-
columnName = propKey;
|
|
6377
|
+
return function(targetOrValue, keyOrContext) {
|
|
6378
|
+
if (isStandardContext(keyOrContext)) {
|
|
6379
|
+
const propKey2 = String(keyOrContext.name);
|
|
6380
|
+
const parsed2 = parseColumnOptions(columnNameOrOptions, propKey2);
|
|
6381
|
+
registerColumn(standardColumnMap(classMetadataBag(keyOrContext, propKey2)), propKey2, {
|
|
6382
|
+
...parsed2,
|
|
6383
|
+
typeCast,
|
|
6384
|
+
serialize,
|
|
6385
|
+
sqlCast,
|
|
6386
|
+
baseSqlType
|
|
6387
|
+
});
|
|
6388
|
+
return;
|
|
6416
6389
|
}
|
|
6417
|
-
|
|
6418
|
-
|
|
6390
|
+
const propKey = String(keyOrContext);
|
|
6391
|
+
const parsed = parseColumnOptions(columnNameOrOptions, propKey);
|
|
6392
|
+
registerColumn(legacyColumnMap(targetOrValue.constructor), propKey, {
|
|
6393
|
+
...parsed,
|
|
6419
6394
|
typeCast,
|
|
6420
6395
|
serialize,
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
autoIncrement,
|
|
6424
|
-
sqlCast
|
|
6396
|
+
sqlCast,
|
|
6397
|
+
baseSqlType
|
|
6425
6398
|
});
|
|
6426
6399
|
};
|
|
6427
6400
|
};
|
|
6428
6401
|
}
|
|
6402
|
+
function requireColumnFamily() {
|
|
6403
|
+
throw new Error(
|
|
6404
|
+
"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."
|
|
6405
|
+
);
|
|
6406
|
+
}
|
|
6429
6407
|
function serializeArray(val, typeCast) {
|
|
6430
6408
|
if (val === null || val === void 0) return null;
|
|
6431
6409
|
if (!Array.isArray(val)) return val;
|
|
@@ -6463,19 +6441,47 @@ function serializeJson(val, typeCast) {
|
|
|
6463
6441
|
return JSON.stringify(val);
|
|
6464
6442
|
}
|
|
6465
6443
|
var column = Object.assign(
|
|
6466
|
-
//
|
|
6467
|
-
|
|
6444
|
+
// The bare `@column()` declared no type — it is rejected, with the migration in the message.
|
|
6445
|
+
(_columnNameOrOptions) => requireColumnFamily(),
|
|
6468
6446
|
{
|
|
6469
6447
|
// ============================================
|
|
6470
6448
|
// Primitive Types
|
|
6471
6449
|
// ============================================
|
|
6450
|
+
/**
|
|
6451
|
+
* Text type (TEXT / VARCHAR / CHAR / ENUM / citext) — the driver value is already a string, so no
|
|
6452
|
+
* cast is applied. The family still DECLARES the column so the typed read types it as `TEXT`.
|
|
6453
|
+
* @example @column.text() name?: string;
|
|
6454
|
+
* @example @column.text('user_name') name?: string;
|
|
6455
|
+
*/
|
|
6456
|
+
text: (columnNameOrOptions) => createColumnDecorator(
|
|
6457
|
+
(v) => materializeString("text", v),
|
|
6458
|
+
// the family DECLARES `string`, so it hands back one
|
|
6459
|
+
(val) => rejectNonText("text", val),
|
|
6460
|
+
// …and it cannot SERIALIZE a Date or an object
|
|
6461
|
+
void 0,
|
|
6462
|
+
// no sqlCast family (a text literal needs no SQL cast)
|
|
6463
|
+
"TEXT"
|
|
6464
|
+
// §4.1 token: types the SCP typed read
|
|
6465
|
+
)(columnNameOrOptions),
|
|
6466
|
+
/**
|
|
6467
|
+
* Exact decimal type (NUMERIC / DECIMAL) — read back as its exact decimal STRING (a JS number
|
|
6468
|
+
* rounds past 2^53). The family states the column is `numeric`, so a write binds the string as a
|
|
6469
|
+
* numeric — a batch write (`createMany` / `updateMany`) included.
|
|
6470
|
+
* @example @column.decimal() price?: string;
|
|
6471
|
+
*/
|
|
6472
|
+
decimal: (columnNameOrOptions) => createColumnDecorator(
|
|
6473
|
+
(v) => materializeString("decimal", v),
|
|
6474
|
+
(val) => rejectNonText("decimal", val),
|
|
6475
|
+
"numeric"
|
|
6476
|
+
// sqlCast for WHERE / INSERT / batch-write type casting
|
|
6477
|
+
)(columnNameOrOptions),
|
|
6472
6478
|
/**
|
|
6473
6479
|
* Boolean type conversion
|
|
6474
6480
|
* Converts 't'/'f', 'true'/'false', 1/0 to boolean
|
|
6475
6481
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6476
6482
|
* @example @column.boolean() is_active?: boolean;
|
|
6477
6483
|
*/
|
|
6478
|
-
boolean: (
|
|
6484
|
+
boolean: (columnNameOrOptions) => createColumnDecorator(
|
|
6479
6485
|
// v2 read contract: BOOLEAN → boolean, via the shared materializer (issue #9).
|
|
6480
6486
|
(v) => {
|
|
6481
6487
|
if (v === void 0) return void 0;
|
|
@@ -6483,42 +6489,38 @@ var column = Object.assign(
|
|
|
6483
6489
|
},
|
|
6484
6490
|
void 0,
|
|
6485
6491
|
// no custom serialize
|
|
6486
|
-
false,
|
|
6487
|
-
// allow auto-inference
|
|
6488
6492
|
"boolean"
|
|
6489
6493
|
// sqlCast for updateMany type inference
|
|
6490
|
-
)(
|
|
6494
|
+
)(columnNameOrOptions),
|
|
6491
6495
|
/**
|
|
6492
6496
|
* Number type conversion (from string)
|
|
6493
6497
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6494
6498
|
* @example @column.number() amount?: number;
|
|
6495
6499
|
*/
|
|
6496
|
-
number: (
|
|
6500
|
+
number: (columnNameOrOptions) => createColumnDecorator((v) => {
|
|
6497
6501
|
if (v === void 0) return void 0;
|
|
6498
6502
|
if (v === null) return null;
|
|
6499
6503
|
const n = Number(v);
|
|
6500
6504
|
return isNaN(n) ? null : n;
|
|
6501
|
-
})(
|
|
6505
|
+
})(columnNameOrOptions),
|
|
6502
6506
|
/**
|
|
6503
6507
|
* BigInt type conversion
|
|
6504
6508
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6505
|
-
* @example @column.bigint() large_id?: bigint;
|
|
6509
|
+
* @example @column.bigint() large_id?: bigint; // bc `int` — a JS bigint, checked i64
|
|
6506
6510
|
*/
|
|
6507
|
-
bigint: (
|
|
6508
|
-
//
|
|
6509
|
-
//
|
|
6510
|
-
//
|
|
6511
|
+
bigint: (columnNameOrOptions) => createColumnDecorator(
|
|
6512
|
+
// An integer column reads back as a JS `bigint` — behavior-contracts' `int` value model
|
|
6513
|
+
// (`int` = bigint, checked i64), which is what the drivers already hand over. `JSON.stringify`
|
|
6514
|
+
// does not serialize a bigint: give the field a `toJSON`, or convert at the boundary.
|
|
6511
6515
|
(v) => {
|
|
6512
6516
|
if (v === void 0) return void 0;
|
|
6513
|
-
return materializeCell(v, "
|
|
6517
|
+
return materializeCell(v, "int");
|
|
6514
6518
|
},
|
|
6515
6519
|
void 0,
|
|
6516
6520
|
// no custom serialize
|
|
6517
|
-
false,
|
|
6518
|
-
// allow auto-inference
|
|
6519
6521
|
"bigint"
|
|
6520
6522
|
// sqlCast for WHERE/INSERT type casting
|
|
6521
|
-
)(
|
|
6523
|
+
)(columnNameOrOptions),
|
|
6522
6524
|
// ============================================
|
|
6523
6525
|
// Date/Time Types
|
|
6524
6526
|
// ============================================
|
|
@@ -6530,9 +6532,9 @@ var column = Object.assign(
|
|
|
6530
6532
|
* - PostgreSQL: Serializes to ISO 8601 UTC string with 'Z' suffix for explicit timezone
|
|
6531
6533
|
* - MySQL/SQLite: Passes Date object to driver (driver-dependent timezone handling)
|
|
6532
6534
|
*
|
|
6533
|
-
* @example @column.datetime() created_at?: Date
|
|
6535
|
+
* @example @column.datetime() created_at?: string; // TZ-attached string, NOT a JS Date
|
|
6534
6536
|
*/
|
|
6535
|
-
datetime: (
|
|
6537
|
+
datetime: (columnNameOrOptions) => createColumnDecorator(
|
|
6536
6538
|
// v2 read contract: DATE/TIMESTAMP/TIMESTAMPTZ/DATETIME/TIME → TZ-attached STRING (NOT a
|
|
6537
6539
|
// TZ-shifted JS Date), via the shared materializer (issue #9). A driver already returning the
|
|
6538
6540
|
// native textual form passes through; a JS Date is rendered to its lossless ISO instant.
|
|
@@ -6548,11 +6550,9 @@ var column = Object.assign(
|
|
|
6548
6550
|
}
|
|
6549
6551
|
return val;
|
|
6550
6552
|
},
|
|
6551
|
-
false,
|
|
6552
|
-
// allow auto-inference
|
|
6553
6553
|
"timestamp"
|
|
6554
6554
|
// sqlCast for updateMany type inference
|
|
6555
|
-
)(
|
|
6555
|
+
)(columnNameOrOptions),
|
|
6556
6556
|
/**
|
|
6557
6557
|
* Date type conversion — returns YYYY-MM-DD string.
|
|
6558
6558
|
* Preserves null for nullable columns, undefined stays undefined.
|
|
@@ -6560,9 +6560,9 @@ var column = Object.assign(
|
|
|
6560
6560
|
* DB values (Date object or string) are normalized to 'YYYY-MM-DD' string.
|
|
6561
6561
|
* On write, string values are passed through; Date objects are formatted as 'YYYY-MM-DD'.
|
|
6562
6562
|
*
|
|
6563
|
-
* @example @column.date() birth_date?: string;
|
|
6563
|
+
* @example @column.date() birth_date?: string; // 'YYYY-MM-DD'
|
|
6564
6564
|
*/
|
|
6565
|
-
date: (
|
|
6565
|
+
date: (columnNameOrOptions) => createColumnDecorator(
|
|
6566
6566
|
(v) => {
|
|
6567
6567
|
if (v === void 0) return void 0;
|
|
6568
6568
|
if (v === null) return null;
|
|
@@ -6587,11 +6587,9 @@ var column = Object.assign(
|
|
|
6587
6587
|
}
|
|
6588
6588
|
return val;
|
|
6589
6589
|
},
|
|
6590
|
-
false,
|
|
6591
|
-
// allow auto-inference
|
|
6592
6590
|
"date"
|
|
6593
6591
|
// sqlCast for updateMany type inference
|
|
6594
|
-
)(
|
|
6592
|
+
)(columnNameOrOptions),
|
|
6595
6593
|
// ============================================
|
|
6596
6594
|
// Array Types
|
|
6597
6595
|
// ============================================
|
|
@@ -6600,71 +6598,71 @@ var column = Object.assign(
|
|
|
6600
6598
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6601
6599
|
* @example @column.stringArray() tags?: string[];
|
|
6602
6600
|
*/
|
|
6603
|
-
stringArray: (
|
|
6601
|
+
stringArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6604
6602
|
(v) => {
|
|
6605
6603
|
if (v === void 0) return void 0;
|
|
6606
6604
|
if (v === null) return null;
|
|
6607
6605
|
return castToStringArray(v);
|
|
6608
6606
|
},
|
|
6609
6607
|
serializeArray,
|
|
6610
|
-
false,
|
|
6611
6608
|
"text[]"
|
|
6612
|
-
)(
|
|
6609
|
+
)(columnNameOrOptions),
|
|
6613
6610
|
/**
|
|
6614
6611
|
* Integer array type conversion (integer[])
|
|
6615
6612
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6616
6613
|
* @example @column.intArray() scores?: number[];
|
|
6617
6614
|
*/
|
|
6618
|
-
intArray: (
|
|
6615
|
+
intArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6619
6616
|
(v) => {
|
|
6620
6617
|
if (v === void 0) return void 0;
|
|
6621
6618
|
if (v === null) return null;
|
|
6622
6619
|
return castToIntegerArray(v);
|
|
6623
6620
|
},
|
|
6624
6621
|
serializeArray,
|
|
6625
|
-
false,
|
|
6626
6622
|
"int[]"
|
|
6627
|
-
)(
|
|
6623
|
+
)(columnNameOrOptions),
|
|
6628
6624
|
/**
|
|
6629
6625
|
* Numeric array type conversion (numeric[], allows null elements)
|
|
6630
6626
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6631
6627
|
* @example @column.numericArray() values?: (number | null)[];
|
|
6632
6628
|
*/
|
|
6633
|
-
numericArray: (
|
|
6629
|
+
numericArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6634
6630
|
(v) => {
|
|
6635
6631
|
if (v === void 0) return void 0;
|
|
6636
6632
|
if (v === null) return null;
|
|
6637
6633
|
return castToNumericArray(v);
|
|
6638
6634
|
},
|
|
6639
6635
|
serializeArray,
|
|
6640
|
-
false,
|
|
6641
6636
|
"numeric[]"
|
|
6642
|
-
)(
|
|
6637
|
+
)(columnNameOrOptions),
|
|
6643
6638
|
/**
|
|
6644
6639
|
* Boolean array type conversion (boolean[])
|
|
6645
6640
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6646
6641
|
* @example @column.booleanArray() flags?: (boolean | null)[];
|
|
6647
6642
|
*/
|
|
6648
|
-
booleanArray: (
|
|
6643
|
+
booleanArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6649
6644
|
(v) => {
|
|
6650
6645
|
if (v === void 0) return void 0;
|
|
6651
6646
|
if (v === null) return null;
|
|
6652
6647
|
return castToBooleanArray(v);
|
|
6653
6648
|
},
|
|
6654
6649
|
serializeBooleanArray,
|
|
6655
|
-
false,
|
|
6656
6650
|
"boolean[]"
|
|
6657
|
-
)(
|
|
6651
|
+
)(columnNameOrOptions),
|
|
6658
6652
|
/**
|
|
6659
6653
|
* DateTime array type conversion (timestamp[])
|
|
6660
6654
|
* Preserves null for nullable columns, undefined stays undefined
|
|
6661
|
-
* @example @column.datetimeArray() event_dates?: (
|
|
6655
|
+
* @example @column.datetimeArray() event_dates?: (string | null)[];
|
|
6662
6656
|
*/
|
|
6663
|
-
datetimeArray: (
|
|
6657
|
+
datetimeArray: (columnNameOrOptions) => createColumnDecorator(
|
|
6658
|
+
// Element-wise the SAME contract as `@column.datetime()`: a TZ-attached STRING, never a
|
|
6659
|
+
// TZ-shifted JS Date. The array family used to be the one place a `Date` still came back, so
|
|
6660
|
+
// `JSON.stringify` of a row silently re-rendered those elements in UTC — the exact hazard #9
|
|
6661
|
+
// closed for the scalar.
|
|
6664
6662
|
(v) => {
|
|
6665
6663
|
if (v === void 0) return void 0;
|
|
6666
6664
|
if (v === null) return null;
|
|
6667
|
-
return castToDatetimeArray(v);
|
|
6665
|
+
return castToDatetimeArray(v).map((d) => d === null ? null : materializeCell(d, "date"));
|
|
6668
6666
|
},
|
|
6669
6667
|
// DateTime arrays serialize each Date to ISO string
|
|
6670
6668
|
(val) => {
|
|
@@ -6673,7 +6671,7 @@ var column = Object.assign(
|
|
|
6673
6671
|
const mapped = val.map((v) => v === null ? "NULL" : v instanceof Date ? v.toISOString() : String(v));
|
|
6674
6672
|
return `{${mapped.join(",")}}`;
|
|
6675
6673
|
}
|
|
6676
|
-
)(
|
|
6674
|
+
)(columnNameOrOptions),
|
|
6677
6675
|
// ============================================
|
|
6678
6676
|
// JSON Types
|
|
6679
6677
|
// ============================================
|
|
@@ -6683,16 +6681,15 @@ var column = Object.assign(
|
|
|
6683
6681
|
* @example @column.json() metadata?: Record<string, unknown>;
|
|
6684
6682
|
* @example @column.json<UserSettings>() settings?: UserSettings;
|
|
6685
6683
|
*/
|
|
6686
|
-
json: (
|
|
6684
|
+
json: (columnNameOrOptions) => createColumnDecorator(
|
|
6687
6685
|
(v) => {
|
|
6688
6686
|
if (v === void 0) return void 0;
|
|
6689
6687
|
if (v === null) return null;
|
|
6690
|
-
return
|
|
6688
|
+
return castToJson2(v);
|
|
6691
6689
|
},
|
|
6692
6690
|
serializeJson,
|
|
6693
|
-
false,
|
|
6694
6691
|
"jsonb"
|
|
6695
|
-
)(
|
|
6692
|
+
)(columnNameOrOptions),
|
|
6696
6693
|
// ============================================
|
|
6697
6694
|
// UUID Type (PostgreSQL)
|
|
6698
6695
|
// ============================================
|
|
@@ -6721,22 +6718,28 @@ var column = Object.assign(
|
|
|
6721
6718
|
if (v === null) return null;
|
|
6722
6719
|
return String(v);
|
|
6723
6720
|
},
|
|
6724
|
-
|
|
6725
|
-
//
|
|
6726
|
-
true,
|
|
6727
|
-
// Skip auto-inference
|
|
6721
|
+
(val) => rejectNonText("uuid", val),
|
|
6722
|
+
// the ::uuid cast handles the rest
|
|
6728
6723
|
"uuid"
|
|
6729
6724
|
// SQL type for casting
|
|
6730
6725
|
)(columnNameOrOptions),
|
|
6731
6726
|
// ============================================
|
|
6732
6727
|
// Custom Type Conversion
|
|
6733
6728
|
// ============================================
|
|
6729
|
+
/**
|
|
6730
|
+
* The driver's value, UNCAST — for a column whose type the library has no cast for (`BYTEA` /
|
|
6731
|
+
* `BLOB` arrives as a driver Buffer, a vendor type as whatever the driver decodes). It states
|
|
6732
|
+
* "this column is passed through", which is a DECLARATION; the removed bare `@column()` was the
|
|
6733
|
+
* absence of one, and produced this same passthrough by accident for every unresolvable type.
|
|
6734
|
+
* @example @column.passthrough() payload?: unknown;
|
|
6735
|
+
*/
|
|
6736
|
+
passthrough: (columnNameOrOptions) => createColumnDecorator()(columnNameOrOptions),
|
|
6734
6737
|
/**
|
|
6735
6738
|
* Custom type conversion with user-provided function
|
|
6736
6739
|
* @example @column.custom((v) => String(v).toUpperCase()) status?: string;
|
|
6737
6740
|
* @example @column.custom((v) => v, (v) => JSON.stringify(v)) data?: MyType; // with serializer
|
|
6738
6741
|
*/
|
|
6739
|
-
custom: (castFn, serializeFn,
|
|
6742
|
+
custom: (castFn, serializeFn, columnNameOrOptions) => createColumnDecorator(castFn, serializeFn)(columnNameOrOptions)
|
|
6740
6743
|
}
|
|
6741
6744
|
);
|
|
6742
6745
|
function getRelationMeta(modelClass) {
|
|
@@ -6780,6 +6783,7 @@ function getPrimaryKey(modelClass) {
|
|
|
6780
6783
|
// src/scp/decorator-adapter.ts
|
|
6781
6784
|
var COLUMN_FAMILY_SQL_TYPE = {
|
|
6782
6785
|
boolean: "BOOLEAN",
|
|
6786
|
+
numeric: "NUMERIC",
|
|
6783
6787
|
bigint: "BIGINT",
|
|
6784
6788
|
timestamp: "TIMESTAMP",
|
|
6785
6789
|
date: "DATE",
|