rads-db 3.1.5 → 3.1.7
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/config.d.ts +1 -1
- package/dist/index.cjs +32 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +32 -7
- package/dist/{types-7e792d1f.d.ts → types-1bda441b.d.ts} +2 -1
- package/drivers/azureCosmos.cjs +48 -37
- package/drivers/azureCosmos.mjs +48 -31
- package/drivers/indexedDb.cjs +38 -24
- package/drivers/indexedDb.mjs +29 -21
- package/drivers/memory.cjs +24 -5
- package/drivers/memory.d.ts +1 -1
- package/drivers/memory.mjs +30 -5
- package/features/eventSourcing.cjs +3 -0
- package/features/eventSourcing.mjs +13 -3
- package/integrations/node.cjs +9 -3
- package/integrations/node.mjs +8 -3
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -156,6 +156,20 @@ const operatorFns = {
|
|
|
156
156
|
return true;
|
|
157
157
|
},
|
|
158
158
|
arrayContains: (x, w) => x?.includes(w),
|
|
159
|
+
isEmpty: (x, w) => {
|
|
160
|
+
if (!x) {
|
|
161
|
+
if (w === true)
|
|
162
|
+
return true;
|
|
163
|
+
if (w === false)
|
|
164
|
+
return false;
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
if (w === true)
|
|
168
|
+
return x?.length === 0;
|
|
169
|
+
if (w === false)
|
|
170
|
+
return x?.length > 0;
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
159
173
|
isNull: (x, w) => {
|
|
160
174
|
if (w === true)
|
|
161
175
|
return x == null;
|
|
@@ -276,7 +290,18 @@ function getFilter(where, namePrefix = "") {
|
|
|
276
290
|
}
|
|
277
291
|
if (andClauses.length === 0)
|
|
278
292
|
return null;
|
|
279
|
-
return (x) => andClauses
|
|
293
|
+
return (x) => resolveAndClauses(andClauses, x);
|
|
294
|
+
}
|
|
295
|
+
function resolveAndClauses(andClauses, x) {
|
|
296
|
+
let result = true;
|
|
297
|
+
for (const ac of andClauses) {
|
|
298
|
+
const clauseResult = ac(x);
|
|
299
|
+
if (clauseResult === false)
|
|
300
|
+
return false;
|
|
301
|
+
if (clauseResult == null)
|
|
302
|
+
result = void 0;
|
|
303
|
+
}
|
|
304
|
+
return result;
|
|
280
305
|
}
|
|
281
306
|
function getWhereNameOperatorPair(whereKey) {
|
|
282
307
|
if (whereKey.startsWith("_type")) {
|
|
@@ -290,14 +315,14 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
290
315
|
return getFilter(whereVal, name);
|
|
291
316
|
}
|
|
292
317
|
if (operator === "some") {
|
|
293
|
-
const f = getFilter(whereVal
|
|
318
|
+
const f = getFilter(whereVal);
|
|
294
319
|
return f && ((x) => {
|
|
295
320
|
const val = ___default.get(x, name);
|
|
296
|
-
return val
|
|
321
|
+
return val?.some(f);
|
|
297
322
|
});
|
|
298
323
|
}
|
|
299
324
|
if (operator === "none") {
|
|
300
|
-
const f = getFilter(whereVal
|
|
325
|
+
const f = getFilter(whereVal);
|
|
301
326
|
return f && ((x) => !___default.get(x, name)?.some(f));
|
|
302
327
|
}
|
|
303
328
|
if (operator === "and") {
|
|
@@ -310,7 +335,7 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
310
335
|
}
|
|
311
336
|
if (operator === "not") {
|
|
312
337
|
const f = getFilter(whereVal, namePrefix);
|
|
313
|
-
return f && ((x) =>
|
|
338
|
+
return f && ((x) => f(x) === false);
|
|
314
339
|
}
|
|
315
340
|
if (operator === "or") {
|
|
316
341
|
if (!___default.isArray(whereVal))
|
|
@@ -387,8 +412,8 @@ async function handlePrecomputed(context, docs, ctx) {
|
|
|
387
412
|
if (!handler)
|
|
388
413
|
throw new Error(`Computed handler for ${typeName}.${fieldName} was not found`);
|
|
389
414
|
}
|
|
390
|
-
const precomputedResults = docs.map(async ({ doc, oldDoc, events }) => {
|
|
391
|
-
doc[fieldName] = await handler({ fieldName, doc, oldDoc, events, db, ctx });
|
|
415
|
+
const precomputedResults = docs.map(async ({ doc, oldDoc, events, updatedEvents }) => {
|
|
416
|
+
doc[fieldName] = await handler({ fieldName, doc, oldDoc, events, updatedEvents, db, ctx });
|
|
392
417
|
});
|
|
393
418
|
await Promise.all(precomputedResults);
|
|
394
419
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as EntityDecoratorArgs, U as UiDecoratorArgs, a as UiFieldDecoratorArgs, V as ValidateEntityDecoratorArgs, b as ValidateFieldDecoratorArgs, F as FieldDecoratorArgs, C as ComputedDecoratorArgs, S as Schema, D as DriverConstructor, c as Driver, d as ComputedContext, R as RadsRequestContext, e as CreateRadsDbArgs, f as CreateRadsDbClientArgs } from './types-
|
|
2
|
-
export { N as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, aj as DeepKeys, ae as DeepPartial, ac as DeepPartialWithNulls, ad as DeepPartialWithNullsItem, ak as EntityMethods, w as EnumDefinition, v as FieldDefinition, I as FileSystemNode, u as FileUploadArgs, q as FileUploadDriver, p as FileUploadResult, B as GenerateClientNormalizedOptions, A as GenerateClientOptions, a8 as Get, _ as GetAggArgs, $ as GetAggArgsAgg, a2 as GetAggArgsAny, a5 as GetAggResponse, Z as GetArgs, a1 as GetArgsAny, a4 as GetArgsInclude, O as GetManyArgs, a0 as GetManyArgsAny, a6 as GetManyResponse, a7 as GetResponse, a9 as GetResponseInclude, aa as GetResponseIncludeSelect, ab as GetResponseNoInclude, s as GetRestRoutesArgs, G as GetRestRoutesOptions, t as GetRestRoutesResponse, ag as InverseRelation, M as MinimalDriver, ai as Put, ah as PutArgs, P as PutEffect, g as RadsConfig, h as RadsConfigDataSource, r as RadsDbInstance, L as RadsFeature, y as RadsHookDoc, K as RadsUiSlotDefinition, J as RadsUiSlotName, H as RadsVitePluginOptions, af as Relation, i as RequiredFields, l as RestDriverOptions, z as RestFileUploadDriverOptions, n as SchemaLoadResult, o as SchemaValidators, T as TypeDefinition, j as ValidateStringDecoratorArgs, Q as VerifyManyArgs, a3 as VerifyManyArgsAny, X as VerifyManyResponse, Y as Where, W as WhereJsonContains } from './types-
|
|
1
|
+
import { E as EntityDecoratorArgs, U as UiDecoratorArgs, a as UiFieldDecoratorArgs, V as ValidateEntityDecoratorArgs, b as ValidateFieldDecoratorArgs, F as FieldDecoratorArgs, C as ComputedDecoratorArgs, S as Schema, D as DriverConstructor, c as Driver, d as ComputedContext, R as RadsRequestContext, e as CreateRadsDbArgs, f as CreateRadsDbClientArgs } from './types-1bda441b.js';
|
|
2
|
+
export { N as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, aj as DeepKeys, ae as DeepPartial, ac as DeepPartialWithNulls, ad as DeepPartialWithNullsItem, ak as EntityMethods, w as EnumDefinition, v as FieldDefinition, I as FileSystemNode, u as FileUploadArgs, q as FileUploadDriver, p as FileUploadResult, B as GenerateClientNormalizedOptions, A as GenerateClientOptions, a8 as Get, _ as GetAggArgs, $ as GetAggArgsAgg, a2 as GetAggArgsAny, a5 as GetAggResponse, Z as GetArgs, a1 as GetArgsAny, a4 as GetArgsInclude, O as GetManyArgs, a0 as GetManyArgsAny, a6 as GetManyResponse, a7 as GetResponse, a9 as GetResponseInclude, aa as GetResponseIncludeSelect, ab as GetResponseNoInclude, s as GetRestRoutesArgs, G as GetRestRoutesOptions, t as GetRestRoutesResponse, ag as InverseRelation, M as MinimalDriver, ai as Put, ah as PutArgs, P as PutEffect, g as RadsConfig, h as RadsConfigDataSource, r as RadsDbInstance, L as RadsFeature, y as RadsHookDoc, K as RadsUiSlotDefinition, J as RadsUiSlotName, H as RadsVitePluginOptions, af as Relation, i as RequiredFields, l as RestDriverOptions, z as RestFileUploadDriverOptions, n as SchemaLoadResult, o as SchemaValidators, T as TypeDefinition, j as ValidateStringDecoratorArgs, Q as VerifyManyArgs, a3 as VerifyManyArgsAny, X as VerifyManyResponse, Y as Where, W as WhereJsonContains } from './types-1bda441b.js';
|
|
3
3
|
import { RadsDb } from '_rads-db';
|
|
4
4
|
export { RadsDb } from '_rads-db';
|
|
5
5
|
|
package/dist/index.mjs
CHANGED
|
@@ -149,6 +149,20 @@ const operatorFns = {
|
|
|
149
149
|
return true;
|
|
150
150
|
},
|
|
151
151
|
arrayContains: (x, w) => x?.includes(w),
|
|
152
|
+
isEmpty: (x, w) => {
|
|
153
|
+
if (!x) {
|
|
154
|
+
if (w === true)
|
|
155
|
+
return true;
|
|
156
|
+
if (w === false)
|
|
157
|
+
return false;
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
if (w === true)
|
|
161
|
+
return x?.length === 0;
|
|
162
|
+
if (w === false)
|
|
163
|
+
return x?.length > 0;
|
|
164
|
+
return true;
|
|
165
|
+
},
|
|
152
166
|
isNull: (x, w) => {
|
|
153
167
|
if (w === true)
|
|
154
168
|
return x == null;
|
|
@@ -269,7 +283,18 @@ function getFilter(where, namePrefix = "") {
|
|
|
269
283
|
}
|
|
270
284
|
if (andClauses.length === 0)
|
|
271
285
|
return null;
|
|
272
|
-
return (x) => andClauses
|
|
286
|
+
return (x) => resolveAndClauses(andClauses, x);
|
|
287
|
+
}
|
|
288
|
+
function resolveAndClauses(andClauses, x) {
|
|
289
|
+
let result = true;
|
|
290
|
+
for (const ac of andClauses) {
|
|
291
|
+
const clauseResult = ac(x);
|
|
292
|
+
if (clauseResult === false)
|
|
293
|
+
return false;
|
|
294
|
+
if (clauseResult == null)
|
|
295
|
+
result = void 0;
|
|
296
|
+
}
|
|
297
|
+
return result;
|
|
273
298
|
}
|
|
274
299
|
function getWhereNameOperatorPair(whereKey) {
|
|
275
300
|
if (whereKey.startsWith("_type")) {
|
|
@@ -283,14 +308,14 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
283
308
|
return getFilter(whereVal, name);
|
|
284
309
|
}
|
|
285
310
|
if (operator === "some") {
|
|
286
|
-
const f = getFilter(whereVal
|
|
311
|
+
const f = getFilter(whereVal);
|
|
287
312
|
return f && ((x) => {
|
|
288
313
|
const val = _.get(x, name);
|
|
289
|
-
return val
|
|
314
|
+
return val?.some(f);
|
|
290
315
|
});
|
|
291
316
|
}
|
|
292
317
|
if (operator === "none") {
|
|
293
|
-
const f = getFilter(whereVal
|
|
318
|
+
const f = getFilter(whereVal);
|
|
294
319
|
return f && ((x) => !_.get(x, name)?.some(f));
|
|
295
320
|
}
|
|
296
321
|
if (operator === "and") {
|
|
@@ -303,7 +328,7 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
303
328
|
}
|
|
304
329
|
if (operator === "not") {
|
|
305
330
|
const f = getFilter(whereVal, namePrefix);
|
|
306
|
-
return f && ((x) =>
|
|
331
|
+
return f && ((x) => f(x) === false);
|
|
307
332
|
}
|
|
308
333
|
if (operator === "or") {
|
|
309
334
|
if (!_.isArray(whereVal))
|
|
@@ -380,8 +405,8 @@ async function handlePrecomputed(context, docs, ctx) {
|
|
|
380
405
|
if (!handler)
|
|
381
406
|
throw new Error(`Computed handler for ${typeName}.${fieldName} was not found`);
|
|
382
407
|
}
|
|
383
|
-
const precomputedResults = docs.map(async ({ doc, oldDoc, events }) => {
|
|
384
|
-
doc[fieldName] = await handler({ fieldName, doc, oldDoc, events, db, ctx });
|
|
408
|
+
const precomputedResults = docs.map(async ({ doc, oldDoc, events, updatedEvents }) => {
|
|
409
|
+
doc[fieldName] = await handler({ fieldName, doc, oldDoc, events, updatedEvents, db, ctx });
|
|
385
410
|
});
|
|
386
411
|
await Promise.all(precomputedResults);
|
|
387
412
|
}
|
|
@@ -355,7 +355,8 @@ interface RadsHookDoc {
|
|
|
355
355
|
/** Previous version of document - i.e. one that is currently in the database (before saving) */
|
|
356
356
|
oldDoc: any;
|
|
357
357
|
/** If current entity is event sourcing aggregate, you can access all events in the chronological order */
|
|
358
|
-
events?: any;
|
|
358
|
+
events?: any[];
|
|
359
|
+
updatedEvents?: any[];
|
|
359
360
|
}
|
|
360
361
|
interface PutEffect {
|
|
361
362
|
beforePut?: (computedContext: ComputedContext, docs: RadsHookDoc[], ctx: RadsRequestContext) => MaybePromise<any>;
|
package/drivers/azureCosmos.cjs
CHANGED
|
@@ -101,11 +101,16 @@ var _default = options => (schema, entity) => {
|
|
|
101
101
|
nodes,
|
|
102
102
|
cursor
|
|
103
103
|
} = await getMany(args, ctx);
|
|
104
|
-
for (const
|
|
105
|
-
const
|
|
104
|
+
for (const chunk of _lodash.default.chunk(nodes, 100)) {
|
|
105
|
+
const chunkToSend = chunk.map(x => ({
|
|
106
|
+
operationType: "Delete",
|
|
107
|
+
partitionKey: x._partition,
|
|
108
|
+
id: x.id
|
|
109
|
+
}));
|
|
110
|
+
const responses = await bulkSendWithRetry(client, chunkToSend);
|
|
106
111
|
ctx?.log?.({
|
|
107
|
-
charge:
|
|
108
|
-
request: `delete#${
|
|
112
|
+
charge: _lodash.default.sumBy(responses, r => r.requestCharge),
|
|
113
|
+
request: `delete#${chunk[0]._partition}[${chunk.length}]`
|
|
109
114
|
});
|
|
110
115
|
}
|
|
111
116
|
return {
|
|
@@ -125,32 +130,11 @@ var _default = options => (schema, entity) => {
|
|
|
125
130
|
});
|
|
126
131
|
}
|
|
127
132
|
for (const chunk of _lodash.default.chunk(itemsToPut, 100)) {
|
|
128
|
-
|
|
133
|
+
const chunkToSend = chunk.map(x => ({
|
|
129
134
|
operationType: "Upsert",
|
|
130
135
|
resourceBody: x
|
|
131
136
|
}));
|
|
132
|
-
const responses =
|
|
133
|
-
for (let i = 0; i < 20; i++) {
|
|
134
|
-
const response = await client.items.bulk(chunkToSend);
|
|
135
|
-
const newChunkToSend = [];
|
|
136
|
-
for (let i2 = 0; i2 < chunkToSend.length; i2++) {
|
|
137
|
-
if (response[i2].statusCode !== 429) {
|
|
138
|
-
responses.push(response[i2]);
|
|
139
|
-
} else {
|
|
140
|
-
newChunkToSend.push(chunkToSend[i2]);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
chunkToSend = newChunkToSend;
|
|
144
|
-
if (chunkToSend.length === 0) break;
|
|
145
|
-
const delay = 50 + i * 100;
|
|
146
|
-
console.warn(`Db overloaded. Retrying after ${delay}ms...`);
|
|
147
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
148
|
-
}
|
|
149
|
-
if (chunkToSend.length !== 0) {
|
|
150
|
-
throw new _cosmos.RestError("Db oveloaded. Too many retries. Consider increasing database RU setting.", {
|
|
151
|
-
code: "429"
|
|
152
|
-
});
|
|
153
|
-
}
|
|
137
|
+
const responses = await bulkSendWithRetry(client, chunkToSend);
|
|
154
138
|
ctx?.log?.({
|
|
155
139
|
charge: _lodash.default.sumBy(responses, r => r.requestCharge),
|
|
156
140
|
request: `put#${chunk[0]._partition}[${chunk.length}]`
|
|
@@ -192,11 +176,7 @@ const operatorHandlers = {
|
|
|
192
176
|
paramName,
|
|
193
177
|
whereVal
|
|
194
178
|
} = whereArgs;
|
|
195
|
-
const
|
|
196
|
-
...ctx,
|
|
197
|
-
entity: ctx.schema[ctx.entity].fields[ctx.field].type
|
|
198
|
-
};
|
|
199
|
-
const subClause = getCosmosQueryWhere(newCtx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
179
|
+
const subClause = getCosmosQueryWhere(ctx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
200
180
|
if (subClause) {
|
|
201
181
|
if (simpleSubclauseRegex.test(subClause)) {
|
|
202
182
|
const parts = subClause.split(" ");
|
|
@@ -216,11 +196,7 @@ const operatorHandlers = {
|
|
|
216
196
|
paramName,
|
|
217
197
|
whereVal
|
|
218
198
|
} = whereArgs;
|
|
219
|
-
const
|
|
220
|
-
...ctx,
|
|
221
|
-
entity: ctx.schema[ctx.entity].fields[ctx.field].type
|
|
222
|
-
};
|
|
223
|
-
const subClause = getCosmosQueryWhere(newCtx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
199
|
+
const subClause = getCosmosQueryWhere(ctx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
224
200
|
if (subClause) return `not exists (select ${name} from ${name} in ${namePrefix}${name} where ${subClause})`;
|
|
225
201
|
return `array_length(${namePrefix}${name}) = 0`;
|
|
226
202
|
},
|
|
@@ -383,6 +359,16 @@ const operatorHandlers = {
|
|
|
383
359
|
parameters[pn] = whereVal;
|
|
384
360
|
return `array_contains(${namePrefix}${name}, @${pn})`;
|
|
385
361
|
},
|
|
362
|
+
isEmpty: (ctx, parameters, whereArgs) => {
|
|
363
|
+
const {
|
|
364
|
+
name,
|
|
365
|
+
namePrefix,
|
|
366
|
+
whereVal
|
|
367
|
+
} = whereArgs;
|
|
368
|
+
const n = `${namePrefix}${name}`;
|
|
369
|
+
if (whereVal) return `(not (is_defined(${n})) or ${n} = null or array_length(${n}) = 0)`;
|
|
370
|
+
return `(is_defined(${n}) and ${n} != null and array_length(${n}) > 0)`;
|
|
371
|
+
},
|
|
386
372
|
jsonContains: (ctx, parameters, whereArgs) => {
|
|
387
373
|
const {
|
|
388
374
|
name,
|
|
@@ -578,4 +564,29 @@ async function createDatabaseIfNotExists(options, client) {
|
|
|
578
564
|
} catch (e) {
|
|
579
565
|
console.error("Error initializing CosmosDb: ", e);
|
|
580
566
|
}
|
|
567
|
+
}
|
|
568
|
+
async function bulkSendWithRetry(client, chunkToSend) {
|
|
569
|
+
const responses = [];
|
|
570
|
+
for (let i = 0; i < 20; i++) {
|
|
571
|
+
const response = await client.items.bulk(chunkToSend);
|
|
572
|
+
const newChunkToSend = [];
|
|
573
|
+
for (let i2 = 0; i2 < chunkToSend.length; i2++) {
|
|
574
|
+
if (response[i2].statusCode !== 429) {
|
|
575
|
+
responses.push(response[i2]);
|
|
576
|
+
} else {
|
|
577
|
+
newChunkToSend.push(chunkToSend[i2]);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
chunkToSend = newChunkToSend;
|
|
581
|
+
if (chunkToSend.length === 0) break;
|
|
582
|
+
const delay = 50 + i * 100;
|
|
583
|
+
console.warn(`Db overloaded. Retrying after ${delay}ms...`);
|
|
584
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
585
|
+
}
|
|
586
|
+
if (chunkToSend.length !== 0) {
|
|
587
|
+
throw new _cosmos.RestError("Db oveloaded. Too many retries. Consider increasing database RU setting.", {
|
|
588
|
+
code: "429"
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
return responses;
|
|
581
592
|
}
|
package/drivers/azureCosmos.mjs
CHANGED
|
@@ -66,9 +66,17 @@ export default (options) => (schema, entity) => {
|
|
|
66
66
|
getMany,
|
|
67
67
|
async deleteMany(args, ctx) {
|
|
68
68
|
const { nodes, cursor } = await getMany(args, ctx);
|
|
69
|
-
for (const
|
|
70
|
-
const
|
|
71
|
-
|
|
69
|
+
for (const chunk of _.chunk(nodes, 100)) {
|
|
70
|
+
const chunkToSend = chunk.map((x) => ({
|
|
71
|
+
operationType: "Delete",
|
|
72
|
+
partitionKey: x._partition,
|
|
73
|
+
id: x.id
|
|
74
|
+
}));
|
|
75
|
+
const responses = await bulkSendWithRetry(client, chunkToSend);
|
|
76
|
+
ctx?.log?.({
|
|
77
|
+
charge: _.sumBy(responses, (r) => r.requestCharge),
|
|
78
|
+
request: `delete#${chunk[0]._partition}[${chunk.length}]`
|
|
79
|
+
});
|
|
72
80
|
}
|
|
73
81
|
return { nodes, cursor };
|
|
74
82
|
},
|
|
@@ -81,33 +89,11 @@ export default (options) => (schema, entity) => {
|
|
|
81
89
|
itemsToPut.push({ _partition: entity, id, ...item });
|
|
82
90
|
}
|
|
83
91
|
for (const chunk of _.chunk(itemsToPut, 100)) {
|
|
84
|
-
|
|
92
|
+
const chunkToSend = chunk.map((x) => ({
|
|
85
93
|
operationType: "Upsert",
|
|
86
94
|
resourceBody: x
|
|
87
95
|
}));
|
|
88
|
-
const responses =
|
|
89
|
-
for (let i = 0; i < 20; i++) {
|
|
90
|
-
const response = await client.items.bulk(chunkToSend);
|
|
91
|
-
const newChunkToSend = [];
|
|
92
|
-
for (let i2 = 0; i2 < chunkToSend.length; i2++) {
|
|
93
|
-
if (response[i2].statusCode !== 429) {
|
|
94
|
-
responses.push(response[i2]);
|
|
95
|
-
} else {
|
|
96
|
-
newChunkToSend.push(chunkToSend[i2]);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
chunkToSend = newChunkToSend;
|
|
100
|
-
if (chunkToSend.length === 0)
|
|
101
|
-
break;
|
|
102
|
-
const delay = 50 + i * 100;
|
|
103
|
-
console.warn(`Db overloaded. Retrying after ${delay}ms...`);
|
|
104
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
105
|
-
}
|
|
106
|
-
if (chunkToSend.length !== 0) {
|
|
107
|
-
throw new RestError("Db oveloaded. Too many retries. Consider increasing database RU setting.", {
|
|
108
|
-
code: "429"
|
|
109
|
-
});
|
|
110
|
-
}
|
|
96
|
+
const responses = await bulkSendWithRetry(client, chunkToSend);
|
|
111
97
|
ctx?.log?.({
|
|
112
98
|
charge: _.sumBy(responses, (r) => r.requestCharge),
|
|
113
99
|
request: `put#${chunk[0]._partition}[${chunk.length}]`
|
|
@@ -139,8 +125,7 @@ function getCosmosQuery(schema, entity, args) {
|
|
|
139
125
|
const operatorHandlers = {
|
|
140
126
|
some: (ctx, parameters, whereArgs) => {
|
|
141
127
|
const { name, namePrefix, paramNamePrefix, paramName, whereVal } = whereArgs;
|
|
142
|
-
const
|
|
143
|
-
const subClause = getCosmosQueryWhere(newCtx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
128
|
+
const subClause = getCosmosQueryWhere(ctx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
144
129
|
if (subClause) {
|
|
145
130
|
if (simpleSubclauseRegex.test(subClause)) {
|
|
146
131
|
const parts = subClause.split(" ");
|
|
@@ -154,8 +139,7 @@ const operatorHandlers = {
|
|
|
154
139
|
},
|
|
155
140
|
none: (ctx, parameters, whereArgs) => {
|
|
156
141
|
const { name, namePrefix, paramNamePrefix, paramName, whereVal } = whereArgs;
|
|
157
|
-
const
|
|
158
|
-
const subClause = getCosmosQueryWhere(newCtx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
142
|
+
const subClause = getCosmosQueryWhere(ctx, parameters, whereVal, `${name}.`, `${paramNamePrefix}${paramName}_`);
|
|
159
143
|
if (subClause)
|
|
160
144
|
return `not exists (select ${name} from ${name} in ${namePrefix}${name} where ${subClause})`;
|
|
161
145
|
return `array_length(${namePrefix}${name}) = 0`;
|
|
@@ -254,6 +238,13 @@ const operatorHandlers = {
|
|
|
254
238
|
parameters[pn] = whereVal;
|
|
255
239
|
return `array_contains(${namePrefix}${name}, @${pn})`;
|
|
256
240
|
},
|
|
241
|
+
isEmpty: (ctx, parameters, whereArgs) => {
|
|
242
|
+
const { name, namePrefix, whereVal } = whereArgs;
|
|
243
|
+
const n = `${namePrefix}${name}`;
|
|
244
|
+
if (whereVal)
|
|
245
|
+
return `(not (is_defined(${n})) or ${n} = null or array_length(${n}) = 0)`;
|
|
246
|
+
return `(is_defined(${n}) and ${n} != null and array_length(${n}) > 0)`;
|
|
247
|
+
},
|
|
257
248
|
jsonContains: (ctx, parameters, whereArgs) => {
|
|
258
249
|
const { name, namePrefix, paramName, paramNamePrefix, whereVal } = whereArgs;
|
|
259
250
|
const { path, isNull, value } = whereVal;
|
|
@@ -385,3 +376,29 @@ async function createDatabaseIfNotExists(options, client) {
|
|
|
385
376
|
console.error("Error initializing CosmosDb: ", e);
|
|
386
377
|
}
|
|
387
378
|
}
|
|
379
|
+
async function bulkSendWithRetry(client, chunkToSend) {
|
|
380
|
+
const responses = [];
|
|
381
|
+
for (let i = 0; i < 20; i++) {
|
|
382
|
+
const response = await client.items.bulk(chunkToSend);
|
|
383
|
+
const newChunkToSend = [];
|
|
384
|
+
for (let i2 = 0; i2 < chunkToSend.length; i2++) {
|
|
385
|
+
if (response[i2].statusCode !== 429) {
|
|
386
|
+
responses.push(response[i2]);
|
|
387
|
+
} else {
|
|
388
|
+
newChunkToSend.push(chunkToSend[i2]);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
chunkToSend = newChunkToSend;
|
|
392
|
+
if (chunkToSend.length === 0)
|
|
393
|
+
break;
|
|
394
|
+
const delay = 50 + i * 100;
|
|
395
|
+
console.warn(`Db overloaded. Retrying after ${delay}ms...`);
|
|
396
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
397
|
+
}
|
|
398
|
+
if (chunkToSend.length !== 0) {
|
|
399
|
+
throw new RestError("Db oveloaded. Too many retries. Consider increasing database RU setting.", {
|
|
400
|
+
code: "429"
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
return responses;
|
|
404
|
+
}
|
package/drivers/indexedDb.cjs
CHANGED
|
@@ -31,36 +31,50 @@ var _default = options => {
|
|
|
31
31
|
const handle = schema[entity]?.handle;
|
|
32
32
|
if (!handle) throw new Error(`Entity ${entity} not found`);
|
|
33
33
|
dbWrapper.entities[handle] = true;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (dexieResult.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (result.length > newCursor) {
|
|
47
|
-
resultCursor = newCursor;
|
|
48
|
-
}
|
|
49
|
-
result = result.slice(normalizedArgs.cursor, newCursor);
|
|
34
|
+
async function getMany(args, ctx) {
|
|
35
|
+
await initDbIfNeeded(dbName);
|
|
36
|
+
const normalizedArgs = normalizeArgs(args);
|
|
37
|
+
const dexieResult = applyArgsToDexieTable(dbWrapper.db.table(handle), normalizedArgs);
|
|
38
|
+
let resultCursor;
|
|
39
|
+
const newCursor = normalizedArgs.cursor + dexieResult.maxItemCount;
|
|
40
|
+
let result = await dexieResult.collection.toArray();
|
|
41
|
+
if (dexieResult.orderByProp) {
|
|
42
|
+
result = _lodash.default.orderBy(result, [dexieResult.orderByProp], [dexieResult.orderByDirection.toLowerCase()]);
|
|
43
|
+
if (dexieResult.maxItemCount) {
|
|
44
|
+
if (result.length > newCursor) {
|
|
45
|
+
resultCursor = newCursor;
|
|
50
46
|
}
|
|
51
|
-
|
|
52
|
-
nodes: result,
|
|
53
|
-
cursor: resultCursor ? _lodash.default.toString(resultCursor) : null
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
if (dexieResult.maxItemCount && result.length >= dexieResult.maxItemCount) {
|
|
57
|
-
resultCursor = newCursor;
|
|
47
|
+
result = result.slice(normalizedArgs.cursor, newCursor);
|
|
58
48
|
}
|
|
59
49
|
return {
|
|
60
50
|
nodes: result,
|
|
61
51
|
cursor: resultCursor ? _lodash.default.toString(resultCursor) : null
|
|
62
52
|
};
|
|
53
|
+
}
|
|
54
|
+
if (dexieResult.maxItemCount && result.length >= dexieResult.maxItemCount) {
|
|
55
|
+
resultCursor = newCursor;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
nodes: result,
|
|
59
|
+
cursor: resultCursor ? _lodash.default.toString(resultCursor) : null
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
driverName: "indexedDb",
|
|
64
|
+
async deleteMany(args, ctx) {
|
|
65
|
+
await initDbIfNeeded(dbName);
|
|
66
|
+
const {
|
|
67
|
+
nodes,
|
|
68
|
+
cursor
|
|
69
|
+
} = await getMany(args, ctx);
|
|
70
|
+
const table = dbWrapper.db.table(handle);
|
|
71
|
+
await table.bulkDelete(nodes.map(x => x.id));
|
|
72
|
+
return {
|
|
73
|
+
nodes,
|
|
74
|
+
cursor
|
|
75
|
+
};
|
|
63
76
|
},
|
|
77
|
+
getMany,
|
|
64
78
|
async putMany(items, ctx) {
|
|
65
79
|
await initDbIfNeeded(dbName);
|
|
66
80
|
const table = dbWrapper.db.table(handle);
|
|
@@ -98,7 +112,7 @@ function applyArgsToDexieTable(table, args) {
|
|
|
98
112
|
}
|
|
99
113
|
const f = (0, _memory.getFilter)(where);
|
|
100
114
|
if (f) {
|
|
101
|
-
collection = collection.filter(f);
|
|
115
|
+
collection = collection.filter(x => f(x) || false);
|
|
102
116
|
}
|
|
103
117
|
if (maxItemCount && !orderByProp) {
|
|
104
118
|
if (args.cursor) collection = collection.offset(_lodash.default.toNumber(args.cursor));
|
package/drivers/indexedDb.mjs
CHANGED
|
@@ -25,30 +25,38 @@ export default (options) => {
|
|
|
25
25
|
if (!handle)
|
|
26
26
|
throw new Error(`Entity ${entity} not found`);
|
|
27
27
|
dbWrapper.entities[handle] = true;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (dexieResult.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (result.length > newCursor) {
|
|
41
|
-
resultCursor = newCursor;
|
|
42
|
-
}
|
|
43
|
-
result = result.slice(normalizedArgs.cursor, newCursor);
|
|
28
|
+
async function getMany(args, ctx) {
|
|
29
|
+
await initDbIfNeeded(dbName);
|
|
30
|
+
const normalizedArgs = normalizeArgs(args);
|
|
31
|
+
const dexieResult = applyArgsToDexieTable(dbWrapper.db.table(handle), normalizedArgs);
|
|
32
|
+
let resultCursor;
|
|
33
|
+
const newCursor = normalizedArgs.cursor + dexieResult.maxItemCount;
|
|
34
|
+
let result = await dexieResult.collection.toArray();
|
|
35
|
+
if (dexieResult.orderByProp) {
|
|
36
|
+
result = _.orderBy(result, [dexieResult.orderByProp], [dexieResult.orderByDirection.toLowerCase()]);
|
|
37
|
+
if (dexieResult.maxItemCount) {
|
|
38
|
+
if (result.length > newCursor) {
|
|
39
|
+
resultCursor = newCursor;
|
|
44
40
|
}
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
if (dexieResult.maxItemCount && result.length >= dexieResult.maxItemCount) {
|
|
48
|
-
resultCursor = newCursor;
|
|
41
|
+
result = result.slice(normalizedArgs.cursor, newCursor);
|
|
49
42
|
}
|
|
50
43
|
return { nodes: result, cursor: resultCursor ? _.toString(resultCursor) : null };
|
|
44
|
+
}
|
|
45
|
+
if (dexieResult.maxItemCount && result.length >= dexieResult.maxItemCount) {
|
|
46
|
+
resultCursor = newCursor;
|
|
47
|
+
}
|
|
48
|
+
return { nodes: result, cursor: resultCursor ? _.toString(resultCursor) : null };
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
driverName: "indexedDb",
|
|
52
|
+
async deleteMany(args, ctx) {
|
|
53
|
+
await initDbIfNeeded(dbName);
|
|
54
|
+
const { nodes, cursor } = await getMany(args, ctx);
|
|
55
|
+
const table = dbWrapper.db.table(handle);
|
|
56
|
+
await table.bulkDelete(nodes.map((x) => x.id));
|
|
57
|
+
return { nodes, cursor };
|
|
51
58
|
},
|
|
59
|
+
getMany,
|
|
52
60
|
async putMany(items, ctx) {
|
|
53
61
|
await initDbIfNeeded(dbName);
|
|
54
62
|
const table = dbWrapper.db.table(handle);
|
|
@@ -81,7 +89,7 @@ function applyArgsToDexieTable(table, args) {
|
|
|
81
89
|
}
|
|
82
90
|
const f = getFilter(where);
|
|
83
91
|
if (f) {
|
|
84
|
-
collection = collection.filter(f);
|
|
92
|
+
collection = collection.filter((x) => f(x) || false);
|
|
85
93
|
}
|
|
86
94
|
if (maxItemCount && !orderByProp) {
|
|
87
95
|
if (args.cursor)
|
package/drivers/memory.cjs
CHANGED
|
@@ -33,6 +33,16 @@ const operatorFns = {
|
|
|
33
33
|
return true;
|
|
34
34
|
},
|
|
35
35
|
arrayContains: (x, w) => x?.includes(w),
|
|
36
|
+
isEmpty: (x, w) => {
|
|
37
|
+
if (!x) {
|
|
38
|
+
if (w === true) return true;
|
|
39
|
+
if (w === false) return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
if (w === true) return x?.length === 0;
|
|
43
|
+
if (w === false) return x?.length > 0;
|
|
44
|
+
return true;
|
|
45
|
+
},
|
|
36
46
|
isNull: (x, w) => {
|
|
37
47
|
if (w === true) return x == null;
|
|
38
48
|
if (w === false) return x != null;
|
|
@@ -154,7 +164,16 @@ function getFilter(where, namePrefix = "") {
|
|
|
154
164
|
if (f) andClauses.push(f);
|
|
155
165
|
}
|
|
156
166
|
if (andClauses.length === 0) return null;
|
|
157
|
-
return x => andClauses
|
|
167
|
+
return x => resolveAndClauses(andClauses, x);
|
|
168
|
+
}
|
|
169
|
+
function resolveAndClauses(andClauses, x) {
|
|
170
|
+
let result = true;
|
|
171
|
+
for (const ac of andClauses) {
|
|
172
|
+
const clauseResult = ac(x);
|
|
173
|
+
if (clauseResult === false) return false;
|
|
174
|
+
if (clauseResult == null) result = void 0;
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
158
177
|
}
|
|
159
178
|
function getWhereNameOperatorPair(whereKey) {
|
|
160
179
|
if (whereKey.startsWith("_type")) {
|
|
@@ -168,14 +187,14 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
168
187
|
return getFilter(whereVal, name);
|
|
169
188
|
}
|
|
170
189
|
if (operator === "some") {
|
|
171
|
-
const f = getFilter(whereVal
|
|
190
|
+
const f = getFilter(whereVal);
|
|
172
191
|
return f && (x => {
|
|
173
192
|
const val = _lodash.default.get(x, name);
|
|
174
|
-
return val
|
|
193
|
+
return val?.some(f);
|
|
175
194
|
});
|
|
176
195
|
}
|
|
177
196
|
if (operator === "none") {
|
|
178
|
-
const f = getFilter(whereVal
|
|
197
|
+
const f = getFilter(whereVal);
|
|
179
198
|
return f && (x => !_lodash.default.get(x, name)?.some(f));
|
|
180
199
|
}
|
|
181
200
|
if (operator === "and") {
|
|
@@ -186,7 +205,7 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
186
205
|
}
|
|
187
206
|
if (operator === "not") {
|
|
188
207
|
const f = getFilter(whereVal, namePrefix);
|
|
189
|
-
return f && (x =>
|
|
208
|
+
return f && (x => f(x) === false);
|
|
190
209
|
}
|
|
191
210
|
if (operator === "or") {
|
|
192
211
|
if (!_lodash.default.isArray(whereVal)) throw new Error(`Value for where._or must be an array`);
|
package/drivers/memory.d.ts
CHANGED
|
@@ -8,4 +8,4 @@ export declare function queryArray(array: any[], args: GetManyArgsAny): {
|
|
|
8
8
|
nodes: any;
|
|
9
9
|
cursor: any;
|
|
10
10
|
};
|
|
11
|
-
export declare function getFilter(where: Record<string, any>, namePrefix?: string): ((x: any) => boolean) | null;
|
|
11
|
+
export declare function getFilter(where: Record<string, any>, namePrefix?: string): ((x: any) => boolean | undefined) | null;
|
package/drivers/memory.mjs
CHANGED
|
@@ -23,6 +23,20 @@ const operatorFns = {
|
|
|
23
23
|
return true;
|
|
24
24
|
},
|
|
25
25
|
arrayContains: (x, w) => x?.includes(w),
|
|
26
|
+
isEmpty: (x, w) => {
|
|
27
|
+
if (!x) {
|
|
28
|
+
if (w === true)
|
|
29
|
+
return true;
|
|
30
|
+
if (w === false)
|
|
31
|
+
return false;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (w === true)
|
|
35
|
+
return x?.length === 0;
|
|
36
|
+
if (w === false)
|
|
37
|
+
return x?.length > 0;
|
|
38
|
+
return true;
|
|
39
|
+
},
|
|
26
40
|
isNull: (x, w) => {
|
|
27
41
|
if (w === true)
|
|
28
42
|
return x == null;
|
|
@@ -143,7 +157,18 @@ export function getFilter(where, namePrefix = "") {
|
|
|
143
157
|
}
|
|
144
158
|
if (andClauses.length === 0)
|
|
145
159
|
return null;
|
|
146
|
-
return (x) => andClauses
|
|
160
|
+
return (x) => resolveAndClauses(andClauses, x);
|
|
161
|
+
}
|
|
162
|
+
function resolveAndClauses(andClauses, x) {
|
|
163
|
+
let result = true;
|
|
164
|
+
for (const ac of andClauses) {
|
|
165
|
+
const clauseResult = ac(x);
|
|
166
|
+
if (clauseResult === false)
|
|
167
|
+
return false;
|
|
168
|
+
if (clauseResult == null)
|
|
169
|
+
result = void 0;
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
147
172
|
}
|
|
148
173
|
function getWhereNameOperatorPair(whereKey) {
|
|
149
174
|
if (whereKey.startsWith("_type")) {
|
|
@@ -157,14 +182,14 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
157
182
|
return getFilter(whereVal, name);
|
|
158
183
|
}
|
|
159
184
|
if (operator === "some") {
|
|
160
|
-
const f = getFilter(whereVal
|
|
185
|
+
const f = getFilter(whereVal);
|
|
161
186
|
return f && ((x) => {
|
|
162
187
|
const val = _.get(x, name);
|
|
163
|
-
return val
|
|
188
|
+
return val?.some(f);
|
|
164
189
|
});
|
|
165
190
|
}
|
|
166
191
|
if (operator === "none") {
|
|
167
|
-
const f = getFilter(whereVal
|
|
192
|
+
const f = getFilter(whereVal);
|
|
168
193
|
return f && ((x) => !_.get(x, name)?.some(f));
|
|
169
194
|
}
|
|
170
195
|
if (operator === "and") {
|
|
@@ -177,7 +202,7 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
177
202
|
}
|
|
178
203
|
if (operator === "not") {
|
|
179
204
|
const f = getFilter(whereVal, namePrefix);
|
|
180
|
-
return f && ((x) =>
|
|
205
|
+
return f && ((x) => f(x) === false);
|
|
181
206
|
}
|
|
182
207
|
if (operator === "or") {
|
|
183
208
|
if (!_.isArray(whereVal))
|
|
@@ -82,6 +82,7 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
82
82
|
result.push({
|
|
83
83
|
aggDoc,
|
|
84
84
|
events,
|
|
85
|
+
updatedEvents: events.filter(ev => docsById[ev.id]),
|
|
85
86
|
oldAggDoc: existingAggregatesById[aggDoc.id]
|
|
86
87
|
});
|
|
87
88
|
}
|
|
@@ -93,6 +94,7 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
93
94
|
}, result.map(v => ({
|
|
94
95
|
doc: v.aggDoc,
|
|
95
96
|
events: v.events,
|
|
97
|
+
updatedEvents: v.updatedEvents,
|
|
96
98
|
oldDoc: v.oldAggDoc
|
|
97
99
|
})), ctx);
|
|
98
100
|
return result;
|
|
@@ -102,6 +104,7 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
102
104
|
const hookItems = beforePutResult.map(v => ({
|
|
103
105
|
doc: v.aggDoc,
|
|
104
106
|
events: v.events,
|
|
107
|
+
updatedEvents: v.updatedEvents,
|
|
105
108
|
oldDoc: v.oldAggDoc
|
|
106
109
|
}));
|
|
107
110
|
const aggregateEffectContext = {
|
|
@@ -74,19 +74,29 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
74
74
|
if (!context.options.keepNulls)
|
|
75
75
|
cleanUndefinedAndNull(aggDoc);
|
|
76
76
|
}
|
|
77
|
-
result.push({
|
|
77
|
+
result.push({
|
|
78
|
+
aggDoc,
|
|
79
|
+
events,
|
|
80
|
+
updatedEvents: events.filter((ev) => docsById[ev.id]),
|
|
81
|
+
oldAggDoc: existingAggregatesById[aggDoc.id]
|
|
82
|
+
});
|
|
78
83
|
}
|
|
79
84
|
await handlePrecomputed(
|
|
80
85
|
// @ts-expect-error TODO wrong types
|
|
81
86
|
{ ...context, typeName: entityName },
|
|
82
|
-
result.map((v) => ({ doc: v.aggDoc, events: v.events, oldDoc: v.oldAggDoc })),
|
|
87
|
+
result.map((v) => ({ doc: v.aggDoc, events: v.events, updatedEvents: v.updatedEvents, oldDoc: v.oldAggDoc })),
|
|
83
88
|
ctx
|
|
84
89
|
);
|
|
85
90
|
return result;
|
|
86
91
|
},
|
|
87
92
|
async afterPut(context, docs, beforePutResult, ctx) {
|
|
88
93
|
const aggs = beforePutResult.map((d) => d.aggDoc);
|
|
89
|
-
const hookItems = beforePutResult.map((v) => ({
|
|
94
|
+
const hookItems = beforePutResult.map((v) => ({
|
|
95
|
+
doc: v.aggDoc,
|
|
96
|
+
events: v.events,
|
|
97
|
+
updatedEvents: v.updatedEvents,
|
|
98
|
+
oldDoc: v.oldAggDoc
|
|
99
|
+
}));
|
|
90
100
|
const aggregateEffectContext = { ...context, typeName: entityName, handle: schema[entityName].handle };
|
|
91
101
|
await beforePut(hookItems, ctx, aggregateEffectContext);
|
|
92
102
|
await context.drivers[entityName].putMany(aggs, ctx);
|
package/integrations/node.cjs
CHANGED
|
@@ -205,9 +205,12 @@ function getWhereFieldsFor(schema, type, fieldKey) {
|
|
|
205
205
|
const isPrimitive = !fieldType;
|
|
206
206
|
const isEnum = !!fieldType?.enumValues;
|
|
207
207
|
const isObject = !!fieldType?.fields;
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
const {
|
|
209
|
+
isRelation,
|
|
210
|
+
isRequired,
|
|
211
|
+
isArray,
|
|
212
|
+
isChange
|
|
213
|
+
} = field;
|
|
211
214
|
if (isArray) {
|
|
212
215
|
const arrayWhereFields = [`${name}_isEmpty?: boolean`];
|
|
213
216
|
if (!isRequired) arrayWhereFields.push(`${name}_isNull?: boolean`);
|
|
@@ -228,6 +231,9 @@ function getWhereFieldsFor(schema, type, fieldKey) {
|
|
|
228
231
|
return [`${name}?: ${getRelationWhereType()}`, ...commonWhereFields];
|
|
229
232
|
}
|
|
230
233
|
if (isObject) {
|
|
234
|
+
if (isChange) {
|
|
235
|
+
return [`${name}?: Omit<${fieldTypeName}_Where, 'id'>`, `${name}_jsonContains?: WhereJsonContains`, ...commonWhereFields];
|
|
236
|
+
}
|
|
231
237
|
return [`${name}?: ${fieldTypeName}_Where`, ...commonWhereFields];
|
|
232
238
|
}
|
|
233
239
|
if (isEnum) {
|
package/integrations/node.mjs
CHANGED
|
@@ -223,9 +223,7 @@ function getWhereFieldsFor(schema, type, fieldKey) {
|
|
|
223
223
|
const isPrimitive = !fieldType;
|
|
224
224
|
const isEnum = !!fieldType?.enumValues;
|
|
225
225
|
const isObject = !!fieldType?.fields;
|
|
226
|
-
const isRelation = field
|
|
227
|
-
const isRequired = field.isRequired;
|
|
228
|
-
const isArray = field.isArray;
|
|
226
|
+
const { isRelation, isRequired, isArray, isChange } = field;
|
|
229
227
|
if (isArray) {
|
|
230
228
|
const arrayWhereFields = [`${name}_isEmpty?: boolean`];
|
|
231
229
|
if (!isRequired)
|
|
@@ -248,6 +246,13 @@ function getWhereFieldsFor(schema, type, fieldKey) {
|
|
|
248
246
|
return [`${name}?: ${getRelationWhereType()}`, ...commonWhereFields];
|
|
249
247
|
}
|
|
250
248
|
if (isObject) {
|
|
249
|
+
if (isChange) {
|
|
250
|
+
return [
|
|
251
|
+
`${name}?: Omit<${fieldTypeName}_Where, 'id'>`,
|
|
252
|
+
`${name}_jsonContains?: WhereJsonContains`,
|
|
253
|
+
...commonWhereFields
|
|
254
|
+
];
|
|
255
|
+
}
|
|
251
256
|
return [`${name}?: ${fieldTypeName}_Where`, ...commonWhereFields];
|
|
252
257
|
}
|
|
253
258
|
if (isEnum) {
|