@farming-labs/orm 0.0.9 → 0.0.10
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/index.cjs +207 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +201 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -32,12 +32,17 @@ __export(index_exports, {
|
|
|
32
32
|
hasOne: () => hasOne,
|
|
33
33
|
id: () => id,
|
|
34
34
|
manyToMany: () => manyToMany,
|
|
35
|
+
mergeUniqueLookupCreateData: () => mergeUniqueLookupCreateData,
|
|
35
36
|
model: () => model,
|
|
36
37
|
renderDrizzleSchema: () => renderDrizzleSchema,
|
|
37
38
|
renderPrismaSchema: () => renderPrismaSchema,
|
|
38
39
|
renderSafeSql: () => renderSafeSql,
|
|
39
40
|
replaceGeneratedBlock: () => replaceGeneratedBlock,
|
|
40
|
-
|
|
41
|
+
requireUniqueLookup: () => requireUniqueLookup,
|
|
42
|
+
resolveRowIdentityLookup: () => resolveRowIdentityLookup,
|
|
43
|
+
string: () => string,
|
|
44
|
+
toUniqueLookupWhere: () => toUniqueLookupWhere,
|
|
45
|
+
validateUniqueLookupUpdateData: () => validateUniqueLookupUpdateData
|
|
41
46
|
});
|
|
42
47
|
module.exports = __toCommonJS(index_exports);
|
|
43
48
|
|
|
@@ -187,6 +192,167 @@ function datetime() {
|
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
// src/manifest.ts
|
|
195
|
+
function equalLookupValues(left, right) {
|
|
196
|
+
if (left instanceof Date && right instanceof Date) {
|
|
197
|
+
return left.getTime() === right.getTime();
|
|
198
|
+
}
|
|
199
|
+
return Object.is(left, right);
|
|
200
|
+
}
|
|
201
|
+
function isFilterObject(value) {
|
|
202
|
+
return !!value && typeof value === "object" && !(value instanceof Date) && !Array.isArray(value);
|
|
203
|
+
}
|
|
204
|
+
function extractEqualityValue(filter) {
|
|
205
|
+
if (!isFilterObject(filter)) {
|
|
206
|
+
return {
|
|
207
|
+
supported: true,
|
|
208
|
+
value: filter
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const keys = Object.keys(filter);
|
|
212
|
+
if (keys.length === 1 && "eq" in filter) {
|
|
213
|
+
return {
|
|
214
|
+
supported: true,
|
|
215
|
+
value: filter.eq
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
supported: false,
|
|
220
|
+
value: void 0
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function requireEqualityValues(model2, where, operation) {
|
|
224
|
+
const keys = Object.keys(where).filter((key) => key !== "AND" && key !== "OR" && key !== "NOT");
|
|
225
|
+
if ("AND" in where || "OR" in where || "NOT" in where || keys.length === 0) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`${operation} on model "${model2.name}" requires a unique equality filter in "where".`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const values = {};
|
|
231
|
+
for (const fieldName of keys) {
|
|
232
|
+
const field = model2.fields[fieldName];
|
|
233
|
+
if (!field) {
|
|
234
|
+
throw new Error(`Unknown field "${fieldName}" on model "${model2.name}".`);
|
|
235
|
+
}
|
|
236
|
+
const { supported, value } = extractEqualityValue(where[fieldName]);
|
|
237
|
+
if (!supported || value === void 0 || value === null) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`${operation} on model "${model2.name}" requires the "where" field "${fieldName}" to use a single non-null equality value.`
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
values[fieldName] = value;
|
|
243
|
+
}
|
|
244
|
+
return values;
|
|
245
|
+
}
|
|
246
|
+
function sameFieldSet(left, right) {
|
|
247
|
+
return left.length === right.length && left.every((fieldName) => right.includes(fieldName));
|
|
248
|
+
}
|
|
249
|
+
function requireUniqueLookup(model2, where, operation) {
|
|
250
|
+
const values = requireEqualityValues(model2, where, operation);
|
|
251
|
+
const keys = Object.keys(values);
|
|
252
|
+
if (keys.length === 1) {
|
|
253
|
+
const field = model2.fields[keys[0]];
|
|
254
|
+
if (field.kind === "id") {
|
|
255
|
+
return {
|
|
256
|
+
kind: "id",
|
|
257
|
+
fields: [field],
|
|
258
|
+
values
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
if (field.unique) {
|
|
262
|
+
return {
|
|
263
|
+
kind: "field",
|
|
264
|
+
fields: [field],
|
|
265
|
+
values
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const constraint = model2.constraints.unique.find(
|
|
270
|
+
(candidate) => sameFieldSet([...candidate.fields], keys)
|
|
271
|
+
);
|
|
272
|
+
if (!constraint) {
|
|
273
|
+
throw new Error(
|
|
274
|
+
`${operation} on model "${model2.name}" requires the "where" clause to match an id field, unique field, or declared unique constraint using equality values only.`
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
kind: "constraint",
|
|
279
|
+
fields: constraint.fields.map((fieldName) => model2.fields[fieldName]),
|
|
280
|
+
values: Object.fromEntries(
|
|
281
|
+
constraint.fields.map((fieldName) => [fieldName, values[fieldName]])
|
|
282
|
+
),
|
|
283
|
+
constraint
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function resolveRowIdentityLookup(model2, row) {
|
|
287
|
+
const idField = model2.fields.id;
|
|
288
|
+
if (idField && row[idField.name] !== void 0 && row[idField.name] !== null) {
|
|
289
|
+
return {
|
|
290
|
+
kind: "id",
|
|
291
|
+
fields: [idField],
|
|
292
|
+
values: {
|
|
293
|
+
[idField.name]: row[idField.name]
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
const uniqueField = Object.values(model2.fields).find(
|
|
298
|
+
(field) => field.unique && row[field.name] !== void 0 && row[field.name] !== null
|
|
299
|
+
);
|
|
300
|
+
if (uniqueField) {
|
|
301
|
+
return {
|
|
302
|
+
kind: "field",
|
|
303
|
+
fields: [uniqueField],
|
|
304
|
+
values: {
|
|
305
|
+
[uniqueField.name]: row[uniqueField.name]
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
for (const constraint of model2.constraints.unique) {
|
|
310
|
+
if (constraint.fields.every(
|
|
311
|
+
(fieldName) => row[fieldName] !== void 0 && row[fieldName] !== null
|
|
312
|
+
)) {
|
|
313
|
+
return {
|
|
314
|
+
kind: "constraint",
|
|
315
|
+
fields: constraint.fields.map((fieldName) => model2.fields[fieldName]),
|
|
316
|
+
values: Object.fromEntries(
|
|
317
|
+
constraint.fields.map((fieldName) => [fieldName, row[fieldName]])
|
|
318
|
+
),
|
|
319
|
+
constraint
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
throw new Error(
|
|
324
|
+
`Model "${model2.name}" requires an "id" field, unique field, or declared unique constraint with non-null values for identity lookups.`
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
function toUniqueLookupWhere(lookup) {
|
|
328
|
+
return Object.fromEntries(lookup.fields.map((field) => [field.name, lookup.values[field.name]]));
|
|
329
|
+
}
|
|
330
|
+
function mergeUniqueLookupCreateData(model2, createData, lookup, operation) {
|
|
331
|
+
const output = {
|
|
332
|
+
...createData
|
|
333
|
+
};
|
|
334
|
+
for (const field of lookup.fields) {
|
|
335
|
+
const currentValue = output[field.name];
|
|
336
|
+
const expectedValue = lookup.values[field.name];
|
|
337
|
+
if (currentValue !== void 0 && !equalLookupValues(currentValue, expectedValue)) {
|
|
338
|
+
throw new Error(
|
|
339
|
+
`${operation} on model "${model2.name}" requires create.${field.name} to match where.${field.name}.`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
output[field.name] = currentValue ?? expectedValue;
|
|
343
|
+
}
|
|
344
|
+
return output;
|
|
345
|
+
}
|
|
346
|
+
function validateUniqueLookupUpdateData(model2, updateData, lookup, operation) {
|
|
347
|
+
for (const field of lookup.fields) {
|
|
348
|
+
const nextValue = updateData[field.name];
|
|
349
|
+
if (nextValue !== void 0 && !equalLookupValues(nextValue, lookup.values[field.name])) {
|
|
350
|
+
throw new Error(
|
|
351
|
+
`${operation} on model "${model2.name}" cannot change the conflict field "${field.name}".`
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
190
356
|
function createConstraintName(table, columns, suffix) {
|
|
191
357
|
const base = [table, ...columns].join("_").replace(/[^a-zA-Z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
192
358
|
return `${base}_${suffix}`;
|
|
@@ -650,6 +816,14 @@ ${block}
|
|
|
650
816
|
// src/memory.ts
|
|
651
817
|
var import_node_crypto = require("crypto");
|
|
652
818
|
var isDate = (value) => value instanceof Date;
|
|
819
|
+
var manifestCache = /* @__PURE__ */ new WeakMap();
|
|
820
|
+
function getManifest(schema) {
|
|
821
|
+
const cached = manifestCache.get(schema);
|
|
822
|
+
if (cached) return cached;
|
|
823
|
+
const next = createManifest(schema);
|
|
824
|
+
manifestCache.set(schema, next);
|
|
825
|
+
return next;
|
|
826
|
+
}
|
|
653
827
|
function evaluateFilter(value, filter) {
|
|
654
828
|
if (filter === void 0 || filter === null || typeof filter !== "object" || isDate(filter) || Array.isArray(filter)) {
|
|
655
829
|
return value === filter;
|
|
@@ -842,6 +1016,11 @@ function createMemoryDriver(seed) {
|
|
|
842
1016
|
return projectRow(schema, model2, row, args.select);
|
|
843
1017
|
},
|
|
844
1018
|
async findUnique(schema, model2, args) {
|
|
1019
|
+
requireUniqueLookup(
|
|
1020
|
+
getManifest(schema).models[model2],
|
|
1021
|
+
args.where,
|
|
1022
|
+
"FindUnique"
|
|
1023
|
+
);
|
|
845
1024
|
const row = applyQuery(getRows(model2), args)[0];
|
|
846
1025
|
if (!row) return null;
|
|
847
1026
|
return projectRow(schema, model2, row, args.select);
|
|
@@ -873,12 +1052,32 @@ function createMemoryDriver(seed) {
|
|
|
873
1052
|
return rows.length;
|
|
874
1053
|
},
|
|
875
1054
|
async upsert(schema, model2, args) {
|
|
1055
|
+
const lookup = requireUniqueLookup(
|
|
1056
|
+
getManifest(schema).models[model2],
|
|
1057
|
+
args.where,
|
|
1058
|
+
"Upsert"
|
|
1059
|
+
);
|
|
1060
|
+
validateUniqueLookupUpdateData(
|
|
1061
|
+
getManifest(schema).models[model2],
|
|
1062
|
+
args.update,
|
|
1063
|
+
lookup,
|
|
1064
|
+
"Upsert"
|
|
1065
|
+
);
|
|
876
1066
|
const row = getRows(model2).find((item) => matchesWhere(item, args.where));
|
|
877
1067
|
if (row) {
|
|
878
1068
|
Object.assign(row, args.update);
|
|
879
1069
|
return projectRow(schema, model2, row, args.select);
|
|
880
1070
|
}
|
|
881
|
-
const created = buildRow(
|
|
1071
|
+
const created = buildRow(
|
|
1072
|
+
schema,
|
|
1073
|
+
model2,
|
|
1074
|
+
mergeUniqueLookupCreateData(
|
|
1075
|
+
getManifest(schema).models[model2],
|
|
1076
|
+
args.create,
|
|
1077
|
+
lookup,
|
|
1078
|
+
"Upsert"
|
|
1079
|
+
)
|
|
1080
|
+
);
|
|
882
1081
|
getRows(model2).push(created);
|
|
883
1082
|
return projectRow(schema, model2, created, args.select);
|
|
884
1083
|
},
|
|
@@ -974,11 +1173,16 @@ function defineSchema(models) {
|
|
|
974
1173
|
hasOne,
|
|
975
1174
|
id,
|
|
976
1175
|
manyToMany,
|
|
1176
|
+
mergeUniqueLookupCreateData,
|
|
977
1177
|
model,
|
|
978
1178
|
renderDrizzleSchema,
|
|
979
1179
|
renderPrismaSchema,
|
|
980
1180
|
renderSafeSql,
|
|
981
1181
|
replaceGeneratedBlock,
|
|
982
|
-
|
|
1182
|
+
requireUniqueLookup,
|
|
1183
|
+
resolveRowIdentityLookup,
|
|
1184
|
+
string,
|
|
1185
|
+
toUniqueLookupWhere,
|
|
1186
|
+
validateUniqueLookupUpdateData
|
|
983
1187
|
});
|
|
984
1188
|
//# sourceMappingURL=index.cjs.map
|