bun-query-builder 0.2.43 → 0.2.44
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/dist/bin/cli.js +247 -91
- package/dist/column-types.d.ts +26 -0
- package/dist/drivers/sqlite.d.ts +11 -6
- package/dist/model.d.ts +4 -0
- package/dist/orm.d.ts +2 -0
- package/dist/src/browser.js +1 -1
- package/dist/src/index.js +247 -90
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -476,7 +476,7 @@ class BrowserModelQueryBuilder {
|
|
|
476
476
|
for (const where of this._wheres) {
|
|
477
477
|
if (where.operator === "=") {
|
|
478
478
|
params.append(where.column, String(where.value));
|
|
479
|
-
} else if (
|
|
479
|
+
} else if (where.operator === "in" && Array.isArray(where.value)) {
|
|
480
480
|
params.append(`${where.column}[]`, where.value.join(","));
|
|
481
481
|
} else if (where.operator === "is" && where.value === null) {
|
|
482
482
|
params.append(`filter[${where.column}][is]`, "null");
|
|
@@ -15793,6 +15793,31 @@ function createQueryBuilder(state) {
|
|
|
15793
15793
|
let built;
|
|
15794
15794
|
let sqlText = "";
|
|
15795
15795
|
const params = [];
|
|
15796
|
+
let noRows = false;
|
|
15797
|
+
const emptyInsertResult = () => isPostgres ? [] : { changes: 0, lastInsertRowid: 0 };
|
|
15798
|
+
const emptyReturningBuilder = () => {
|
|
15799
|
+
const noRow = async () => {
|
|
15800
|
+
return;
|
|
15801
|
+
};
|
|
15802
|
+
const noRowOrFail = async () => {
|
|
15803
|
+
throw new Error("Insert with RETURNING returned no rows");
|
|
15804
|
+
};
|
|
15805
|
+
return {
|
|
15806
|
+
where: () => emptyReturningBuilder(),
|
|
15807
|
+
andWhere: () => emptyReturningBuilder(),
|
|
15808
|
+
orWhere: () => emptyReturningBuilder(),
|
|
15809
|
+
orderBy: () => emptyReturningBuilder(),
|
|
15810
|
+
limit: () => emptyReturningBuilder(),
|
|
15811
|
+
offset: () => emptyReturningBuilder(),
|
|
15812
|
+
toSQL: () => makeExecutableQuery(null, ""),
|
|
15813
|
+
execute: async () => [],
|
|
15814
|
+
get: async () => [],
|
|
15815
|
+
first: noRow,
|
|
15816
|
+
executeTakeFirst: noRow,
|
|
15817
|
+
firstOrFail: noRowOrFail,
|
|
15818
|
+
executeTakeFirstOrThrow: noRowOrFail
|
|
15819
|
+
};
|
|
15820
|
+
};
|
|
15796
15821
|
const isPostgres = config5.dialect === "postgres";
|
|
15797
15822
|
const quoteId = isPostgres ? (id) => `"${String(id).replace(/"/g, '""')}"` : isMysqlLike(config5.dialect) ? (id) => `\`${String(id).replace(/`/g, "``")}\`` : (id) => `"${String(id).replace(/"/g, '""')}"`;
|
|
15798
15823
|
const getPlaceholder2 = isPostgres ? (index) => `$${index + 1}` : (_index) => "?";
|
|
@@ -15801,9 +15826,13 @@ function createQueryBuilder(state) {
|
|
|
15801
15826
|
const rows = Array.isArray(data) ? data : [data];
|
|
15802
15827
|
const rowCount = rows.length;
|
|
15803
15828
|
if (rowCount === 0) {
|
|
15804
|
-
|
|
15829
|
+
noRows = true;
|
|
15830
|
+
built = null;
|
|
15831
|
+
sqlText = "";
|
|
15832
|
+
params.length = 0;
|
|
15805
15833
|
return this;
|
|
15806
15834
|
}
|
|
15835
|
+
noRows = false;
|
|
15807
15836
|
const firstRow = rows[0];
|
|
15808
15837
|
const keys = Object.keys(firstRow);
|
|
15809
15838
|
const colCount = keys.length;
|
|
@@ -15857,6 +15886,8 @@ function createQueryBuilder(state) {
|
|
|
15857
15886
|
return this;
|
|
15858
15887
|
},
|
|
15859
15888
|
returning(...cols) {
|
|
15889
|
+
if (noRows)
|
|
15890
|
+
return emptyReturningBuilder();
|
|
15860
15891
|
const returningSql = `${sqlText} RETURNING ${cols.join(", ")}`;
|
|
15861
15892
|
const q = _sql.unsafe(returningSql, params);
|
|
15862
15893
|
const runFirst = async () => {
|
|
@@ -15890,11 +15921,15 @@ function createQueryBuilder(state) {
|
|
|
15890
15921
|
};
|
|
15891
15922
|
},
|
|
15892
15923
|
toSQL() {
|
|
15924
|
+
if (noRows)
|
|
15925
|
+
return makeExecutableQuery(null, "");
|
|
15893
15926
|
if (!built)
|
|
15894
15927
|
built = _sql.unsafe(sqlText, params);
|
|
15895
15928
|
return makeExecutableQuery(built, sqlText);
|
|
15896
15929
|
},
|
|
15897
15930
|
execute() {
|
|
15931
|
+
if (noRows)
|
|
15932
|
+
return Promise.resolve(emptyInsertResult());
|
|
15898
15933
|
const hooks = activeHooks();
|
|
15899
15934
|
const hasHooks = hooks && (hooks.onQueryStart || hooks.onQueryEnd || hooks.onQueryError || hooks.startSpan || hooks.beforeCreate || hooks.afterCreate || hasSlowQueryHook(hooks));
|
|
15900
15935
|
if (!hasHooks) {
|
|
@@ -15909,12 +15944,16 @@ function createQueryBuilder(state) {
|
|
|
15909
15944
|
return runWithHooks(built, "insert");
|
|
15910
15945
|
},
|
|
15911
15946
|
async executeTakeFirst() {
|
|
15947
|
+
if (noRows)
|
|
15948
|
+
return emptyInsertResult();
|
|
15912
15949
|
if (!built)
|
|
15913
15950
|
built = _sql.unsafe(sqlText, params);
|
|
15914
15951
|
const result = await runWithHooks(built, "insert");
|
|
15915
15952
|
return result;
|
|
15916
15953
|
},
|
|
15917
15954
|
async executeTakeFirstOrThrow() {
|
|
15955
|
+
if (noRows)
|
|
15956
|
+
throw new Error("Insert failed");
|
|
15918
15957
|
if (!built)
|
|
15919
15958
|
built = _sql.unsafe(sqlText, params);
|
|
15920
15959
|
const result = await runWithHooks(built, "insert");
|
|
@@ -15923,6 +15962,8 @@ function createQueryBuilder(state) {
|
|
|
15923
15962
|
return result;
|
|
15924
15963
|
},
|
|
15925
15964
|
returningAll() {
|
|
15965
|
+
if (noRows)
|
|
15966
|
+
return emptyReturningBuilder();
|
|
15926
15967
|
const returningSql = `${sqlText} RETURNING *`;
|
|
15927
15968
|
const q = _sql.unsafe(returningSql, params);
|
|
15928
15969
|
const runFirst = async () => {
|
|
@@ -16029,8 +16070,22 @@ function createQueryBuilder(state) {
|
|
|
16029
16070
|
built = _sql.unsafe(sqlText, params);
|
|
16030
16071
|
return this;
|
|
16031
16072
|
}
|
|
16032
|
-
if (
|
|
16073
|
+
if (isRawExpression(expr)) {
|
|
16074
|
+
sqlText = `${sqlText} ${getWhereKeyword()} ${expr.raw}`;
|
|
16075
|
+
built = _sql.unsafe(sqlText, params);
|
|
16076
|
+
return this;
|
|
16077
|
+
}
|
|
16078
|
+
if (isBoundSqlExpression(expr)) {
|
|
16079
|
+
const rendered = renderBoundSqlExpression(expr, params.length + 1);
|
|
16080
|
+
sqlText = `${sqlText} ${getWhereKeyword()} ${rendered.text}`;
|
|
16081
|
+
params.push(...rendered.parameters);
|
|
16082
|
+
built = _sql.unsafe(sqlText, params);
|
|
16083
|
+
return this;
|
|
16084
|
+
}
|
|
16085
|
+
if (expr && typeof expr === "object") {
|
|
16033
16086
|
const keys = Object.keys(expr);
|
|
16087
|
+
if (keys.length === 0)
|
|
16088
|
+
throw new TypeError("[query-builder] updateTable.where({}): an empty object is not a filter. Pass a condition, or drop the where() call if updating every row is intended.");
|
|
16034
16089
|
const len = keys.length;
|
|
16035
16090
|
const baseIdx = params.length;
|
|
16036
16091
|
const conditions = Array.from({ length: len });
|
|
@@ -16040,8 +16095,9 @@ function createQueryBuilder(state) {
|
|
|
16040
16095
|
}
|
|
16041
16096
|
sqlText = `${sqlText} ${getWhereKeyword()} ${conditions.join(" AND ")}`;
|
|
16042
16097
|
built = _sql.unsafe(sqlText, params);
|
|
16098
|
+
return this;
|
|
16043
16099
|
}
|
|
16044
|
-
|
|
16100
|
+
throw new TypeError(`[query-builder] updateTable.where(): expected a condition, got ${expr === null ? "null" : typeof expr}. Refusing to run an UPDATE with no WHERE \u2014 drop the where() call if updating every row is intended.`);
|
|
16045
16101
|
},
|
|
16046
16102
|
whereNull(column) {
|
|
16047
16103
|
const keyword = SQL_PATTERNS.WHERE.test(sqlText) ? "AND" : "WHERE";
|
|
@@ -16056,22 +16112,40 @@ function createQueryBuilder(state) {
|
|
|
16056
16112
|
return this;
|
|
16057
16113
|
},
|
|
16058
16114
|
returning(...cols) {
|
|
16059
|
-
const
|
|
16060
|
-
const
|
|
16115
|
+
const parent = this;
|
|
16116
|
+
const retText = () => `${sqlText} RETURNING ${cols.join(", ")}`;
|
|
16117
|
+
const build = () => params.length > 0 ? _sql.unsafe(retText(), params) : _sql.unsafe(retText());
|
|
16061
16118
|
const runFirst = async () => {
|
|
16062
|
-
const rows = await runWithHooks(
|
|
16119
|
+
const rows = await runWithHooks(build(), "update");
|
|
16063
16120
|
return Array.isArray(rows) ? rows[0] : rows;
|
|
16064
16121
|
};
|
|
16122
|
+
const unsupported = (name) => () => {
|
|
16123
|
+
throw new TypeError(`[query-builder] updateTable.returning(...).${name}() is not supported \u2014 an UPDATE cannot be ordered or limited through this builder. Apply the filter with where() instead.`);
|
|
16124
|
+
};
|
|
16065
16125
|
const obj = {
|
|
16066
|
-
where: () =>
|
|
16067
|
-
|
|
16068
|
-
|
|
16069
|
-
|
|
16070
|
-
|
|
16071
|
-
|
|
16072
|
-
|
|
16073
|
-
|
|
16074
|
-
|
|
16126
|
+
where: (...args) => {
|
|
16127
|
+
parent.where(...args);
|
|
16128
|
+
return obj;
|
|
16129
|
+
},
|
|
16130
|
+
andWhere: (...args) => {
|
|
16131
|
+
parent.where(...args);
|
|
16132
|
+
return obj;
|
|
16133
|
+
},
|
|
16134
|
+
whereNull: (...args) => {
|
|
16135
|
+
parent.whereNull(...args);
|
|
16136
|
+
return obj;
|
|
16137
|
+
},
|
|
16138
|
+
whereNotNull: (...args) => {
|
|
16139
|
+
parent.whereNotNull(...args);
|
|
16140
|
+
return obj;
|
|
16141
|
+
},
|
|
16142
|
+
orWhere: unsupported("orWhere"),
|
|
16143
|
+
orderBy: unsupported("orderBy"),
|
|
16144
|
+
limit: unsupported("limit"),
|
|
16145
|
+
offset: unsupported("offset"),
|
|
16146
|
+
toSQL: () => makeExecutableQuery(build(), retText()),
|
|
16147
|
+
execute: () => runWithHooks(build(), "update"),
|
|
16148
|
+
get: () => runWithHooks(build(), "update"),
|
|
16075
16149
|
first: runFirst,
|
|
16076
16150
|
executeTakeFirst: runFirst,
|
|
16077
16151
|
async firstOrFail() {
|
|
@@ -16110,17 +16184,17 @@ function createQueryBuilder(state) {
|
|
|
16110
16184
|
return { numUpdatedRows: result };
|
|
16111
16185
|
},
|
|
16112
16186
|
returningAll() {
|
|
16113
|
-
const retAllText = `${sqlText} RETURNING *`;
|
|
16114
|
-
const
|
|
16187
|
+
const retAllText = () => `${sqlText} RETURNING *`;
|
|
16188
|
+
const build = () => params.length > 0 ? _sql.unsafe(retAllText(), params) : _sql.unsafe(retAllText());
|
|
16115
16189
|
return {
|
|
16116
|
-
toSQL: () => makeExecutableQuery(
|
|
16117
|
-
execute: () => runWithHooks(
|
|
16190
|
+
toSQL: () => makeExecutableQuery(build(), retAllText()),
|
|
16191
|
+
execute: () => runWithHooks(build(), "update"),
|
|
16118
16192
|
async executeTakeFirst() {
|
|
16119
|
-
const result = await runWithHooks(
|
|
16193
|
+
const result = await runWithHooks(build(), "update");
|
|
16120
16194
|
return Array.isArray(result) ? result[0] : result;
|
|
16121
16195
|
},
|
|
16122
16196
|
async executeTakeFirstOrThrow() {
|
|
16123
|
-
const result = await runWithHooks(
|
|
16197
|
+
const result = await runWithHooks(build(), "update");
|
|
16124
16198
|
const first = Array.isArray(result) ? result[0] : result;
|
|
16125
16199
|
if (!first)
|
|
16126
16200
|
throw new Error("Update with RETURNING failed");
|
|
@@ -16185,8 +16259,22 @@ function createQueryBuilder(state) {
|
|
|
16185
16259
|
built = null;
|
|
16186
16260
|
return this;
|
|
16187
16261
|
}
|
|
16188
|
-
if (
|
|
16262
|
+
if (isRawExpression(expr)) {
|
|
16263
|
+
sqlText += ` ${getWhereKeyword()} ${expr.raw}`;
|
|
16264
|
+
built = null;
|
|
16265
|
+
return this;
|
|
16266
|
+
}
|
|
16267
|
+
if (isBoundSqlExpression(expr)) {
|
|
16268
|
+
const rendered = renderBoundSqlExpression(expr, delParams.length + 1);
|
|
16269
|
+
sqlText += ` ${getWhereKeyword()} ${rendered.text}`;
|
|
16270
|
+
delParams.push(...rendered.parameters);
|
|
16271
|
+
built = null;
|
|
16272
|
+
return this;
|
|
16273
|
+
}
|
|
16274
|
+
if (expr && typeof expr === "object") {
|
|
16189
16275
|
const keys = Object.keys(expr);
|
|
16276
|
+
if (keys.length === 0)
|
|
16277
|
+
throw new TypeError("[query-builder] deleteFrom.where({}): an empty object is not a filter. Pass a condition, or drop the where() call if deleting every row is intended.");
|
|
16190
16278
|
const conditions = [];
|
|
16191
16279
|
for (const key of keys) {
|
|
16192
16280
|
const paramIndex = delParams.length + 1;
|
|
@@ -16197,8 +16285,7 @@ function createQueryBuilder(state) {
|
|
|
16197
16285
|
built = null;
|
|
16198
16286
|
return this;
|
|
16199
16287
|
}
|
|
16200
|
-
|
|
16201
|
-
return this;
|
|
16288
|
+
throw new TypeError(`[query-builder] deleteFrom.where(): expected a condition, got ${expr === null ? "null" : typeof expr}. Refusing to run a DELETE with no WHERE \u2014 drop the where() call if deleting every row is intended.`);
|
|
16202
16289
|
},
|
|
16203
16290
|
whereNull(column) {
|
|
16204
16291
|
sqlText += ` ${getWhereKeyword()} ${quoteId(String(column))} IS NULL`;
|
|
@@ -16211,22 +16298,48 @@ function createQueryBuilder(state) {
|
|
|
16211
16298
|
return this;
|
|
16212
16299
|
},
|
|
16213
16300
|
returning(...cols) {
|
|
16214
|
-
const
|
|
16215
|
-
const
|
|
16301
|
+
const parent = this;
|
|
16302
|
+
const retText = () => `${sqlText} RETURNING ${cols.join(", ")}`;
|
|
16303
|
+
const build = () => delParams.length > 0 ? _sql.unsafe(retText(), delParams) : _sql.unsafe(retText());
|
|
16304
|
+
const runDelete = async () => {
|
|
16305
|
+
await activeHooks()?.beforeDelete?.({ table: String(table), where: whereCondition });
|
|
16306
|
+
const rows = await runWithHooks(build(), "delete");
|
|
16307
|
+
try {
|
|
16308
|
+
await activeHooks()?.afterDelete?.({ table: String(table), where: whereCondition, result: rows });
|
|
16309
|
+
} catch {}
|
|
16310
|
+
return rows;
|
|
16311
|
+
};
|
|
16216
16312
|
const runFirst = async () => {
|
|
16217
|
-
const rows = await
|
|
16313
|
+
const rows = await runDelete();
|
|
16218
16314
|
return Array.isArray(rows) ? rows[0] : rows;
|
|
16219
16315
|
};
|
|
16316
|
+
const unsupported = (name) => () => {
|
|
16317
|
+
throw new TypeError(`[query-builder] deleteFrom.returning(...).${name}() is not supported \u2014 a DELETE cannot be ordered or limited through this builder. Narrow it with where() instead.`);
|
|
16318
|
+
};
|
|
16220
16319
|
const obj = {
|
|
16221
|
-
where: () =>
|
|
16222
|
-
|
|
16223
|
-
|
|
16224
|
-
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16320
|
+
where: (...args) => {
|
|
16321
|
+
parent.where(...args);
|
|
16322
|
+
return obj;
|
|
16323
|
+
},
|
|
16324
|
+
andWhere: (...args) => {
|
|
16325
|
+
parent.where(...args);
|
|
16326
|
+
return obj;
|
|
16327
|
+
},
|
|
16328
|
+
whereNull: (...args) => {
|
|
16329
|
+
parent.whereNull(...args);
|
|
16330
|
+
return obj;
|
|
16331
|
+
},
|
|
16332
|
+
whereNotNull: (...args) => {
|
|
16333
|
+
parent.whereNotNull(...args);
|
|
16334
|
+
return obj;
|
|
16335
|
+
},
|
|
16336
|
+
orWhere: unsupported("orWhere"),
|
|
16337
|
+
orderBy: unsupported("orderBy"),
|
|
16338
|
+
limit: unsupported("limit"),
|
|
16339
|
+
offset: unsupported("offset"),
|
|
16340
|
+
toSQL: () => makeExecutableQuery(build(), retText()),
|
|
16341
|
+
execute: () => runDelete(),
|
|
16342
|
+
get: () => runDelete(),
|
|
16230
16343
|
first: runFirst,
|
|
16231
16344
|
executeTakeFirst: runFirst,
|
|
16232
16345
|
async firstOrFail() {
|
|
@@ -16270,17 +16383,17 @@ function createQueryBuilder(state) {
|
|
|
16270
16383
|
return { numDeletedRows: result };
|
|
16271
16384
|
},
|
|
16272
16385
|
returningAll() {
|
|
16273
|
-
const retAllText = `${sqlText} RETURNING *`;
|
|
16274
|
-
const
|
|
16386
|
+
const retAllText = () => `${sqlText} RETURNING *`;
|
|
16387
|
+
const build = () => delParams.length > 0 ? _sql.unsafe(retAllText(), delParams) : _sql.unsafe(retAllText());
|
|
16275
16388
|
return {
|
|
16276
|
-
toSQL: () => makeExecutableQuery(
|
|
16277
|
-
execute: () => runWithHooks(
|
|
16389
|
+
toSQL: () => makeExecutableQuery(build(), retAllText()),
|
|
16390
|
+
execute: () => runWithHooks(build(), "delete"),
|
|
16278
16391
|
async executeTakeFirst() {
|
|
16279
|
-
const result = await runWithHooks(
|
|
16392
|
+
const result = await runWithHooks(build(), "delete");
|
|
16280
16393
|
return Array.isArray(result) ? result[0] : result;
|
|
16281
16394
|
},
|
|
16282
16395
|
async executeTakeFirstOrThrow() {
|
|
16283
|
-
const result = await runWithHooks(
|
|
16396
|
+
const result = await runWithHooks(build(), "delete");
|
|
16284
16397
|
const first = Array.isArray(result) ? result[0] : result;
|
|
16285
16398
|
if (!first)
|
|
16286
16399
|
throw new Error("Delete with RETURNING failed");
|
|
@@ -18944,11 +19057,66 @@ var init_vitess = __esm(() => {
|
|
|
18944
19057
|
};
|
|
18945
19058
|
});
|
|
18946
19059
|
|
|
18947
|
-
// src/
|
|
19060
|
+
// src/column-types.ts
|
|
18948
19061
|
function isNumericPlanType(type) {
|
|
18949
19062
|
return type === "integer" || type === "bigint" || type === "float" || type === "double" || type === "decimal";
|
|
18950
19063
|
}
|
|
19064
|
+
function normalizeAttributeType(raw2) {
|
|
19065
|
+
if (typeof raw2 !== "string")
|
|
19066
|
+
return;
|
|
19067
|
+
switch (raw2.toLowerCase()) {
|
|
19068
|
+
case "string":
|
|
19069
|
+
return "string";
|
|
19070
|
+
case "text":
|
|
19071
|
+
return "text";
|
|
19072
|
+
case "integer":
|
|
19073
|
+
case "int":
|
|
19074
|
+
return "integer";
|
|
19075
|
+
case "number":
|
|
19076
|
+
return "integer";
|
|
19077
|
+
case "bigint":
|
|
19078
|
+
return "bigint";
|
|
19079
|
+
case "float":
|
|
19080
|
+
return "float";
|
|
19081
|
+
case "double":
|
|
19082
|
+
return "double";
|
|
19083
|
+
case "decimal":
|
|
19084
|
+
return "decimal";
|
|
19085
|
+
case "boolean":
|
|
19086
|
+
case "bool":
|
|
19087
|
+
return "boolean";
|
|
19088
|
+
case "date":
|
|
19089
|
+
return "date";
|
|
19090
|
+
case "datetime":
|
|
19091
|
+
case "timestamp":
|
|
19092
|
+
return "datetime";
|
|
19093
|
+
case "timestamptz":
|
|
19094
|
+
case "timestamp_tz":
|
|
19095
|
+
return "timestamptz";
|
|
19096
|
+
case "json":
|
|
19097
|
+
return "json";
|
|
19098
|
+
case "enum":
|
|
19099
|
+
return "enum";
|
|
19100
|
+
default:
|
|
19101
|
+
return;
|
|
19102
|
+
}
|
|
19103
|
+
}
|
|
19104
|
+
function sqliteAffinityFor(type) {
|
|
19105
|
+
switch (type) {
|
|
19106
|
+
case "boolean":
|
|
19107
|
+
case "integer":
|
|
19108
|
+
case "bigint":
|
|
19109
|
+
return "INTEGER";
|
|
19110
|
+
case "float":
|
|
19111
|
+
case "double":
|
|
19112
|
+
case "decimal":
|
|
19113
|
+
return "REAL";
|
|
19114
|
+
default:
|
|
19115
|
+
return "TEXT";
|
|
19116
|
+
}
|
|
19117
|
+
}
|
|
18951
19118
|
|
|
19119
|
+
// src/drivers/sqlite.ts
|
|
18952
19120
|
class SQLiteDriver {
|
|
18953
19121
|
quoteIdentifier(id) {
|
|
18954
19122
|
return `"${id.replace(/"/g, '""')}"`;
|
|
@@ -18957,40 +19125,14 @@ class SQLiteDriver {
|
|
|
18957
19125
|
if (column.name.endsWith("_id") && isNumericPlanType(column.type)) {
|
|
18958
19126
|
return "INTEGER";
|
|
18959
19127
|
}
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
return "INTEGER";
|
|
18967
|
-
case "integer":
|
|
18968
|
-
return "INTEGER";
|
|
18969
|
-
case "bigint":
|
|
18970
|
-
return "INTEGER";
|
|
18971
|
-
case "float":
|
|
18972
|
-
return "REAL";
|
|
18973
|
-
case "double":
|
|
18974
|
-
return "REAL";
|
|
18975
|
-
case "decimal":
|
|
18976
|
-
return "REAL";
|
|
18977
|
-
case "date":
|
|
18978
|
-
return "TEXT";
|
|
18979
|
-
case "datetime":
|
|
18980
|
-
return "TEXT";
|
|
18981
|
-
case "timestamptz":
|
|
18982
|
-
return "TEXT";
|
|
18983
|
-
case "json":
|
|
18984
|
-
return "TEXT";
|
|
18985
|
-
case "enum":
|
|
18986
|
-
if (column.enumValues && column.enumValues.length > 0) {
|
|
18987
|
-
const enumValues = column.enumValues.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
|
|
18988
|
-
return `TEXT CHECK (${this.quoteIdentifier(column.name)} IN (${enumValues}))`;
|
|
18989
|
-
}
|
|
18990
|
-
return "TEXT";
|
|
18991
|
-
default:
|
|
18992
|
-
return "TEXT";
|
|
19128
|
+
if (column.type === "enum") {
|
|
19129
|
+
if (column.enumValues && column.enumValues.length > 0) {
|
|
19130
|
+
const enumValues = column.enumValues.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
|
|
19131
|
+
return `TEXT CHECK (${this.quoteIdentifier(column.name)} IN (${enumValues}))`;
|
|
19132
|
+
}
|
|
19133
|
+
return "TEXT";
|
|
18993
19134
|
}
|
|
19135
|
+
return sqliteAffinityFor(column.type);
|
|
18994
19136
|
}
|
|
18995
19137
|
getPrimaryKeyType(column) {
|
|
18996
19138
|
return this.getColumnType(column);
|
|
@@ -25386,6 +25528,14 @@ function assertValidOrderByColumn(name, context) {
|
|
|
25386
25528
|
if (parts.length > 2 || parts.some((p2) => p2.length === 0 || p2.length > 64 || !SAFE_SQL_IDENTIFIER.test(p2)))
|
|
25387
25529
|
throw new TypeError(`[bun-query-builder] ${context}: invalid ORDER BY column '${name}' \u2014 expected 'column' or 'table.column' of [A-Za-z0-9_] \u2014 refusing to interpolate into SQL`);
|
|
25388
25530
|
}
|
|
25531
|
+
function registerLocalModel(name, model) {
|
|
25532
|
+
localModels.set(name, model);
|
|
25533
|
+
relationCache.clear();
|
|
25534
|
+
}
|
|
25535
|
+
function clearLocalModels() {
|
|
25536
|
+
localModels.clear();
|
|
25537
|
+
relationCache.clear();
|
|
25538
|
+
}
|
|
25389
25539
|
function getModelFromRegistry(name) {
|
|
25390
25540
|
if (!_getModel) {
|
|
25391
25541
|
try {
|
|
@@ -25396,7 +25546,7 @@ function getModelFromRegistry(name) {
|
|
|
25396
25546
|
};
|
|
25397
25547
|
}
|
|
25398
25548
|
}
|
|
25399
|
-
return _getModel(name);
|
|
25549
|
+
return _getModel(name) ?? localModels.get(name);
|
|
25400
25550
|
}
|
|
25401
25551
|
function toPostgresPlaceholders(sql2) {
|
|
25402
25552
|
const hit = pgPlaceholderCache.get(sql2);
|
|
@@ -25594,6 +25744,7 @@ function findAttributeDef(attrs, key) {
|
|
|
25594
25744
|
class ModelInstance {
|
|
25595
25745
|
_attributes;
|
|
25596
25746
|
_original;
|
|
25747
|
+
_forced = new Set;
|
|
25597
25748
|
_definition;
|
|
25598
25749
|
_hasSaved = false;
|
|
25599
25750
|
_relations = {};
|
|
@@ -25727,7 +25878,10 @@ class ModelInstance {
|
|
|
25727
25878
|
forceFill(data) {
|
|
25728
25879
|
if (this._original === null)
|
|
25729
25880
|
this._original = { ...this._attributes };
|
|
25730
|
-
|
|
25881
|
+
const normalized = normalizeAttributeKeys(data);
|
|
25882
|
+
Object.assign(this._attributes, normalized);
|
|
25883
|
+
for (const col of Object.keys(normalized))
|
|
25884
|
+
this._forced.add(col);
|
|
25731
25885
|
return this;
|
|
25732
25886
|
}
|
|
25733
25887
|
async save() {
|
|
@@ -25759,7 +25913,7 @@ class ModelInstance {
|
|
|
25759
25913
|
const attrs = this._definition.attributes;
|
|
25760
25914
|
const data = {};
|
|
25761
25915
|
for (const [key, attr] of Object.entries(attrs)) {
|
|
25762
|
-
if (attr.guarded)
|
|
25916
|
+
if (attr.guarded && !this._forced.has(toSnakeCase(key)))
|
|
25763
25917
|
continue;
|
|
25764
25918
|
const col = toSnakeCase(key);
|
|
25765
25919
|
if (this._attributes[col] !== undefined) {
|
|
@@ -27157,7 +27311,10 @@ function createModelInternal(definition) {
|
|
|
27157
27311
|
});
|
|
27158
27312
|
}
|
|
27159
27313
|
function createModel(definition) {
|
|
27160
|
-
|
|
27314
|
+
const model = createModelInternal(definition);
|
|
27315
|
+
if (definition?.name)
|
|
27316
|
+
registerLocalModel(definition.name, model);
|
|
27317
|
+
return model;
|
|
27161
27318
|
}
|
|
27162
27319
|
async function createTableFromModel(definition) {
|
|
27163
27320
|
const exec = getExecutor();
|
|
@@ -27174,12 +27331,9 @@ async function createTableFromModel(definition) {
|
|
|
27174
27331
|
if (emitted.has(name))
|
|
27175
27332
|
continue;
|
|
27176
27333
|
emitted.add(name);
|
|
27177
|
-
|
|
27178
|
-
|
|
27179
|
-
|
|
27180
|
-
else if (attr.type === "boolean")
|
|
27181
|
-
colType = "INTEGER";
|
|
27182
|
-
if (name.endsWith("_id"))
|
|
27334
|
+
const declaredType = normalizeAttributeType(attr.type);
|
|
27335
|
+
let colType = sqliteAffinityFor(declaredType);
|
|
27336
|
+
if (name.endsWith("_id") && (declaredType === undefined || isNumericPlanType(declaredType)))
|
|
27183
27337
|
colType = "INTEGER";
|
|
27184
27338
|
let colDef = `${name} ${colType}`;
|
|
27185
27339
|
if (attr.unique)
|
|
@@ -27245,12 +27399,13 @@ async function seedModel(definition, count, faker) {
|
|
|
27245
27399
|
await exec.run(`INSERT INTO ${definition.table} (${columns.join(", ")}) VALUES (${columns.map(() => "?").join(", ")})`, Object.values(data));
|
|
27246
27400
|
}
|
|
27247
27401
|
}
|
|
27248
|
-
var SAFE_SQL_IDENTIFIER, _getModel = null, pgPlaceholderCache, PG_PLACEHOLDER_CACHE_MAX = 500, globalDb = null, _executor = null, _executorForDb = null, _executorDialect = null, _executorDatabase = null, SOFT_DELETE_COLUMN = "deleted_at", BTM_RELATED_ALIAS = "__btm_rel__", btmKeysCache, snakeCaseCache, tableNameCache, relationCache, RELATION_CACHE_MAX = 1000, RESOLVABLE_RELATION_KINDS, DECLARABLE_RELATION_KINDS;
|
|
27402
|
+
var SAFE_SQL_IDENTIFIER, _getModel = null, localModels, pgPlaceholderCache, PG_PLACEHOLDER_CACHE_MAX = 500, globalDb = null, _executor = null, _executorForDb = null, _executorDialect = null, _executorDatabase = null, SOFT_DELETE_COLUMN = "deleted_at", BTM_RELATED_ALIAS = "__btm_rel__", btmKeysCache, snakeCaseCache, tableNameCache, relationCache, RELATION_CACHE_MAX = 1000, RESOLVABLE_RELATION_KINDS, DECLARABLE_RELATION_KINDS;
|
|
27249
27403
|
var init_orm = __esm(() => {
|
|
27250
27404
|
init_config();
|
|
27251
27405
|
init_db();
|
|
27252
27406
|
init_sqlite_pragmas();
|
|
27253
27407
|
SAFE_SQL_IDENTIFIER = /^[A-Z_][A-Z0-9_]*$/i;
|
|
27408
|
+
localModels = new Map;
|
|
27254
27409
|
pgPlaceholderCache = new Map;
|
|
27255
27410
|
btmKeysCache = new WeakMap;
|
|
27256
27411
|
snakeCaseCache = new Map;
|
|
@@ -27295,6 +27450,7 @@ function hasModel(name) {
|
|
|
27295
27450
|
}
|
|
27296
27451
|
function clearModelRegistry() {
|
|
27297
27452
|
modelRegistry.clear();
|
|
27453
|
+
clearLocalModels();
|
|
27298
27454
|
}
|
|
27299
27455
|
function registerModel(name, model) {
|
|
27300
27456
|
modelRegistry.set(name, model);
|
|
@@ -29070,7 +29226,7 @@ function detectTypeFromValidationRule(rule) {
|
|
|
29070
29226
|
}
|
|
29071
29227
|
return;
|
|
29072
29228
|
}
|
|
29073
|
-
function
|
|
29229
|
+
function normalizeAttributeType2(value) {
|
|
29074
29230
|
if (typeof value !== "string")
|
|
29075
29231
|
return;
|
|
29076
29232
|
const type = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
@@ -29160,7 +29316,7 @@ function buildMigrationPlan2(models, options) {
|
|
|
29160
29316
|
let inferred;
|
|
29161
29317
|
let enumValues;
|
|
29162
29318
|
const isPk = attrName === primaryKey;
|
|
29163
|
-
inferred =
|
|
29319
|
+
inferred = normalizeAttributeType2(attr.type) ?? detectTypeFromValidationRule(attr.validation?.rule);
|
|
29164
29320
|
if (inferred === "string") {
|
|
29165
29321
|
const maxLength = extractMaxFromRules(attr.validation?.rule);
|
|
29166
29322
|
if (maxLength && maxLength > MAX_BOUNDED_VARCHAR_LENGTH)
|
|
@@ -32359,7 +32515,7 @@ function getPrefix() {
|
|
|
32359
32515
|
}
|
|
32360
32516
|
var prefix = getPrefix();
|
|
32361
32517
|
// package.json
|
|
32362
|
-
var version2 = "0.2.
|
|
32518
|
+
var version2 = "0.2.44";
|
|
32363
32519
|
|
|
32364
32520
|
// bin/cli.ts
|
|
32365
32521
|
init_actions();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { NormalizedColumnType } from './migrations';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a canonical type stores a number.
|
|
4
|
+
*
|
|
5
|
+
* Used to decide when the `*_id` naming heuristic may coerce a column to
|
|
6
|
+
* INTEGER. Declared text types must never be coerced by a name heuristic —
|
|
7
|
+
* external ids are frequently strings (tickers, wallet addresses, hashes).
|
|
8
|
+
*/
|
|
9
|
+
export declare function isNumericPlanType(type: string | undefined): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Map a declared attribute type onto the canonical set.
|
|
12
|
+
*
|
|
13
|
+
* Accepts the spellings the model layer and the validation-rule reader already
|
|
14
|
+
* accept, so `type: 'int'`, `'bool'` and `'timestamp'` land where their long
|
|
15
|
+
* forms do. Returns `undefined` for anything unrecognised, which callers treat
|
|
16
|
+
* as "no opinion" rather than guessing.
|
|
17
|
+
*/
|
|
18
|
+
export declare function normalizeAttributeType(raw: unknown): NormalizedColumnType | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The SQLite storage class for a canonical type.
|
|
21
|
+
*
|
|
22
|
+
* `enum` is TEXT here; the migration driver additionally emits a CHECK
|
|
23
|
+
* constraint, which needs the column name and a quoter and so stays with the
|
|
24
|
+
* driver.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sqliteAffinityFor(type: NormalizedColumnType | undefined): 'TEXT' | 'INTEGER' | 'REAL';
|
package/dist/drivers/sqlite.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
+
import { isNumericPlanType } from '../column-types';
|
|
1
2
|
import type { ColumnPlan, IndexPlan, RebuildTableSpec, TablePlan } from '../migrations';
|
|
2
3
|
import type { DateBucketGrain } from './postgres';
|
|
3
|
-
/**
|
|
4
|
-
* Whether a plan type belongs to the numeric family. Used by the `_id`
|
|
5
|
-
* safety net (numeric ids must store as INTEGER on SQLite) — non-numeric
|
|
6
|
-
* declared types must never be coerced by the name heuristic.
|
|
7
|
-
*/
|
|
8
|
-
export declare function isNumericPlanType(type: string | undefined): boolean;
|
|
9
4
|
export declare interface DialectDriver {
|
|
10
5
|
createEnumType: (enumTypeName: string, values: string[]) => string
|
|
11
6
|
createTable: (table: TablePlan) => string
|
|
@@ -45,3 +40,13 @@ export declare class SQLiteDriver implements DialectDriver {
|
|
|
45
40
|
dateBucket(column: string, grain: DateBucketGrain, offsetHours?: number): string;
|
|
46
41
|
booleanLiteral(value: boolean): string;
|
|
47
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Whether a plan type belongs to the numeric family. Used by the `_id`
|
|
45
|
+
* safety net (numeric ids must store as INTEGER on SQLite) — non-numeric
|
|
46
|
+
* declared types must never be coerced by the name heuristic.
|
|
47
|
+
*
|
|
48
|
+
* Defined in column-types.ts now, so the ORM's create-table path applies the
|
|
49
|
+
* same rule from the same source. Re-exported because this is where callers
|
|
50
|
+
* already import it from.
|
|
51
|
+
*/
|
|
52
|
+
export { isNumericPlanType };
|
package/dist/model.d.ts
CHANGED
|
@@ -51,6 +51,10 @@ export declare function getModelRegistry(): Record<string, ReturnType<typeof cre
|
|
|
51
51
|
export declare function hasModel(name: string): boolean;
|
|
52
52
|
/**
|
|
53
53
|
* Clear all registered models. Primarily useful for testing.
|
|
54
|
+
*
|
|
55
|
+
* Also drops the models `createModel` registered internally, and the memoized
|
|
56
|
+
* relation resolutions derived from them. Leaving either behind lets a stale
|
|
57
|
+
* resolution from one test file decide a relation's table in the next.
|
|
54
58
|
*/
|
|
55
59
|
export declare function clearModelRegistry(): void;
|
|
56
60
|
/**
|
package/dist/orm.d.ts
CHANGED
package/dist/src/browser.js
CHANGED
|
@@ -475,7 +475,7 @@ class BrowserModelQueryBuilder {
|
|
|
475
475
|
for (const where of this._wheres) {
|
|
476
476
|
if (where.operator === "=") {
|
|
477
477
|
params.append(where.column, String(where.value));
|
|
478
|
-
} else if (
|
|
478
|
+
} else if (where.operator === "in" && Array.isArray(where.value)) {
|
|
479
479
|
params.append(`${where.column}[]`, where.value.join(","));
|
|
480
480
|
} else if (where.operator === "is" && where.value === null) {
|
|
481
481
|
params.append(`filter[${where.column}][is]`, "null");
|
package/dist/src/index.js
CHANGED
|
@@ -475,7 +475,7 @@ class BrowserModelQueryBuilder {
|
|
|
475
475
|
for (const where of this._wheres) {
|
|
476
476
|
if (where.operator === "=") {
|
|
477
477
|
params.append(where.column, String(where.value));
|
|
478
|
-
} else if (
|
|
478
|
+
} else if (where.operator === "in" && Array.isArray(where.value)) {
|
|
479
479
|
params.append(`${where.column}[]`, where.value.join(","));
|
|
480
480
|
} else if (where.operator === "is" && where.value === null) {
|
|
481
481
|
params.append(`filter[${where.column}][is]`, "null");
|
|
@@ -15792,6 +15792,31 @@ function createQueryBuilder(state) {
|
|
|
15792
15792
|
let built;
|
|
15793
15793
|
let sqlText = "";
|
|
15794
15794
|
const params = [];
|
|
15795
|
+
let noRows = false;
|
|
15796
|
+
const emptyInsertResult = () => isPostgres ? [] : { changes: 0, lastInsertRowid: 0 };
|
|
15797
|
+
const emptyReturningBuilder = () => {
|
|
15798
|
+
const noRow = async () => {
|
|
15799
|
+
return;
|
|
15800
|
+
};
|
|
15801
|
+
const noRowOrFail = async () => {
|
|
15802
|
+
throw new Error("Insert with RETURNING returned no rows");
|
|
15803
|
+
};
|
|
15804
|
+
return {
|
|
15805
|
+
where: () => emptyReturningBuilder(),
|
|
15806
|
+
andWhere: () => emptyReturningBuilder(),
|
|
15807
|
+
orWhere: () => emptyReturningBuilder(),
|
|
15808
|
+
orderBy: () => emptyReturningBuilder(),
|
|
15809
|
+
limit: () => emptyReturningBuilder(),
|
|
15810
|
+
offset: () => emptyReturningBuilder(),
|
|
15811
|
+
toSQL: () => makeExecutableQuery(null, ""),
|
|
15812
|
+
execute: async () => [],
|
|
15813
|
+
get: async () => [],
|
|
15814
|
+
first: noRow,
|
|
15815
|
+
executeTakeFirst: noRow,
|
|
15816
|
+
firstOrFail: noRowOrFail,
|
|
15817
|
+
executeTakeFirstOrThrow: noRowOrFail
|
|
15818
|
+
};
|
|
15819
|
+
};
|
|
15795
15820
|
const isPostgres = config5.dialect === "postgres";
|
|
15796
15821
|
const quoteId = isPostgres ? (id) => `"${String(id).replace(/"/g, '""')}"` : isMysqlLike(config5.dialect) ? (id) => `\`${String(id).replace(/`/g, "``")}\`` : (id) => `"${String(id).replace(/"/g, '""')}"`;
|
|
15797
15822
|
const getPlaceholder2 = isPostgres ? (index) => `$${index + 1}` : (_index) => "?";
|
|
@@ -15800,9 +15825,13 @@ function createQueryBuilder(state) {
|
|
|
15800
15825
|
const rows = Array.isArray(data) ? data : [data];
|
|
15801
15826
|
const rowCount = rows.length;
|
|
15802
15827
|
if (rowCount === 0) {
|
|
15803
|
-
|
|
15828
|
+
noRows = true;
|
|
15829
|
+
built = null;
|
|
15830
|
+
sqlText = "";
|
|
15831
|
+
params.length = 0;
|
|
15804
15832
|
return this;
|
|
15805
15833
|
}
|
|
15834
|
+
noRows = false;
|
|
15806
15835
|
const firstRow = rows[0];
|
|
15807
15836
|
const keys = Object.keys(firstRow);
|
|
15808
15837
|
const colCount = keys.length;
|
|
@@ -15856,6 +15885,8 @@ function createQueryBuilder(state) {
|
|
|
15856
15885
|
return this;
|
|
15857
15886
|
},
|
|
15858
15887
|
returning(...cols) {
|
|
15888
|
+
if (noRows)
|
|
15889
|
+
return emptyReturningBuilder();
|
|
15859
15890
|
const returningSql = `${sqlText} RETURNING ${cols.join(", ")}`;
|
|
15860
15891
|
const q = _sql.unsafe(returningSql, params);
|
|
15861
15892
|
const runFirst = async () => {
|
|
@@ -15889,11 +15920,15 @@ function createQueryBuilder(state) {
|
|
|
15889
15920
|
};
|
|
15890
15921
|
},
|
|
15891
15922
|
toSQL() {
|
|
15923
|
+
if (noRows)
|
|
15924
|
+
return makeExecutableQuery(null, "");
|
|
15892
15925
|
if (!built)
|
|
15893
15926
|
built = _sql.unsafe(sqlText, params);
|
|
15894
15927
|
return makeExecutableQuery(built, sqlText);
|
|
15895
15928
|
},
|
|
15896
15929
|
execute() {
|
|
15930
|
+
if (noRows)
|
|
15931
|
+
return Promise.resolve(emptyInsertResult());
|
|
15897
15932
|
const hooks = activeHooks();
|
|
15898
15933
|
const hasHooks = hooks && (hooks.onQueryStart || hooks.onQueryEnd || hooks.onQueryError || hooks.startSpan || hooks.beforeCreate || hooks.afterCreate || hasSlowQueryHook(hooks));
|
|
15899
15934
|
if (!hasHooks) {
|
|
@@ -15908,12 +15943,16 @@ function createQueryBuilder(state) {
|
|
|
15908
15943
|
return runWithHooks(built, "insert");
|
|
15909
15944
|
},
|
|
15910
15945
|
async executeTakeFirst() {
|
|
15946
|
+
if (noRows)
|
|
15947
|
+
return emptyInsertResult();
|
|
15911
15948
|
if (!built)
|
|
15912
15949
|
built = _sql.unsafe(sqlText, params);
|
|
15913
15950
|
const result = await runWithHooks(built, "insert");
|
|
15914
15951
|
return result;
|
|
15915
15952
|
},
|
|
15916
15953
|
async executeTakeFirstOrThrow() {
|
|
15954
|
+
if (noRows)
|
|
15955
|
+
throw new Error("Insert failed");
|
|
15917
15956
|
if (!built)
|
|
15918
15957
|
built = _sql.unsafe(sqlText, params);
|
|
15919
15958
|
const result = await runWithHooks(built, "insert");
|
|
@@ -15922,6 +15961,8 @@ function createQueryBuilder(state) {
|
|
|
15922
15961
|
return result;
|
|
15923
15962
|
},
|
|
15924
15963
|
returningAll() {
|
|
15964
|
+
if (noRows)
|
|
15965
|
+
return emptyReturningBuilder();
|
|
15925
15966
|
const returningSql = `${sqlText} RETURNING *`;
|
|
15926
15967
|
const q = _sql.unsafe(returningSql, params);
|
|
15927
15968
|
const runFirst = async () => {
|
|
@@ -16028,8 +16069,22 @@ function createQueryBuilder(state) {
|
|
|
16028
16069
|
built = _sql.unsafe(sqlText, params);
|
|
16029
16070
|
return this;
|
|
16030
16071
|
}
|
|
16031
|
-
if (
|
|
16072
|
+
if (isRawExpression(expr)) {
|
|
16073
|
+
sqlText = `${sqlText} ${getWhereKeyword()} ${expr.raw}`;
|
|
16074
|
+
built = _sql.unsafe(sqlText, params);
|
|
16075
|
+
return this;
|
|
16076
|
+
}
|
|
16077
|
+
if (isBoundSqlExpression(expr)) {
|
|
16078
|
+
const rendered = renderBoundSqlExpression(expr, params.length + 1);
|
|
16079
|
+
sqlText = `${sqlText} ${getWhereKeyword()} ${rendered.text}`;
|
|
16080
|
+
params.push(...rendered.parameters);
|
|
16081
|
+
built = _sql.unsafe(sqlText, params);
|
|
16082
|
+
return this;
|
|
16083
|
+
}
|
|
16084
|
+
if (expr && typeof expr === "object") {
|
|
16032
16085
|
const keys = Object.keys(expr);
|
|
16086
|
+
if (keys.length === 0)
|
|
16087
|
+
throw new TypeError("[query-builder] updateTable.where({}): an empty object is not a filter. Pass a condition, or drop the where() call if updating every row is intended.");
|
|
16033
16088
|
const len = keys.length;
|
|
16034
16089
|
const baseIdx = params.length;
|
|
16035
16090
|
const conditions = Array.from({ length: len });
|
|
@@ -16039,8 +16094,9 @@ function createQueryBuilder(state) {
|
|
|
16039
16094
|
}
|
|
16040
16095
|
sqlText = `${sqlText} ${getWhereKeyword()} ${conditions.join(" AND ")}`;
|
|
16041
16096
|
built = _sql.unsafe(sqlText, params);
|
|
16097
|
+
return this;
|
|
16042
16098
|
}
|
|
16043
|
-
|
|
16099
|
+
throw new TypeError(`[query-builder] updateTable.where(): expected a condition, got ${expr === null ? "null" : typeof expr}. Refusing to run an UPDATE with no WHERE \u2014 drop the where() call if updating every row is intended.`);
|
|
16044
16100
|
},
|
|
16045
16101
|
whereNull(column) {
|
|
16046
16102
|
const keyword = SQL_PATTERNS.WHERE.test(sqlText) ? "AND" : "WHERE";
|
|
@@ -16055,22 +16111,40 @@ function createQueryBuilder(state) {
|
|
|
16055
16111
|
return this;
|
|
16056
16112
|
},
|
|
16057
16113
|
returning(...cols) {
|
|
16058
|
-
const
|
|
16059
|
-
const
|
|
16114
|
+
const parent = this;
|
|
16115
|
+
const retText = () => `${sqlText} RETURNING ${cols.join(", ")}`;
|
|
16116
|
+
const build = () => params.length > 0 ? _sql.unsafe(retText(), params) : _sql.unsafe(retText());
|
|
16060
16117
|
const runFirst = async () => {
|
|
16061
|
-
const rows = await runWithHooks(
|
|
16118
|
+
const rows = await runWithHooks(build(), "update");
|
|
16062
16119
|
return Array.isArray(rows) ? rows[0] : rows;
|
|
16063
16120
|
};
|
|
16121
|
+
const unsupported = (name) => () => {
|
|
16122
|
+
throw new TypeError(`[query-builder] updateTable.returning(...).${name}() is not supported \u2014 an UPDATE cannot be ordered or limited through this builder. Apply the filter with where() instead.`);
|
|
16123
|
+
};
|
|
16064
16124
|
const obj = {
|
|
16065
|
-
where: () =>
|
|
16066
|
-
|
|
16067
|
-
|
|
16068
|
-
|
|
16069
|
-
|
|
16070
|
-
|
|
16071
|
-
|
|
16072
|
-
|
|
16073
|
-
|
|
16125
|
+
where: (...args) => {
|
|
16126
|
+
parent.where(...args);
|
|
16127
|
+
return obj;
|
|
16128
|
+
},
|
|
16129
|
+
andWhere: (...args) => {
|
|
16130
|
+
parent.where(...args);
|
|
16131
|
+
return obj;
|
|
16132
|
+
},
|
|
16133
|
+
whereNull: (...args) => {
|
|
16134
|
+
parent.whereNull(...args);
|
|
16135
|
+
return obj;
|
|
16136
|
+
},
|
|
16137
|
+
whereNotNull: (...args) => {
|
|
16138
|
+
parent.whereNotNull(...args);
|
|
16139
|
+
return obj;
|
|
16140
|
+
},
|
|
16141
|
+
orWhere: unsupported("orWhere"),
|
|
16142
|
+
orderBy: unsupported("orderBy"),
|
|
16143
|
+
limit: unsupported("limit"),
|
|
16144
|
+
offset: unsupported("offset"),
|
|
16145
|
+
toSQL: () => makeExecutableQuery(build(), retText()),
|
|
16146
|
+
execute: () => runWithHooks(build(), "update"),
|
|
16147
|
+
get: () => runWithHooks(build(), "update"),
|
|
16074
16148
|
first: runFirst,
|
|
16075
16149
|
executeTakeFirst: runFirst,
|
|
16076
16150
|
async firstOrFail() {
|
|
@@ -16109,17 +16183,17 @@ function createQueryBuilder(state) {
|
|
|
16109
16183
|
return { numUpdatedRows: result };
|
|
16110
16184
|
},
|
|
16111
16185
|
returningAll() {
|
|
16112
|
-
const retAllText = `${sqlText} RETURNING *`;
|
|
16113
|
-
const
|
|
16186
|
+
const retAllText = () => `${sqlText} RETURNING *`;
|
|
16187
|
+
const build = () => params.length > 0 ? _sql.unsafe(retAllText(), params) : _sql.unsafe(retAllText());
|
|
16114
16188
|
return {
|
|
16115
|
-
toSQL: () => makeExecutableQuery(
|
|
16116
|
-
execute: () => runWithHooks(
|
|
16189
|
+
toSQL: () => makeExecutableQuery(build(), retAllText()),
|
|
16190
|
+
execute: () => runWithHooks(build(), "update"),
|
|
16117
16191
|
async executeTakeFirst() {
|
|
16118
|
-
const result = await runWithHooks(
|
|
16192
|
+
const result = await runWithHooks(build(), "update");
|
|
16119
16193
|
return Array.isArray(result) ? result[0] : result;
|
|
16120
16194
|
},
|
|
16121
16195
|
async executeTakeFirstOrThrow() {
|
|
16122
|
-
const result = await runWithHooks(
|
|
16196
|
+
const result = await runWithHooks(build(), "update");
|
|
16123
16197
|
const first = Array.isArray(result) ? result[0] : result;
|
|
16124
16198
|
if (!first)
|
|
16125
16199
|
throw new Error("Update with RETURNING failed");
|
|
@@ -16184,8 +16258,22 @@ function createQueryBuilder(state) {
|
|
|
16184
16258
|
built = null;
|
|
16185
16259
|
return this;
|
|
16186
16260
|
}
|
|
16187
|
-
if (
|
|
16261
|
+
if (isRawExpression(expr)) {
|
|
16262
|
+
sqlText += ` ${getWhereKeyword()} ${expr.raw}`;
|
|
16263
|
+
built = null;
|
|
16264
|
+
return this;
|
|
16265
|
+
}
|
|
16266
|
+
if (isBoundSqlExpression(expr)) {
|
|
16267
|
+
const rendered = renderBoundSqlExpression(expr, delParams.length + 1);
|
|
16268
|
+
sqlText += ` ${getWhereKeyword()} ${rendered.text}`;
|
|
16269
|
+
delParams.push(...rendered.parameters);
|
|
16270
|
+
built = null;
|
|
16271
|
+
return this;
|
|
16272
|
+
}
|
|
16273
|
+
if (expr && typeof expr === "object") {
|
|
16188
16274
|
const keys = Object.keys(expr);
|
|
16275
|
+
if (keys.length === 0)
|
|
16276
|
+
throw new TypeError("[query-builder] deleteFrom.where({}): an empty object is not a filter. Pass a condition, or drop the where() call if deleting every row is intended.");
|
|
16189
16277
|
const conditions = [];
|
|
16190
16278
|
for (const key of keys) {
|
|
16191
16279
|
const paramIndex = delParams.length + 1;
|
|
@@ -16196,8 +16284,7 @@ function createQueryBuilder(state) {
|
|
|
16196
16284
|
built = null;
|
|
16197
16285
|
return this;
|
|
16198
16286
|
}
|
|
16199
|
-
|
|
16200
|
-
return this;
|
|
16287
|
+
throw new TypeError(`[query-builder] deleteFrom.where(): expected a condition, got ${expr === null ? "null" : typeof expr}. Refusing to run a DELETE with no WHERE \u2014 drop the where() call if deleting every row is intended.`);
|
|
16201
16288
|
},
|
|
16202
16289
|
whereNull(column) {
|
|
16203
16290
|
sqlText += ` ${getWhereKeyword()} ${quoteId(String(column))} IS NULL`;
|
|
@@ -16210,22 +16297,48 @@ function createQueryBuilder(state) {
|
|
|
16210
16297
|
return this;
|
|
16211
16298
|
},
|
|
16212
16299
|
returning(...cols) {
|
|
16213
|
-
const
|
|
16214
|
-
const
|
|
16300
|
+
const parent = this;
|
|
16301
|
+
const retText = () => `${sqlText} RETURNING ${cols.join(", ")}`;
|
|
16302
|
+
const build = () => delParams.length > 0 ? _sql.unsafe(retText(), delParams) : _sql.unsafe(retText());
|
|
16303
|
+
const runDelete = async () => {
|
|
16304
|
+
await activeHooks()?.beforeDelete?.({ table: String(table), where: whereCondition });
|
|
16305
|
+
const rows = await runWithHooks(build(), "delete");
|
|
16306
|
+
try {
|
|
16307
|
+
await activeHooks()?.afterDelete?.({ table: String(table), where: whereCondition, result: rows });
|
|
16308
|
+
} catch {}
|
|
16309
|
+
return rows;
|
|
16310
|
+
};
|
|
16215
16311
|
const runFirst = async () => {
|
|
16216
|
-
const rows = await
|
|
16312
|
+
const rows = await runDelete();
|
|
16217
16313
|
return Array.isArray(rows) ? rows[0] : rows;
|
|
16218
16314
|
};
|
|
16315
|
+
const unsupported = (name) => () => {
|
|
16316
|
+
throw new TypeError(`[query-builder] deleteFrom.returning(...).${name}() is not supported \u2014 a DELETE cannot be ordered or limited through this builder. Narrow it with where() instead.`);
|
|
16317
|
+
};
|
|
16219
16318
|
const obj = {
|
|
16220
|
-
where: () =>
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
|
|
16224
|
-
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16319
|
+
where: (...args) => {
|
|
16320
|
+
parent.where(...args);
|
|
16321
|
+
return obj;
|
|
16322
|
+
},
|
|
16323
|
+
andWhere: (...args) => {
|
|
16324
|
+
parent.where(...args);
|
|
16325
|
+
return obj;
|
|
16326
|
+
},
|
|
16327
|
+
whereNull: (...args) => {
|
|
16328
|
+
parent.whereNull(...args);
|
|
16329
|
+
return obj;
|
|
16330
|
+
},
|
|
16331
|
+
whereNotNull: (...args) => {
|
|
16332
|
+
parent.whereNotNull(...args);
|
|
16333
|
+
return obj;
|
|
16334
|
+
},
|
|
16335
|
+
orWhere: unsupported("orWhere"),
|
|
16336
|
+
orderBy: unsupported("orderBy"),
|
|
16337
|
+
limit: unsupported("limit"),
|
|
16338
|
+
offset: unsupported("offset"),
|
|
16339
|
+
toSQL: () => makeExecutableQuery(build(), retText()),
|
|
16340
|
+
execute: () => runDelete(),
|
|
16341
|
+
get: () => runDelete(),
|
|
16229
16342
|
first: runFirst,
|
|
16230
16343
|
executeTakeFirst: runFirst,
|
|
16231
16344
|
async firstOrFail() {
|
|
@@ -16269,17 +16382,17 @@ function createQueryBuilder(state) {
|
|
|
16269
16382
|
return { numDeletedRows: result };
|
|
16270
16383
|
},
|
|
16271
16384
|
returningAll() {
|
|
16272
|
-
const retAllText = `${sqlText} RETURNING *`;
|
|
16273
|
-
const
|
|
16385
|
+
const retAllText = () => `${sqlText} RETURNING *`;
|
|
16386
|
+
const build = () => delParams.length > 0 ? _sql.unsafe(retAllText(), delParams) : _sql.unsafe(retAllText());
|
|
16274
16387
|
return {
|
|
16275
|
-
toSQL: () => makeExecutableQuery(
|
|
16276
|
-
execute: () => runWithHooks(
|
|
16388
|
+
toSQL: () => makeExecutableQuery(build(), retAllText()),
|
|
16389
|
+
execute: () => runWithHooks(build(), "delete"),
|
|
16277
16390
|
async executeTakeFirst() {
|
|
16278
|
-
const result = await runWithHooks(
|
|
16391
|
+
const result = await runWithHooks(build(), "delete");
|
|
16279
16392
|
return Array.isArray(result) ? result[0] : result;
|
|
16280
16393
|
},
|
|
16281
16394
|
async executeTakeFirstOrThrow() {
|
|
16282
|
-
const result = await runWithHooks(
|
|
16395
|
+
const result = await runWithHooks(build(), "delete");
|
|
16283
16396
|
const first = Array.isArray(result) ? result[0] : result;
|
|
16284
16397
|
if (!first)
|
|
16285
16398
|
throw new Error("Delete with RETURNING failed");
|
|
@@ -18943,11 +19056,66 @@ var init_vitess = __esm(() => {
|
|
|
18943
19056
|
};
|
|
18944
19057
|
});
|
|
18945
19058
|
|
|
18946
|
-
// src/
|
|
19059
|
+
// src/column-types.ts
|
|
18947
19060
|
function isNumericPlanType(type) {
|
|
18948
19061
|
return type === "integer" || type === "bigint" || type === "float" || type === "double" || type === "decimal";
|
|
18949
19062
|
}
|
|
19063
|
+
function normalizeAttributeType(raw2) {
|
|
19064
|
+
if (typeof raw2 !== "string")
|
|
19065
|
+
return;
|
|
19066
|
+
switch (raw2.toLowerCase()) {
|
|
19067
|
+
case "string":
|
|
19068
|
+
return "string";
|
|
19069
|
+
case "text":
|
|
19070
|
+
return "text";
|
|
19071
|
+
case "integer":
|
|
19072
|
+
case "int":
|
|
19073
|
+
return "integer";
|
|
19074
|
+
case "number":
|
|
19075
|
+
return "integer";
|
|
19076
|
+
case "bigint":
|
|
19077
|
+
return "bigint";
|
|
19078
|
+
case "float":
|
|
19079
|
+
return "float";
|
|
19080
|
+
case "double":
|
|
19081
|
+
return "double";
|
|
19082
|
+
case "decimal":
|
|
19083
|
+
return "decimal";
|
|
19084
|
+
case "boolean":
|
|
19085
|
+
case "bool":
|
|
19086
|
+
return "boolean";
|
|
19087
|
+
case "date":
|
|
19088
|
+
return "date";
|
|
19089
|
+
case "datetime":
|
|
19090
|
+
case "timestamp":
|
|
19091
|
+
return "datetime";
|
|
19092
|
+
case "timestamptz":
|
|
19093
|
+
case "timestamp_tz":
|
|
19094
|
+
return "timestamptz";
|
|
19095
|
+
case "json":
|
|
19096
|
+
return "json";
|
|
19097
|
+
case "enum":
|
|
19098
|
+
return "enum";
|
|
19099
|
+
default:
|
|
19100
|
+
return;
|
|
19101
|
+
}
|
|
19102
|
+
}
|
|
19103
|
+
function sqliteAffinityFor(type) {
|
|
19104
|
+
switch (type) {
|
|
19105
|
+
case "boolean":
|
|
19106
|
+
case "integer":
|
|
19107
|
+
case "bigint":
|
|
19108
|
+
return "INTEGER";
|
|
19109
|
+
case "float":
|
|
19110
|
+
case "double":
|
|
19111
|
+
case "decimal":
|
|
19112
|
+
return "REAL";
|
|
19113
|
+
default:
|
|
19114
|
+
return "TEXT";
|
|
19115
|
+
}
|
|
19116
|
+
}
|
|
18950
19117
|
|
|
19118
|
+
// src/drivers/sqlite.ts
|
|
18951
19119
|
class SQLiteDriver {
|
|
18952
19120
|
quoteIdentifier(id) {
|
|
18953
19121
|
return `"${id.replace(/"/g, '""')}"`;
|
|
@@ -18956,40 +19124,14 @@ class SQLiteDriver {
|
|
|
18956
19124
|
if (column.name.endsWith("_id") && isNumericPlanType(column.type)) {
|
|
18957
19125
|
return "INTEGER";
|
|
18958
19126
|
}
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
return "INTEGER";
|
|
18966
|
-
case "integer":
|
|
18967
|
-
return "INTEGER";
|
|
18968
|
-
case "bigint":
|
|
18969
|
-
return "INTEGER";
|
|
18970
|
-
case "float":
|
|
18971
|
-
return "REAL";
|
|
18972
|
-
case "double":
|
|
18973
|
-
return "REAL";
|
|
18974
|
-
case "decimal":
|
|
18975
|
-
return "REAL";
|
|
18976
|
-
case "date":
|
|
18977
|
-
return "TEXT";
|
|
18978
|
-
case "datetime":
|
|
18979
|
-
return "TEXT";
|
|
18980
|
-
case "timestamptz":
|
|
18981
|
-
return "TEXT";
|
|
18982
|
-
case "json":
|
|
18983
|
-
return "TEXT";
|
|
18984
|
-
case "enum":
|
|
18985
|
-
if (column.enumValues && column.enumValues.length > 0) {
|
|
18986
|
-
const enumValues = column.enumValues.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
|
|
18987
|
-
return `TEXT CHECK (${this.quoteIdentifier(column.name)} IN (${enumValues}))`;
|
|
18988
|
-
}
|
|
18989
|
-
return "TEXT";
|
|
18990
|
-
default:
|
|
18991
|
-
return "TEXT";
|
|
19127
|
+
if (column.type === "enum") {
|
|
19128
|
+
if (column.enumValues && column.enumValues.length > 0) {
|
|
19129
|
+
const enumValues = column.enumValues.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
|
|
19130
|
+
return `TEXT CHECK (${this.quoteIdentifier(column.name)} IN (${enumValues}))`;
|
|
19131
|
+
}
|
|
19132
|
+
return "TEXT";
|
|
18992
19133
|
}
|
|
19134
|
+
return sqliteAffinityFor(column.type);
|
|
18993
19135
|
}
|
|
18994
19136
|
getPrimaryKeyType(column) {
|
|
18995
19137
|
return this.getColumnType(column);
|
|
@@ -25385,6 +25527,14 @@ function assertValidOrderByColumn(name, context) {
|
|
|
25385
25527
|
if (parts.length > 2 || parts.some((p2) => p2.length === 0 || p2.length > 64 || !SAFE_SQL_IDENTIFIER.test(p2)))
|
|
25386
25528
|
throw new TypeError(`[bun-query-builder] ${context}: invalid ORDER BY column '${name}' \u2014 expected 'column' or 'table.column' of [A-Za-z0-9_] \u2014 refusing to interpolate into SQL`);
|
|
25387
25529
|
}
|
|
25530
|
+
function registerLocalModel(name, model) {
|
|
25531
|
+
localModels.set(name, model);
|
|
25532
|
+
relationCache.clear();
|
|
25533
|
+
}
|
|
25534
|
+
function clearLocalModels() {
|
|
25535
|
+
localModels.clear();
|
|
25536
|
+
relationCache.clear();
|
|
25537
|
+
}
|
|
25388
25538
|
function getModelFromRegistry(name) {
|
|
25389
25539
|
if (!_getModel) {
|
|
25390
25540
|
try {
|
|
@@ -25395,7 +25545,7 @@ function getModelFromRegistry(name) {
|
|
|
25395
25545
|
};
|
|
25396
25546
|
}
|
|
25397
25547
|
}
|
|
25398
|
-
return _getModel(name);
|
|
25548
|
+
return _getModel(name) ?? localModels.get(name);
|
|
25399
25549
|
}
|
|
25400
25550
|
function toPostgresPlaceholders(sql2) {
|
|
25401
25551
|
const hit = pgPlaceholderCache.get(sql2);
|
|
@@ -25593,6 +25743,7 @@ function findAttributeDef(attrs, key) {
|
|
|
25593
25743
|
class ModelInstance {
|
|
25594
25744
|
_attributes;
|
|
25595
25745
|
_original;
|
|
25746
|
+
_forced = new Set;
|
|
25596
25747
|
_definition;
|
|
25597
25748
|
_hasSaved = false;
|
|
25598
25749
|
_relations = {};
|
|
@@ -25726,7 +25877,10 @@ class ModelInstance {
|
|
|
25726
25877
|
forceFill(data) {
|
|
25727
25878
|
if (this._original === null)
|
|
25728
25879
|
this._original = { ...this._attributes };
|
|
25729
|
-
|
|
25880
|
+
const normalized = normalizeAttributeKeys(data);
|
|
25881
|
+
Object.assign(this._attributes, normalized);
|
|
25882
|
+
for (const col of Object.keys(normalized))
|
|
25883
|
+
this._forced.add(col);
|
|
25730
25884
|
return this;
|
|
25731
25885
|
}
|
|
25732
25886
|
async save() {
|
|
@@ -25758,7 +25912,7 @@ class ModelInstance {
|
|
|
25758
25912
|
const attrs = this._definition.attributes;
|
|
25759
25913
|
const data = {};
|
|
25760
25914
|
for (const [key, attr] of Object.entries(attrs)) {
|
|
25761
|
-
if (attr.guarded)
|
|
25915
|
+
if (attr.guarded && !this._forced.has(toSnakeCase(key)))
|
|
25762
25916
|
continue;
|
|
25763
25917
|
const col = toSnakeCase(key);
|
|
25764
25918
|
if (this._attributes[col] !== undefined) {
|
|
@@ -27156,7 +27310,10 @@ function createModelInternal(definition) {
|
|
|
27156
27310
|
});
|
|
27157
27311
|
}
|
|
27158
27312
|
function createModel(definition) {
|
|
27159
|
-
|
|
27313
|
+
const model = createModelInternal(definition);
|
|
27314
|
+
if (definition?.name)
|
|
27315
|
+
registerLocalModel(definition.name, model);
|
|
27316
|
+
return model;
|
|
27160
27317
|
}
|
|
27161
27318
|
async function createTableFromModel(definition) {
|
|
27162
27319
|
const exec = getExecutor();
|
|
@@ -27173,12 +27330,9 @@ async function createTableFromModel(definition) {
|
|
|
27173
27330
|
if (emitted.has(name))
|
|
27174
27331
|
continue;
|
|
27175
27332
|
emitted.add(name);
|
|
27176
|
-
|
|
27177
|
-
|
|
27178
|
-
|
|
27179
|
-
else if (attr.type === "boolean")
|
|
27180
|
-
colType = "INTEGER";
|
|
27181
|
-
if (name.endsWith("_id"))
|
|
27333
|
+
const declaredType = normalizeAttributeType(attr.type);
|
|
27334
|
+
let colType = sqliteAffinityFor(declaredType);
|
|
27335
|
+
if (name.endsWith("_id") && (declaredType === undefined || isNumericPlanType(declaredType)))
|
|
27182
27336
|
colType = "INTEGER";
|
|
27183
27337
|
let colDef = `${name} ${colType}`;
|
|
27184
27338
|
if (attr.unique)
|
|
@@ -27244,12 +27398,13 @@ async function seedModel(definition, count, faker) {
|
|
|
27244
27398
|
await exec.run(`INSERT INTO ${definition.table} (${columns.join(", ")}) VALUES (${columns.map(() => "?").join(", ")})`, Object.values(data));
|
|
27245
27399
|
}
|
|
27246
27400
|
}
|
|
27247
|
-
var SAFE_SQL_IDENTIFIER, _getModel = null, pgPlaceholderCache, PG_PLACEHOLDER_CACHE_MAX = 500, globalDb = null, _executor = null, _executorForDb = null, _executorDialect = null, _executorDatabase = null, SOFT_DELETE_COLUMN = "deleted_at", BTM_RELATED_ALIAS = "__btm_rel__", btmKeysCache, snakeCaseCache, tableNameCache, relationCache, RELATION_CACHE_MAX = 1000, RESOLVABLE_RELATION_KINDS, DECLARABLE_RELATION_KINDS;
|
|
27401
|
+
var SAFE_SQL_IDENTIFIER, _getModel = null, localModels, pgPlaceholderCache, PG_PLACEHOLDER_CACHE_MAX = 500, globalDb = null, _executor = null, _executorForDb = null, _executorDialect = null, _executorDatabase = null, SOFT_DELETE_COLUMN = "deleted_at", BTM_RELATED_ALIAS = "__btm_rel__", btmKeysCache, snakeCaseCache, tableNameCache, relationCache, RELATION_CACHE_MAX = 1000, RESOLVABLE_RELATION_KINDS, DECLARABLE_RELATION_KINDS;
|
|
27248
27402
|
var init_orm = __esm(() => {
|
|
27249
27403
|
init_config();
|
|
27250
27404
|
init_db();
|
|
27251
27405
|
init_sqlite_pragmas();
|
|
27252
27406
|
SAFE_SQL_IDENTIFIER = /^[A-Z_][A-Z0-9_]*$/i;
|
|
27407
|
+
localModels = new Map;
|
|
27253
27408
|
pgPlaceholderCache = new Map;
|
|
27254
27409
|
btmKeysCache = new WeakMap;
|
|
27255
27410
|
snakeCaseCache = new Map;
|
|
@@ -27294,6 +27449,7 @@ function hasModel(name) {
|
|
|
27294
27449
|
}
|
|
27295
27450
|
function clearModelRegistry() {
|
|
27296
27451
|
modelRegistry.clear();
|
|
27452
|
+
clearLocalModels();
|
|
27297
27453
|
}
|
|
27298
27454
|
function registerModel(name, model) {
|
|
27299
27455
|
modelRegistry.set(name, model);
|
|
@@ -29069,7 +29225,7 @@ function detectTypeFromValidationRule(rule) {
|
|
|
29069
29225
|
}
|
|
29070
29226
|
return;
|
|
29071
29227
|
}
|
|
29072
|
-
function
|
|
29228
|
+
function normalizeAttributeType2(value) {
|
|
29073
29229
|
if (typeof value !== "string")
|
|
29074
29230
|
return;
|
|
29075
29231
|
const type = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
@@ -29159,7 +29315,7 @@ function buildMigrationPlan2(models, options) {
|
|
|
29159
29315
|
let inferred;
|
|
29160
29316
|
let enumValues;
|
|
29161
29317
|
const isPk = attrName === primaryKey;
|
|
29162
|
-
inferred =
|
|
29318
|
+
inferred = normalizeAttributeType2(attr.type) ?? detectTypeFromValidationRule(attr.validation?.rule);
|
|
29163
29319
|
if (inferred === "string") {
|
|
29164
29320
|
const maxLength = extractMaxFromRules(attr.validation?.rule);
|
|
29165
29321
|
if (maxLength && maxLength > MAX_BOUNDED_VARCHAR_LENGTH)
|
|
@@ -30420,6 +30576,7 @@ export {
|
|
|
30420
30576
|
config5 as config,
|
|
30421
30577
|
clearQueryCache,
|
|
30422
30578
|
clearModelRegistry,
|
|
30579
|
+
clearLocalModels,
|
|
30423
30580
|
checkSchema,
|
|
30424
30581
|
canonicalizeDefault,
|
|
30425
30582
|
canonicalStorageType,
|
package/package.json
CHANGED