rads-db 3.1.11 → 3.1.13
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 +20 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +20 -10
- package/dist/{types-9c3659f0.d.ts → types-9cb9d6e7.d.ts} +9 -0
- package/drivers/azureCosmos.cjs +23 -8
- package/drivers/azureCosmos.mjs +23 -8
- package/drivers/memory.cjs +20 -10
- package/drivers/memory.mjs +18 -8
- package/features/eventSourcing.cjs +9 -6
- package/features/eventSourcing.d.ts +5 -2
- package/features/eventSourcing.mjs +9 -6
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -268,14 +268,14 @@ function queryArray(array, args) {
|
|
|
268
268
|
if (!array)
|
|
269
269
|
return array;
|
|
270
270
|
let result = array;
|
|
271
|
-
const { where,
|
|
271
|
+
const { where, orderByProperties, orderByDirections, maxItemCount, cursor } = prepareArgs(args);
|
|
272
272
|
const startIndex = Number(cursor) || 0;
|
|
273
273
|
const endIndex = startIndex + maxItemCount;
|
|
274
274
|
const f = getFilter(where);
|
|
275
275
|
if (f)
|
|
276
276
|
result = result.filter(f);
|
|
277
|
-
if (
|
|
278
|
-
result = ___default.orderBy(result,
|
|
277
|
+
if (orderByProperties)
|
|
278
|
+
result = ___default.orderBy(result, orderByProperties, orderByDirections);
|
|
279
279
|
if (maxItemCount)
|
|
280
280
|
result = result.slice(startIndex, endIndex);
|
|
281
281
|
const newCursor = endIndex >= array.length ? null : endIndex;
|
|
@@ -362,15 +362,25 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
362
362
|
function prepareArgs(args) {
|
|
363
363
|
args = args || {};
|
|
364
364
|
const where = { ...args.where };
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
365
|
+
const orderByProperties = [];
|
|
366
|
+
const orderByDirections = [];
|
|
367
|
+
if (args.orderBy) {
|
|
368
|
+
let orderBy = args.orderBy || "";
|
|
369
|
+
if (Array.isArray(orderBy))
|
|
370
|
+
orderBy = orderBy[0] || "";
|
|
371
|
+
const orderByParts = orderBy.split("_");
|
|
372
|
+
orderByProperties.push(orderByParts.slice(0, -1).join("."));
|
|
373
|
+
orderByDirections.push(orderByParts.slice(-1)[0]);
|
|
374
|
+
} else if (args.orderByArray) {
|
|
375
|
+
for (const order of args.orderByArray) {
|
|
376
|
+
const [property, direction] = order.split("_");
|
|
377
|
+
orderByProperties.push(property);
|
|
378
|
+
orderByDirections.push(direction);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
371
381
|
let maxItemCount = args.maxItemCount;
|
|
372
382
|
maxItemCount = maxItemCount || 100;
|
|
373
|
-
return { where,
|
|
383
|
+
return { where, orderByProperties, orderByDirections, maxItemCount, cursor: args.cursor, pick: args.include };
|
|
374
384
|
}
|
|
375
385
|
|
|
376
386
|
const computedPresets = {
|
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-9cb9d6e7.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-9cb9d6e7.js';
|
|
3
3
|
import { RadsDb } from '_rads-db';
|
|
4
4
|
export { RadsDb } from '_rads-db';
|
|
5
5
|
|
package/dist/index.mjs
CHANGED
|
@@ -261,14 +261,14 @@ function queryArray(array, args) {
|
|
|
261
261
|
if (!array)
|
|
262
262
|
return array;
|
|
263
263
|
let result = array;
|
|
264
|
-
const { where,
|
|
264
|
+
const { where, orderByProperties, orderByDirections, maxItemCount, cursor } = prepareArgs(args);
|
|
265
265
|
const startIndex = Number(cursor) || 0;
|
|
266
266
|
const endIndex = startIndex + maxItemCount;
|
|
267
267
|
const f = getFilter(where);
|
|
268
268
|
if (f)
|
|
269
269
|
result = result.filter(f);
|
|
270
|
-
if (
|
|
271
|
-
result = _.orderBy(result,
|
|
270
|
+
if (orderByProperties)
|
|
271
|
+
result = _.orderBy(result, orderByProperties, orderByDirections);
|
|
272
272
|
if (maxItemCount)
|
|
273
273
|
result = result.slice(startIndex, endIndex);
|
|
274
274
|
const newCursor = endIndex >= array.length ? null : endIndex;
|
|
@@ -355,15 +355,25 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
355
355
|
function prepareArgs(args) {
|
|
356
356
|
args = args || {};
|
|
357
357
|
const where = { ...args.where };
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
358
|
+
const orderByProperties = [];
|
|
359
|
+
const orderByDirections = [];
|
|
360
|
+
if (args.orderBy) {
|
|
361
|
+
let orderBy = args.orderBy || "";
|
|
362
|
+
if (Array.isArray(orderBy))
|
|
363
|
+
orderBy = orderBy[0] || "";
|
|
364
|
+
const orderByParts = orderBy.split("_");
|
|
365
|
+
orderByProperties.push(orderByParts.slice(0, -1).join("."));
|
|
366
|
+
orderByDirections.push(orderByParts.slice(-1)[0]);
|
|
367
|
+
} else if (args.orderByArray) {
|
|
368
|
+
for (const order of args.orderByArray) {
|
|
369
|
+
const [property, direction] = order.split("_");
|
|
370
|
+
orderByProperties.push(property);
|
|
371
|
+
orderByDirections.push(direction);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
364
374
|
let maxItemCount = args.maxItemCount;
|
|
365
375
|
maxItemCount = maxItemCount || 100;
|
|
366
|
-
return { where,
|
|
376
|
+
return { where, orderByProperties, orderByDirections, maxItemCount, cursor: args.cursor, pick: args.include };
|
|
367
377
|
}
|
|
368
378
|
|
|
369
379
|
const computedPresets = {
|
|
@@ -8,6 +8,7 @@ interface GetManyArgs<EN extends keyof EntityMeta> extends GetArgs<EN> {
|
|
|
8
8
|
cursor?: string | null;
|
|
9
9
|
maxItemCount?: number;
|
|
10
10
|
orderBy?: string;
|
|
11
|
+
orderByArray?: OrderBy<EntityMeta[EN]>;
|
|
11
12
|
}
|
|
12
13
|
interface VerifyManyArgs<EN extends keyof EntityMeta> extends GetManyArgs<EN> {
|
|
13
14
|
recompute?: string[];
|
|
@@ -122,6 +123,14 @@ interface EntityMethods<E, EN extends keyof EntityMeta> {
|
|
|
122
123
|
verifyMany<A extends VerifyManyArgs<EN>>(args?: A, ctx?: RadsRequestContext): MaybePromise$1<VerifyManyResponse>;
|
|
123
124
|
verifyAll<A extends VerifyManyArgs<EN>>(args?: A, ctx?: RadsRequestContext): MaybePromise$1<Pick<VerifyManyResponse, 'correctCount' | 'incorrectCount'>>;
|
|
124
125
|
}
|
|
126
|
+
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...0[]];
|
|
127
|
+
type Primitive = string | number | boolean | symbol | null | undefined;
|
|
128
|
+
type OrderByDeepKeys<T, Prefix extends string = '', MaxDepth extends number = 5, Depth extends number = MaxDepth> = Depth extends 0 ? '' : T extends Primitive ? Prefix extends '' ? never : Prefix : T extends object ? {
|
|
129
|
+
[K in keyof T]-?: K extends string | number ? OrderByDeepKeys<T[K], `${Prefix}${K & string}`, MaxDepth, Prev[Depth]> : never;
|
|
130
|
+
}[keyof T] : never;
|
|
131
|
+
type TrimEnd<T extends string, S extends string> = T extends `${infer R}${S}` ? R : T;
|
|
132
|
+
type ValidOrderByKey<T> = TrimEnd<OrderByDeepKeys<T>, '.'>;
|
|
133
|
+
type OrderBy<T> = Array<`${ValidOrderByKey<T>}_${'asc' | 'desc'}`>;
|
|
125
134
|
|
|
126
135
|
interface RadsConfig {
|
|
127
136
|
dataSources: Record<string, RadsConfigDataSource>;
|
package/drivers/azureCosmos.cjs
CHANGED
|
@@ -154,14 +154,7 @@ function getCosmosQuery(schema, entity, args) {
|
|
|
154
154
|
schema,
|
|
155
155
|
entity
|
|
156
156
|
}, parameters, where)].filter(x => x);
|
|
157
|
-
|
|
158
|
-
if (args.orderBy) {
|
|
159
|
-
const orderByParts = args.orderBy.split("_");
|
|
160
|
-
const orderPropFromOrderBy = orderByParts.slice(0, -1).join(".");
|
|
161
|
-
const orderDirection = orderByParts.at(-1);
|
|
162
|
-
const orderProp = orderPropFromOrderBy === "value" ? `r["value"]` : `r.${orderPropFromOrderBy}`;
|
|
163
|
-
orderByClause = `order by ${orderProp} ${orderDirection}`;
|
|
164
|
-
}
|
|
157
|
+
const orderByClause = getCosmosOrderBy(args);
|
|
165
158
|
let colums = "*";
|
|
166
159
|
if (args.include?._pick) {
|
|
167
160
|
colums = getCosmosSelectValue(args.include);
|
|
@@ -466,6 +459,28 @@ const operatorHandlers = {
|
|
|
466
459
|
return `${namePrefix}${name} <= @${pn}`;
|
|
467
460
|
}
|
|
468
461
|
};
|
|
462
|
+
function getCosmosOrderBy(args) {
|
|
463
|
+
let orderByClause = "";
|
|
464
|
+
if (args.orderByArray) {
|
|
465
|
+
orderByClause = `order by `;
|
|
466
|
+
const orderByColumns = [];
|
|
467
|
+
for (const order of args.orderByArray) {
|
|
468
|
+
orderByColumns.push(parseOrderBy(order));
|
|
469
|
+
}
|
|
470
|
+
orderByClause = orderByClause + orderByColumns.join(",");
|
|
471
|
+
} else if (args.orderBy) {
|
|
472
|
+
orderByClause = `order by ${parseOrderBy(args.orderBy)}`;
|
|
473
|
+
}
|
|
474
|
+
return orderByClause;
|
|
475
|
+
}
|
|
476
|
+
function parseOrderBy(order) {
|
|
477
|
+
const orderByParts = order.split("_");
|
|
478
|
+
const orderPropFromOrderBy = orderByParts.slice(0, -1).join(".");
|
|
479
|
+
const orderDirection = orderByParts.at(-1);
|
|
480
|
+
const orderProp = orderPropFromOrderBy === "value" ? `r["value"]` : `r.${orderPropFromOrderBy}`;
|
|
481
|
+
const ordr = `${orderProp} ${orderDirection}`;
|
|
482
|
+
return ordr;
|
|
483
|
+
}
|
|
469
484
|
function getCosmosQueryWhere(ctx, parameters, where, namePrefix = "r.", paramNamePrefix = "") {
|
|
470
485
|
const whereClauses = [];
|
|
471
486
|
for (const key in where) {
|
package/drivers/azureCosmos.mjs
CHANGED
|
@@ -110,14 +110,7 @@ function getCosmosQuery(schema, entity, args) {
|
|
|
110
110
|
`r._partition = '${entity}'`,
|
|
111
111
|
getCosmosQueryWhere({ schema, entity }, parameters, where)
|
|
112
112
|
].filter((x) => x);
|
|
113
|
-
|
|
114
|
-
if (args.orderBy) {
|
|
115
|
-
const orderByParts = args.orderBy.split("_");
|
|
116
|
-
const orderPropFromOrderBy = orderByParts.slice(0, -1).join(".");
|
|
117
|
-
const orderDirection = orderByParts.at(-1);
|
|
118
|
-
const orderProp = orderPropFromOrderBy === "value" ? `r["value"]` : `r.${orderPropFromOrderBy}`;
|
|
119
|
-
orderByClause = `order by ${orderProp} ${orderDirection}`;
|
|
120
|
-
}
|
|
113
|
+
const orderByClause = getCosmosOrderBy(args);
|
|
121
114
|
let colums = "*";
|
|
122
115
|
if (args.include?._pick) {
|
|
123
116
|
colums = getCosmosSelectValue(args.include);
|
|
@@ -292,6 +285,28 @@ const operatorHandlers = {
|
|
|
292
285
|
return `${namePrefix}${name} <= @${pn}`;
|
|
293
286
|
}
|
|
294
287
|
};
|
|
288
|
+
function getCosmosOrderBy(args) {
|
|
289
|
+
let orderByClause = "";
|
|
290
|
+
if (args.orderByArray) {
|
|
291
|
+
orderByClause = `order by `;
|
|
292
|
+
const orderByColumns = [];
|
|
293
|
+
for (const order of args.orderByArray) {
|
|
294
|
+
orderByColumns.push(parseOrderBy(order));
|
|
295
|
+
}
|
|
296
|
+
orderByClause = orderByClause + orderByColumns.join(",");
|
|
297
|
+
} else if (args.orderBy) {
|
|
298
|
+
orderByClause = `order by ${parseOrderBy(args.orderBy)}`;
|
|
299
|
+
}
|
|
300
|
+
return orderByClause;
|
|
301
|
+
}
|
|
302
|
+
function parseOrderBy(order) {
|
|
303
|
+
const orderByParts = order.split("_");
|
|
304
|
+
const orderPropFromOrderBy = orderByParts.slice(0, -1).join(".");
|
|
305
|
+
const orderDirection = orderByParts.at(-1);
|
|
306
|
+
const orderProp = orderPropFromOrderBy === "value" ? `r["value"]` : `r.${orderPropFromOrderBy}`;
|
|
307
|
+
const ordr = `${orderProp} ${orderDirection}`;
|
|
308
|
+
return ordr;
|
|
309
|
+
}
|
|
295
310
|
function getCosmosQueryWhere(ctx, parameters, where, namePrefix = "r.", paramNamePrefix = "") {
|
|
296
311
|
const whereClauses = [];
|
|
297
312
|
for (const key in where) {
|
package/drivers/memory.cjs
CHANGED
|
@@ -141,8 +141,8 @@ function queryArray(array, args) {
|
|
|
141
141
|
let result = array;
|
|
142
142
|
const {
|
|
143
143
|
where,
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
orderByProperties,
|
|
145
|
+
orderByDirections,
|
|
146
146
|
maxItemCount,
|
|
147
147
|
cursor
|
|
148
148
|
} = prepareArgs(args);
|
|
@@ -150,7 +150,7 @@ function queryArray(array, args) {
|
|
|
150
150
|
const endIndex = startIndex + maxItemCount;
|
|
151
151
|
const f = getFilter(where);
|
|
152
152
|
if (f) result = result.filter(f);
|
|
153
|
-
if (
|
|
153
|
+
if (orderByProperties) result = _lodash.default.orderBy(result, orderByProperties, orderByDirections);
|
|
154
154
|
if (maxItemCount) result = result.slice(startIndex, endIndex);
|
|
155
155
|
const newCursor = endIndex >= array.length ? null : endIndex;
|
|
156
156
|
return {
|
|
@@ -231,17 +231,27 @@ function prepareArgs(args) {
|
|
|
231
231
|
const where = {
|
|
232
232
|
...args.where
|
|
233
233
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
const orderByProperties = [];
|
|
235
|
+
const orderByDirections = [];
|
|
236
|
+
if (args.orderBy) {
|
|
237
|
+
let orderBy = args.orderBy || "";
|
|
238
|
+
if (Array.isArray(orderBy)) orderBy = orderBy[0] || "";
|
|
239
|
+
const orderByParts = orderBy.split("_");
|
|
240
|
+
orderByProperties.push(orderByParts.slice(0, -1).join("."));
|
|
241
|
+
orderByDirections.push(orderByParts.slice(-1)[0]);
|
|
242
|
+
} else if (args.orderByArray) {
|
|
243
|
+
for (const order of args.orderByArray) {
|
|
244
|
+
const [property, direction] = order.split("_");
|
|
245
|
+
orderByProperties.push(property);
|
|
246
|
+
orderByDirections.push(direction);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
239
249
|
let maxItemCount = args.maxItemCount;
|
|
240
250
|
maxItemCount = maxItemCount || 100;
|
|
241
251
|
return {
|
|
242
252
|
where,
|
|
243
|
-
|
|
244
|
-
|
|
253
|
+
orderByProperties,
|
|
254
|
+
orderByDirections,
|
|
245
255
|
maxItemCount,
|
|
246
256
|
cursor: args.cursor,
|
|
247
257
|
pick: args.include
|
package/drivers/memory.mjs
CHANGED
|
@@ -115,12 +115,12 @@ export function getAggFromArray(array, args) {
|
|
|
115
115
|
export function queryArray(array, args) {
|
|
116
116
|
if (!array) return array;
|
|
117
117
|
let result = array;
|
|
118
|
-
const { where,
|
|
118
|
+
const { where, orderByProperties, orderByDirections, maxItemCount, cursor } = prepareArgs(args);
|
|
119
119
|
const startIndex = Number(cursor) || 0;
|
|
120
120
|
const endIndex = startIndex + maxItemCount;
|
|
121
121
|
const f = getFilter(where);
|
|
122
122
|
if (f) result = result.filter(f);
|
|
123
|
-
if (
|
|
123
|
+
if (orderByProperties) result = _.orderBy(result, orderByProperties, orderByDirections);
|
|
124
124
|
if (maxItemCount) result = result.slice(startIndex, endIndex);
|
|
125
125
|
const newCursor = endIndex >= array.length ? null : endIndex;
|
|
126
126
|
return { nodes: _.cloneDeep(result), cursor: newCursor?.toString() || null };
|
|
@@ -196,12 +196,22 @@ function getFilterInner(operator, whereVal, name, namePrefix) {
|
|
|
196
196
|
function prepareArgs(args) {
|
|
197
197
|
args = args || {};
|
|
198
198
|
const where = { ...args.where };
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
199
|
+
const orderByProperties = [];
|
|
200
|
+
const orderByDirections = [];
|
|
201
|
+
if (args.orderBy) {
|
|
202
|
+
let orderBy = args.orderBy || "";
|
|
203
|
+
if (Array.isArray(orderBy)) orderBy = orderBy[0] || "";
|
|
204
|
+
const orderByParts = orderBy.split("_");
|
|
205
|
+
orderByProperties.push(orderByParts.slice(0, -1).join("."));
|
|
206
|
+
orderByDirections.push(orderByParts.slice(-1)[0]);
|
|
207
|
+
} else if (args.orderByArray) {
|
|
208
|
+
for (const order of args.orderByArray) {
|
|
209
|
+
const [property, direction] = order.split("_");
|
|
210
|
+
orderByProperties.push(property);
|
|
211
|
+
orderByDirections.push(direction);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
204
214
|
let maxItemCount = args.maxItemCount;
|
|
205
215
|
maxItemCount = maxItemCount || 100;
|
|
206
|
-
return { where,
|
|
216
|
+
return { where, orderByProperties, orderByDirections, maxItemCount, cursor: args.cursor, pick: args.include };
|
|
207
217
|
}
|
|
@@ -7,27 +7,27 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
8
8
|
var _radsDb = require("rads-db");
|
|
9
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
var _default =
|
|
10
|
+
var _default = options => {
|
|
11
11
|
return {
|
|
12
12
|
name: "eventSourcing",
|
|
13
13
|
init(db, context) {
|
|
14
|
-
verifyEventSourcingSetup(context.schema, context.effects);
|
|
14
|
+
verifyEventSourcingSetup(context.schema, context.effects, options || {});
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
module.exports = _default;
|
|
19
|
-
function verifyEventSourcingSetup(schema, effects) {
|
|
19
|
+
function verifyEventSourcingSetup(schema, effects, options) {
|
|
20
20
|
for (const entityName in schema) {
|
|
21
21
|
if (!schema[entityName].decorators.entity) continue;
|
|
22
22
|
if (schema[entityName].decorators.precomputed?.preset !== "eventSourcing") continue;
|
|
23
23
|
const eventEntityName = `${entityName}Event`;
|
|
24
24
|
const aggregateRelationField = _lodash.default.lowerFirst(entityName);
|
|
25
25
|
validateEventSourcingSetup(schema, entityName, eventEntityName, aggregateRelationField);
|
|
26
|
-
const effect = getEffectFor(entityName, aggregateRelationField, eventEntityName, schema);
|
|
26
|
+
const effect = getEffectFor(entityName, aggregateRelationField, eventEntityName, schema, options);
|
|
27
27
|
effects[eventEntityName].push(effect);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
function getEffectFor(entityName, aggregateRelationField, eventEntityName, schema) {
|
|
30
|
+
function getEffectFor(entityName, aggregateRelationField, eventEntityName, schema, options) {
|
|
31
31
|
return {
|
|
32
32
|
async beforePut(context, docs, ctx) {
|
|
33
33
|
const docsByAggId = {};
|
|
@@ -62,7 +62,10 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
62
62
|
const existingAggregatesById = _lodash.default.keyBy(existingAggregates, "id");
|
|
63
63
|
const result = [];
|
|
64
64
|
for (const aggId in docsByAggId) {
|
|
65
|
-
|
|
65
|
+
let events = _lodash.default.orderBy([...docsByAggId[aggId], ...(existingEventsByAggId[aggId] || [])], ["date"], "asc");
|
|
66
|
+
if (options.applyEventIf) {
|
|
67
|
+
events = events.filter(ev => options.applyEventIf(ev, context, ctx));
|
|
68
|
+
}
|
|
66
69
|
if (events[0].type !== "creation") throw new Error(`First event must have type = "creation". (type: ${events[0].type}, id: ${events[0].id})`);
|
|
67
70
|
if (events.slice(1).some(ev => ev.type === "creation")) {
|
|
68
71
|
throw new Error(`Only first event may have type = "creation"`);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import type { RadsFeature } from '@/types';
|
|
2
|
-
|
|
1
|
+
import type { ComputedContext, RadsFeature, RadsRequestContext } from '@/types';
|
|
2
|
+
export interface EventSourcingFeatureOptions {
|
|
3
|
+
applyEventIf?: (event: any, context: ComputedContext, ctx: RadsRequestContext) => boolean;
|
|
4
|
+
}
|
|
5
|
+
declare const _default: (options?: EventSourcingFeatureOptions) => RadsFeature;
|
|
3
6
|
export default _default;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import _ from "lodash";
|
|
2
2
|
import { cleanUndefinedAndNull, diff, handlePrecomputed, merge } from "rads-db";
|
|
3
|
-
export default () => {
|
|
3
|
+
export default (options) => {
|
|
4
4
|
return {
|
|
5
5
|
name: "eventSourcing",
|
|
6
6
|
init(db, context) {
|
|
7
|
-
verifyEventSourcingSetup(context.schema, context.effects);
|
|
7
|
+
verifyEventSourcingSetup(context.schema, context.effects, options || {});
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
10
|
};
|
|
11
|
-
function verifyEventSourcingSetup(schema, effects) {
|
|
11
|
+
function verifyEventSourcingSetup(schema, effects, options) {
|
|
12
12
|
for (const entityName in schema) {
|
|
13
13
|
if (!schema[entityName].decorators.entity) continue;
|
|
14
14
|
if (schema[entityName].decorators.precomputed?.preset !== "eventSourcing") continue;
|
|
15
15
|
const eventEntityName = `${entityName}Event`;
|
|
16
16
|
const aggregateRelationField = _.lowerFirst(entityName);
|
|
17
17
|
validateEventSourcingSetup(schema, entityName, eventEntityName, aggregateRelationField);
|
|
18
|
-
const effect = getEffectFor(entityName, aggregateRelationField, eventEntityName, schema);
|
|
18
|
+
const effect = getEffectFor(entityName, aggregateRelationField, eventEntityName, schema, options);
|
|
19
19
|
effects[eventEntityName].push(effect);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
function getEffectFor(entityName, aggregateRelationField, eventEntityName, schema) {
|
|
22
|
+
function getEffectFor(entityName, aggregateRelationField, eventEntityName, schema, options) {
|
|
23
23
|
return {
|
|
24
24
|
async beforePut(context, docs, ctx) {
|
|
25
25
|
const docsByAggId = {};
|
|
@@ -52,7 +52,10 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
52
52
|
const existingAggregatesById = _.keyBy(existingAggregates, "id");
|
|
53
53
|
const result = [];
|
|
54
54
|
for (const aggId in docsByAggId) {
|
|
55
|
-
|
|
55
|
+
let events = _.orderBy([...docsByAggId[aggId], ...existingEventsByAggId[aggId] || []], ["date"], "asc");
|
|
56
|
+
if (options.applyEventIf) {
|
|
57
|
+
events = events.filter((ev) => options.applyEventIf(ev, context, ctx));
|
|
58
|
+
}
|
|
56
59
|
if (events[0].type !== "creation")
|
|
57
60
|
throw new Error(`First event must have type = "creation". (type: ${events[0].type}, id: ${events[0].id})`);
|
|
58
61
|
if (events.slice(1).some((ev) => ev.type === "creation")) {
|