rads-db 3.2.6 → 3.2.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 +57 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +57 -13
- package/dist/{types-17bcd41b.d.ts → types-131986eb.d.ts} +7 -3
- package/drivers/azureCosmos.cjs +0 -2
- package/drivers/azureCosmos.mjs +0 -2
- package/drivers/sql.cjs +0 -1
- package/drivers/sql.mjs +0 -1
- package/features/eventSourcing.cjs +2 -1
- package/features/eventSourcing.mjs +2 -1
- package/integrations/cli.cjs +0 -0
- package/package.json +10 -17
package/dist/config.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -383,6 +383,21 @@ function prepareArgs(args) {
|
|
|
383
383
|
return { where, orderByProperties, orderByDirections, maxItemCount, cursor: args.cursor, pick: args.include };
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
function getEnabledEffects(effects, ctx) {
|
|
387
|
+
const { excludeFeatures, includeFeatures } = ctx;
|
|
388
|
+
if (excludeFeatures && includeFeatures) {
|
|
389
|
+
throw new Error("Cannot use both excludeFeatures and includeFeatures together");
|
|
390
|
+
}
|
|
391
|
+
const systemEffects = effects.filter((ef) => ef.featureName.startsWith("_"));
|
|
392
|
+
const featureEffects = effects.filter((ef) => !ef.featureName.startsWith("_"));
|
|
393
|
+
if (includeFeatures) {
|
|
394
|
+
return [...systemEffects, ...featureEffects.filter((ef) => includeFeatures.includes(ef.featureName))];
|
|
395
|
+
}
|
|
396
|
+
if (excludeFeatures) {
|
|
397
|
+
return [...systemEffects, ...featureEffects.filter((ef) => !excludeFeatures.includes(ef.featureName))];
|
|
398
|
+
}
|
|
399
|
+
return effects;
|
|
400
|
+
}
|
|
386
401
|
const computedPresets = {
|
|
387
402
|
createdAt: ({ fieldName, doc, oldDoc }) => {
|
|
388
403
|
return oldDoc?.[fieldName] || (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -503,6 +518,7 @@ function verifyComputedPresense(schema, computed, effects) {
|
|
|
503
518
|
}
|
|
504
519
|
for (const dependencyEntity in handler.recomputeWhen) {
|
|
505
520
|
effects[dependencyEntity].push({
|
|
521
|
+
featureName: "_computed",
|
|
506
522
|
async afterPut(computedContext, docs, ctx) {
|
|
507
523
|
const conditionResult = handler.recomputeWhen[dependencyEntity](docs);
|
|
508
524
|
if (!conditionResult)
|
|
@@ -546,13 +562,19 @@ function verifyComputedPresense(schema, computed, effects) {
|
|
|
546
562
|
async function handleEffectsBeforePut(context, docs, ctx) {
|
|
547
563
|
if (context.drivers[context.typeName]?.driverName === "restApi")
|
|
548
564
|
return [];
|
|
549
|
-
|
|
565
|
+
const effects = getEnabledEffects(context.effects[context.typeName], ctx);
|
|
566
|
+
return Promise.all(effects.map((ef) => ef.beforePut?.(context, docs, ctx)));
|
|
550
567
|
}
|
|
551
568
|
async function handleEffectsAfterPut(context, docs, beforePutResults, ctx) {
|
|
552
569
|
if (context.drivers[context.typeName]?.driverName === "restApi")
|
|
553
570
|
return [];
|
|
571
|
+
const allEffects = context.effects[context.typeName];
|
|
572
|
+
const enabledEffects = getEnabledEffects(allEffects, ctx);
|
|
554
573
|
return Promise.all(
|
|
555
|
-
|
|
574
|
+
enabledEffects.map((ef) => {
|
|
575
|
+
const originalIndex = allEffects.indexOf(ef);
|
|
576
|
+
return ef.afterPut(context, docs, beforePutResults[originalIndex], ctx);
|
|
577
|
+
})
|
|
556
578
|
);
|
|
557
579
|
}
|
|
558
580
|
|
|
@@ -630,11 +652,12 @@ function verifyRelationsSetup(schema, effects) {
|
|
|
630
652
|
for (const fName in entity.fields) {
|
|
631
653
|
const f = entity.fields[fName];
|
|
632
654
|
const denormFields = [];
|
|
633
|
-
if (!f.isRelation || !denormFields)
|
|
655
|
+
if (!f.isRelation || !denormFields?.length)
|
|
634
656
|
continue;
|
|
635
657
|
if (!newEffects[f.type])
|
|
636
658
|
newEffects[f.type] = [];
|
|
637
659
|
newEffects[f.type].push({
|
|
660
|
+
featureName: "_relations",
|
|
638
661
|
async afterPut(context, docs, beforePutResult, ctx) {
|
|
639
662
|
const { drivers } = context;
|
|
640
663
|
const changedDocs = docs.filter((d) => denormFields.some((f2) => !___default.isEqual(d.doc[f2], d.oldDoc?.[f2])));
|
|
@@ -671,6 +694,7 @@ function verifyRelationsSetup(schema, effects) {
|
|
|
671
694
|
}
|
|
672
695
|
for (const relatedEntityName in newEffects) {
|
|
673
696
|
effects[relatedEntityName].push({
|
|
697
|
+
featureName: "_relations",
|
|
674
698
|
async afterPut(computedContext, docs, beforePutResult, ctx) {
|
|
675
699
|
for (const effect of newEffects[relatedEntityName]) {
|
|
676
700
|
await effect.afterPut(computedContext, docs, beforePutResult, ctx);
|
|
@@ -860,10 +884,10 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
|
|
|
860
884
|
}
|
|
861
885
|
await radsDbRelations.fillDenormFieldsBeforePut(computedContext, docArgsToSave, ctx);
|
|
862
886
|
const docsToSave = docArgsToSave.map((x) => x.doc);
|
|
863
|
-
await driverInstance.putMany(docsToSave, ctx);
|
|
887
|
+
const putManyResponse = await driverInstance.putMany(docsToSave, ctx);
|
|
864
888
|
await handleEffectsAfterPut(computedContext, docArgsToSave, beforePutResults, ctx);
|
|
865
889
|
await afterPut(docArgsToSave, ctx, computedContext);
|
|
866
|
-
return docsToSave;
|
|
890
|
+
return putManyResponse || docsToSave;
|
|
867
891
|
}
|
|
868
892
|
async function verifyMany(args, ctx) {
|
|
869
893
|
if (driverInstance.verifyMany) {
|
|
@@ -1047,25 +1071,44 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
|
|
|
1047
1071
|
}
|
|
1048
1072
|
return result;
|
|
1049
1073
|
}
|
|
1074
|
+
function getEnabledFeatures(allFeatures, ctx) {
|
|
1075
|
+
if (!ctx)
|
|
1076
|
+
return allFeatures;
|
|
1077
|
+
const { excludeFeatures, includeFeatures } = ctx;
|
|
1078
|
+
if (excludeFeatures && includeFeatures) {
|
|
1079
|
+
throw new Error("Cannot use both excludeFeatures and includeFeatures together");
|
|
1080
|
+
}
|
|
1081
|
+
if (includeFeatures) {
|
|
1082
|
+
return allFeatures.filter((f) => includeFeatures.includes(f.name));
|
|
1083
|
+
}
|
|
1084
|
+
if (excludeFeatures) {
|
|
1085
|
+
return allFeatures.filter((f) => !excludeFeatures.includes(f.name));
|
|
1086
|
+
}
|
|
1087
|
+
return allFeatures;
|
|
1088
|
+
}
|
|
1050
1089
|
async function beforeGet(args, ctx, computedContext) {
|
|
1051
|
-
|
|
1090
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1091
|
+
for (const f of enabledFeatures) {
|
|
1052
1092
|
const result = await f.beforeGet?.(args, ctx, computedContext);
|
|
1053
1093
|
if (result)
|
|
1054
1094
|
return result;
|
|
1055
1095
|
}
|
|
1056
1096
|
}
|
|
1057
1097
|
async function afterGet(items, args, ctx, computedContext) {
|
|
1058
|
-
|
|
1098
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1099
|
+
for (const f of enabledFeatures) {
|
|
1059
1100
|
await f.afterGet?.(items, args, ctx, computedContext);
|
|
1060
1101
|
}
|
|
1061
1102
|
}
|
|
1062
1103
|
async function beforePut(items, ctx, computedContext) {
|
|
1063
|
-
|
|
1104
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1105
|
+
for (const f of enabledFeatures) {
|
|
1064
1106
|
await f.beforePut?.(items, ctx, computedContext);
|
|
1065
1107
|
}
|
|
1066
1108
|
}
|
|
1067
1109
|
async function afterPut(items, ctx, computedContext) {
|
|
1068
|
-
|
|
1110
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1111
|
+
for (const f of enabledFeatures) {
|
|
1069
1112
|
await f.afterPut?.(items, ctx, computedContext);
|
|
1070
1113
|
}
|
|
1071
1114
|
}
|
|
@@ -1088,16 +1131,17 @@ function generateMethods(schema, validators, options) {
|
|
|
1088
1131
|
const db = {
|
|
1089
1132
|
_schema: schema,
|
|
1090
1133
|
_radsUiSlots: getRadsUiSlots(opts.features),
|
|
1091
|
-
async uploadFile(args) {
|
|
1092
|
-
|
|
1134
|
+
async uploadFile(args, ctx) {
|
|
1135
|
+
const enabledFeatures = getEnabledFeatures(opts.features, ctx);
|
|
1136
|
+
for (const f of enabledFeatures) {
|
|
1093
1137
|
const result2 = await f.beforeUploadFile?.(args);
|
|
1094
1138
|
if (result2)
|
|
1095
1139
|
return result2;
|
|
1096
1140
|
}
|
|
1097
1141
|
if (!opts.fileUploadDriver)
|
|
1098
1142
|
throw new Error(`Missing configuration. Please specify "fileUploadDriver" argument in "createRads()".`);
|
|
1099
|
-
const result = await opts.fileUploadDriver.uploadFile(args);
|
|
1100
|
-
for (const f of
|
|
1143
|
+
const result = await opts.fileUploadDriver.uploadFile(args, ctx);
|
|
1144
|
+
for (const f of enabledFeatures) {
|
|
1101
1145
|
await f.afterUploadFile?.(result, args);
|
|
1102
1146
|
}
|
|
1103
1147
|
return result;
|
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 { O as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, ak as DeepKeys, af as DeepPartial, ad as DeepPartialWithNulls, ae as DeepPartialWithNullsItem, al as EntityMethods, w as EnumDefinition, v as FieldDefinition, J as FileSystemNode, u as FileUploadArgs, q as FileUploadDriver, p as FileUploadResult, H as GenerateClientNormalizedOptions, B as GenerateClientOptions, a9 as Get, $ as GetAggArgs, a0 as GetAggArgsAgg, a3 as GetAggArgsAny, a6 as GetAggResponse, _ as GetArgs, a2 as GetArgsAny, a5 as GetArgsInclude, Q as GetManyArgs, a1 as GetManyArgsAny, a7 as GetManyResponse, a8 as GetResponse, aa as GetResponseInclude, ab as GetResponseIncludeSelect, ac as GetResponseNoInclude, s as GetRestRoutesArgs, G as GetRestRoutesOptions, t as GetRestRoutesResponse, ah as InverseRelation, M as MinimalDriver, aj as Put, ai as PutArgs, P as PutEffect, g as RadsConfig, h as RadsConfigDataSource, r as RadsDbInstance, N as RadsFeature, y as RadsHookDoc, L as RadsUiSlotDefinition, K as RadsUiSlotName, I as RadsVitePluginOptions, ag as Relation, i as RequiredFields, l as RestDriverOptions, A as RestFileUploadDriverOptions, n as SchemaLoadResult, o as SchemaValidators, z as SqlDriverOptions, T as TypeDefinition, j as ValidateStringDecoratorArgs, X as VerifyManyArgs, a4 as VerifyManyArgsAny, Y as VerifyManyResponse, Z 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-131986eb.js';
|
|
2
|
+
export { O as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, ak as DeepKeys, af as DeepPartial, ad as DeepPartialWithNulls, ae as DeepPartialWithNullsItem, al as EntityMethods, w as EnumDefinition, v as FieldDefinition, J as FileSystemNode, u as FileUploadArgs, q as FileUploadDriver, p as FileUploadResult, H as GenerateClientNormalizedOptions, B as GenerateClientOptions, a9 as Get, $ as GetAggArgs, a0 as GetAggArgsAgg, a3 as GetAggArgsAny, a6 as GetAggResponse, _ as GetArgs, a2 as GetArgsAny, a5 as GetArgsInclude, Q as GetManyArgs, a1 as GetManyArgsAny, a7 as GetManyResponse, a8 as GetResponse, aa as GetResponseInclude, ab as GetResponseIncludeSelect, ac as GetResponseNoInclude, s as GetRestRoutesArgs, G as GetRestRoutesOptions, t as GetRestRoutesResponse, ah as InverseRelation, M as MinimalDriver, aj as Put, ai as PutArgs, P as PutEffect, g as RadsConfig, h as RadsConfigDataSource, r as RadsDbInstance, N as RadsFeature, y as RadsHookDoc, L as RadsUiSlotDefinition, K as RadsUiSlotName, I as RadsVitePluginOptions, ag as Relation, i as RequiredFields, l as RestDriverOptions, A as RestFileUploadDriverOptions, n as SchemaLoadResult, o as SchemaValidators, z as SqlDriverOptions, T as TypeDefinition, j as ValidateStringDecoratorArgs, X as VerifyManyArgs, a4 as VerifyManyArgsAny, Y as VerifyManyResponse, Z as Where, W as WhereJsonContains } from './types-131986eb.js';
|
|
3
3
|
import { RadsDb } from '_rads-db';
|
|
4
4
|
export { RadsDb } from '_rads-db';
|
|
5
5
|
import 'mssql';
|
package/dist/index.mjs
CHANGED
|
@@ -376,6 +376,21 @@ function prepareArgs(args) {
|
|
|
376
376
|
return { where, orderByProperties, orderByDirections, maxItemCount, cursor: args.cursor, pick: args.include };
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
+
function getEnabledEffects(effects, ctx) {
|
|
380
|
+
const { excludeFeatures, includeFeatures } = ctx;
|
|
381
|
+
if (excludeFeatures && includeFeatures) {
|
|
382
|
+
throw new Error("Cannot use both excludeFeatures and includeFeatures together");
|
|
383
|
+
}
|
|
384
|
+
const systemEffects = effects.filter((ef) => ef.featureName.startsWith("_"));
|
|
385
|
+
const featureEffects = effects.filter((ef) => !ef.featureName.startsWith("_"));
|
|
386
|
+
if (includeFeatures) {
|
|
387
|
+
return [...systemEffects, ...featureEffects.filter((ef) => includeFeatures.includes(ef.featureName))];
|
|
388
|
+
}
|
|
389
|
+
if (excludeFeatures) {
|
|
390
|
+
return [...systemEffects, ...featureEffects.filter((ef) => !excludeFeatures.includes(ef.featureName))];
|
|
391
|
+
}
|
|
392
|
+
return effects;
|
|
393
|
+
}
|
|
379
394
|
const computedPresets = {
|
|
380
395
|
createdAt: ({ fieldName, doc, oldDoc }) => {
|
|
381
396
|
return oldDoc?.[fieldName] || (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -496,6 +511,7 @@ function verifyComputedPresense(schema, computed, effects) {
|
|
|
496
511
|
}
|
|
497
512
|
for (const dependencyEntity in handler.recomputeWhen) {
|
|
498
513
|
effects[dependencyEntity].push({
|
|
514
|
+
featureName: "_computed",
|
|
499
515
|
async afterPut(computedContext, docs, ctx) {
|
|
500
516
|
const conditionResult = handler.recomputeWhen[dependencyEntity](docs);
|
|
501
517
|
if (!conditionResult)
|
|
@@ -539,13 +555,19 @@ function verifyComputedPresense(schema, computed, effects) {
|
|
|
539
555
|
async function handleEffectsBeforePut(context, docs, ctx) {
|
|
540
556
|
if (context.drivers[context.typeName]?.driverName === "restApi")
|
|
541
557
|
return [];
|
|
542
|
-
|
|
558
|
+
const effects = getEnabledEffects(context.effects[context.typeName], ctx);
|
|
559
|
+
return Promise.all(effects.map((ef) => ef.beforePut?.(context, docs, ctx)));
|
|
543
560
|
}
|
|
544
561
|
async function handleEffectsAfterPut(context, docs, beforePutResults, ctx) {
|
|
545
562
|
if (context.drivers[context.typeName]?.driverName === "restApi")
|
|
546
563
|
return [];
|
|
564
|
+
const allEffects = context.effects[context.typeName];
|
|
565
|
+
const enabledEffects = getEnabledEffects(allEffects, ctx);
|
|
547
566
|
return Promise.all(
|
|
548
|
-
|
|
567
|
+
enabledEffects.map((ef) => {
|
|
568
|
+
const originalIndex = allEffects.indexOf(ef);
|
|
569
|
+
return ef.afterPut(context, docs, beforePutResults[originalIndex], ctx);
|
|
570
|
+
})
|
|
549
571
|
);
|
|
550
572
|
}
|
|
551
573
|
|
|
@@ -623,11 +645,12 @@ function verifyRelationsSetup(schema, effects) {
|
|
|
623
645
|
for (const fName in entity.fields) {
|
|
624
646
|
const f = entity.fields[fName];
|
|
625
647
|
const denormFields = [];
|
|
626
|
-
if (!f.isRelation || !denormFields)
|
|
648
|
+
if (!f.isRelation || !denormFields?.length)
|
|
627
649
|
continue;
|
|
628
650
|
if (!newEffects[f.type])
|
|
629
651
|
newEffects[f.type] = [];
|
|
630
652
|
newEffects[f.type].push({
|
|
653
|
+
featureName: "_relations",
|
|
631
654
|
async afterPut(context, docs, beforePutResult, ctx) {
|
|
632
655
|
const { drivers } = context;
|
|
633
656
|
const changedDocs = docs.filter((d) => denormFields.some((f2) => !_.isEqual(d.doc[f2], d.oldDoc?.[f2])));
|
|
@@ -664,6 +687,7 @@ function verifyRelationsSetup(schema, effects) {
|
|
|
664
687
|
}
|
|
665
688
|
for (const relatedEntityName in newEffects) {
|
|
666
689
|
effects[relatedEntityName].push({
|
|
690
|
+
featureName: "_relations",
|
|
667
691
|
async afterPut(computedContext, docs, beforePutResult, ctx) {
|
|
668
692
|
for (const effect of newEffects[relatedEntityName]) {
|
|
669
693
|
await effect.afterPut(computedContext, docs, beforePutResult, ctx);
|
|
@@ -853,10 +877,10 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
|
|
|
853
877
|
}
|
|
854
878
|
await radsDbRelations.fillDenormFieldsBeforePut(computedContext, docArgsToSave, ctx);
|
|
855
879
|
const docsToSave = docArgsToSave.map((x) => x.doc);
|
|
856
|
-
await driverInstance.putMany(docsToSave, ctx);
|
|
880
|
+
const putManyResponse = await driverInstance.putMany(docsToSave, ctx);
|
|
857
881
|
await handleEffectsAfterPut(computedContext, docArgsToSave, beforePutResults, ctx);
|
|
858
882
|
await afterPut(docArgsToSave, ctx, computedContext);
|
|
859
|
-
return docsToSave;
|
|
883
|
+
return putManyResponse || docsToSave;
|
|
860
884
|
}
|
|
861
885
|
async function verifyMany(args, ctx) {
|
|
862
886
|
if (driverInstance.verifyMany) {
|
|
@@ -1040,25 +1064,44 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
|
|
|
1040
1064
|
}
|
|
1041
1065
|
return result;
|
|
1042
1066
|
}
|
|
1067
|
+
function getEnabledFeatures(allFeatures, ctx) {
|
|
1068
|
+
if (!ctx)
|
|
1069
|
+
return allFeatures;
|
|
1070
|
+
const { excludeFeatures, includeFeatures } = ctx;
|
|
1071
|
+
if (excludeFeatures && includeFeatures) {
|
|
1072
|
+
throw new Error("Cannot use both excludeFeatures and includeFeatures together");
|
|
1073
|
+
}
|
|
1074
|
+
if (includeFeatures) {
|
|
1075
|
+
return allFeatures.filter((f) => includeFeatures.includes(f.name));
|
|
1076
|
+
}
|
|
1077
|
+
if (excludeFeatures) {
|
|
1078
|
+
return allFeatures.filter((f) => !excludeFeatures.includes(f.name));
|
|
1079
|
+
}
|
|
1080
|
+
return allFeatures;
|
|
1081
|
+
}
|
|
1043
1082
|
async function beforeGet(args, ctx, computedContext) {
|
|
1044
|
-
|
|
1083
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1084
|
+
for (const f of enabledFeatures) {
|
|
1045
1085
|
const result = await f.beforeGet?.(args, ctx, computedContext);
|
|
1046
1086
|
if (result)
|
|
1047
1087
|
return result;
|
|
1048
1088
|
}
|
|
1049
1089
|
}
|
|
1050
1090
|
async function afterGet(items, args, ctx, computedContext) {
|
|
1051
|
-
|
|
1091
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1092
|
+
for (const f of enabledFeatures) {
|
|
1052
1093
|
await f.afterGet?.(items, args, ctx, computedContext);
|
|
1053
1094
|
}
|
|
1054
1095
|
}
|
|
1055
1096
|
async function beforePut(items, ctx, computedContext) {
|
|
1056
|
-
|
|
1097
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1098
|
+
for (const f of enabledFeatures) {
|
|
1057
1099
|
await f.beforePut?.(items, ctx, computedContext);
|
|
1058
1100
|
}
|
|
1059
1101
|
}
|
|
1060
1102
|
async function afterPut(items, ctx, computedContext) {
|
|
1061
|
-
|
|
1103
|
+
const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
|
|
1104
|
+
for (const f of enabledFeatures) {
|
|
1062
1105
|
await f.afterPut?.(items, ctx, computedContext);
|
|
1063
1106
|
}
|
|
1064
1107
|
}
|
|
@@ -1081,16 +1124,17 @@ function generateMethods(schema, validators, options) {
|
|
|
1081
1124
|
const db = {
|
|
1082
1125
|
_schema: schema,
|
|
1083
1126
|
_radsUiSlots: getRadsUiSlots(opts.features),
|
|
1084
|
-
async uploadFile(args) {
|
|
1085
|
-
|
|
1127
|
+
async uploadFile(args, ctx) {
|
|
1128
|
+
const enabledFeatures = getEnabledFeatures(opts.features, ctx);
|
|
1129
|
+
for (const f of enabledFeatures) {
|
|
1086
1130
|
const result2 = await f.beforeUploadFile?.(args);
|
|
1087
1131
|
if (result2)
|
|
1088
1132
|
return result2;
|
|
1089
1133
|
}
|
|
1090
1134
|
if (!opts.fileUploadDriver)
|
|
1091
1135
|
throw new Error(`Missing configuration. Please specify "fileUploadDriver" argument in "createRads()".`);
|
|
1092
|
-
const result = await opts.fileUploadDriver.uploadFile(args);
|
|
1093
|
-
for (const f of
|
|
1136
|
+
const result = await opts.fileUploadDriver.uploadFile(args, ctx);
|
|
1137
|
+
for (const f of enabledFeatures) {
|
|
1094
1138
|
await f.afterUploadFile?.(result, args);
|
|
1095
1139
|
}
|
|
1096
1140
|
return result;
|
|
@@ -34,8 +34,7 @@ interface GetArgs<EN extends keyof EntityMeta> {
|
|
|
34
34
|
where?: Where<EN>;
|
|
35
35
|
include?: GetArgsInclude<EN>;
|
|
36
36
|
}
|
|
37
|
-
interface GetAggArgs<EN extends keyof EntityMeta> {
|
|
38
|
-
where?: Where<EN>;
|
|
37
|
+
interface GetAggArgs<EN extends keyof EntityMeta> extends Omit<GetManyArgs<EN>, 'include'> {
|
|
39
38
|
agg: GetAggArgsAgg<EN>;
|
|
40
39
|
}
|
|
41
40
|
type GetAggArgsAgg<EN extends keyof EntityMeta, F extends string = EntityMeta[EN]['aggregates']> = ('_count' | `${F}_min` | `${F}_max` | `${F}_sum`)[];
|
|
@@ -101,7 +100,7 @@ type Relation<T extends {
|
|
|
101
100
|
* Note: this field is not stored in the database at all. Returns up to 100 items and doesn't support pagination
|
|
102
101
|
* If you need more control, please, use separate request instead.
|
|
103
102
|
*/
|
|
104
|
-
type InverseRelation<EN extends keyof EntityMeta
|
|
103
|
+
type InverseRelation<EN extends keyof EntityMeta> = EntityMeta[EN]['type'];
|
|
105
104
|
type PutArgs<T> = {
|
|
106
105
|
id: string;
|
|
107
106
|
} & DeepPartialWithNulls<T>;
|
|
@@ -374,6 +373,7 @@ interface RadsHookDoc {
|
|
|
374
373
|
updatedEvents?: any[];
|
|
375
374
|
}
|
|
376
375
|
interface PutEffect {
|
|
376
|
+
featureName: string;
|
|
377
377
|
beforePut?: (computedContext: ComputedContext, docs: RadsHookDoc[], ctx: RadsRequestContext) => MaybePromise<any>;
|
|
378
378
|
afterPut: (computedContext: ComputedContext, docs: RadsHookDoc[], beforePutResult: any, ctx: RadsRequestContext) => MaybePromise<any>;
|
|
379
379
|
}
|
|
@@ -429,6 +429,10 @@ interface RadsRequestContext {
|
|
|
429
429
|
method?: 'get' | 'getAll' | 'getMany' | 'getAgg' | 'put' | 'putMany' | 'deleteMany' | 'deleteAll';
|
|
430
430
|
/** if true, all cache layers will be bypassed */
|
|
431
431
|
noCache?: boolean;
|
|
432
|
+
/** Skip these features for this request (blacklist) */
|
|
433
|
+
excludeFeatures?: string[];
|
|
434
|
+
/** Run only these features, skip all others (whitelist). Cannot be used together with excludeFeatures */
|
|
435
|
+
includeFeatures?: string[];
|
|
432
436
|
[key: string]: any;
|
|
433
437
|
}
|
|
434
438
|
interface FileSystemNode {
|
package/drivers/azureCosmos.cjs
CHANGED
|
@@ -99,12 +99,10 @@ var _default = options => (schema, entity) => {
|
|
|
99
99
|
getMany,
|
|
100
100
|
async getAgg(args, ctx) {
|
|
101
101
|
args = args || {};
|
|
102
|
-
const where = args.where || {};
|
|
103
102
|
const {
|
|
104
103
|
query,
|
|
105
104
|
parameters
|
|
106
105
|
} = getCosmosQuery(schema, entity, args);
|
|
107
|
-
let cursor;
|
|
108
106
|
const response = client.items.query({
|
|
109
107
|
query,
|
|
110
108
|
parameters: Object.keys(parameters).map(k => ({
|
package/drivers/azureCosmos.mjs
CHANGED
|
@@ -66,9 +66,7 @@ export default (options) => (schema, entity) => {
|
|
|
66
66
|
getMany,
|
|
67
67
|
async getAgg(args, ctx) {
|
|
68
68
|
args = args || {};
|
|
69
|
-
const where = args.where || {};
|
|
70
69
|
const { query, parameters } = getCosmosQuery(schema, entity, args);
|
|
71
|
-
let cursor;
|
|
72
70
|
const response = client.items.query(
|
|
73
71
|
{
|
|
74
72
|
query,
|
package/drivers/sql.cjs
CHANGED
|
@@ -13,7 +13,6 @@ const strType = "VARCHAR(MAX)";
|
|
|
13
13
|
const numberType = "DECIMAL(30,15)";
|
|
14
14
|
const booleanType = "BIT";
|
|
15
15
|
const simpleSubclauseRegex = /^[a-z0-9_@]+.[a-z0-9_@]+ = [a-z0-9_@.]+$/i;
|
|
16
|
-
const sanitizePathRegex = /^[a-z0-9_\[\]\.]+$/i;
|
|
17
16
|
const operatorHandlers = {
|
|
18
17
|
some: (ctx, parameters, whereArgs) => {
|
|
19
18
|
const {
|
package/drivers/sql.mjs
CHANGED
|
@@ -6,7 +6,6 @@ const strType = "VARCHAR(MAX)";
|
|
|
6
6
|
const numberType = "DECIMAL(30,15)";
|
|
7
7
|
const booleanType = "BIT";
|
|
8
8
|
const simpleSubclauseRegex = /^[a-z0-9_@]+.[a-z0-9_@]+ = [a-z0-9_@.]+$/i;
|
|
9
|
-
const sanitizePathRegex = /^[a-z0-9_\[\]\.]+$/i;
|
|
10
9
|
const operatorHandlers = {
|
|
11
10
|
some: (ctx, parameters, whereArgs) => {
|
|
12
11
|
const { name, namePrefix, paramNamePrefix, paramName, whereVal } = whereArgs;
|
|
@@ -29,6 +29,7 @@ function verifyEventSourcingSetup(schema, effects, options) {
|
|
|
29
29
|
}
|
|
30
30
|
function getEffectFor(entityName, aggregateRelationField, eventEntityName, schema, options) {
|
|
31
31
|
return {
|
|
32
|
+
featureName: "eventSourcing",
|
|
32
33
|
async beforePut(context, docs, ctx) {
|
|
33
34
|
const docsByAggId = {};
|
|
34
35
|
const docsById = {};
|
|
@@ -62,7 +63,7 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
62
63
|
const existingAggregatesById = _lodash.default.keyBy(existingAggregates, "id");
|
|
63
64
|
const result = [];
|
|
64
65
|
for (const aggId in docsByAggId) {
|
|
65
|
-
|
|
66
|
+
const events = _lodash.default.orderBy([...docsByAggId[aggId], ...(existingEventsByAggId[aggId] || [])], ["date"], "asc");
|
|
66
67
|
if (events[0].type !== "creation") throw new Error(`First event must have type = "creation". (type: ${events[0].type}, id: ${events[0].id})`);
|
|
67
68
|
if (events.slice(1).some(ev => ev.type === "creation")) {
|
|
68
69
|
throw new Error(`Only first event may have type = "creation"`);
|
|
@@ -21,6 +21,7 @@ function verifyEventSourcingSetup(schema, effects, options) {
|
|
|
21
21
|
}
|
|
22
22
|
function getEffectFor(entityName, aggregateRelationField, eventEntityName, schema, options) {
|
|
23
23
|
return {
|
|
24
|
+
featureName: "eventSourcing",
|
|
24
25
|
async beforePut(context, docs, ctx) {
|
|
25
26
|
const docsByAggId = {};
|
|
26
27
|
const docsById = {};
|
|
@@ -52,7 +53,7 @@ function getEffectFor(entityName, aggregateRelationField, eventEntityName, schem
|
|
|
52
53
|
const existingAggregatesById = _.keyBy(existingAggregates, "id");
|
|
53
54
|
const result = [];
|
|
54
55
|
for (const aggId in docsByAggId) {
|
|
55
|
-
|
|
56
|
+
const events = _.orderBy([...docsByAggId[aggId], ...existingEventsByAggId[aggId] || []], ["date"], "asc");
|
|
56
57
|
if (events[0].type !== "creation")
|
|
57
58
|
throw new Error(`First event must have type = "creation". (type: ${events[0].type}, id: ${events[0].id})`);
|
|
58
59
|
if (events.slice(1).some((ev) => ev.type === "creation")) {
|
package/integrations/cli.cjs
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rads-db",
|
|
3
|
-
"version": "3.2.
|
|
4
|
-
"packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac",
|
|
3
|
+
"version": "3.2.7",
|
|
5
4
|
"description": "Say goodbye to boilerplate code and hello to efficient and elegant syntax.",
|
|
6
5
|
"author": "",
|
|
7
6
|
"license": "ISC",
|
|
@@ -51,16 +50,6 @@
|
|
|
51
50
|
"integrations",
|
|
52
51
|
"features"
|
|
53
52
|
],
|
|
54
|
-
"scripts": {
|
|
55
|
-
"prepublishOnly": "pnpm build",
|
|
56
|
-
"test": "vitest --run && vitest typecheck --run",
|
|
57
|
-
"link-rads-db": "symlink-dir ./test/_rads-db ./node_modules/_rads-db",
|
|
58
|
-
"generate-test-schema": "jiti ./src/integrations/cli",
|
|
59
|
-
"dev": "pnpm install && pnpm link-rads-db && pnpm build && pnpm generate-test-schema && vitest --ui --test-timeout 300000 --typecheck",
|
|
60
|
-
"lint": "cross-env NODE_ENV=production eslint src/**/*.* test/**/*.*",
|
|
61
|
-
"typecheck": "tsc --noEmit",
|
|
62
|
-
"build": "unbuild"
|
|
63
|
-
},
|
|
64
53
|
"peerDependencies": {
|
|
65
54
|
"@azure/cosmos": ">=3",
|
|
66
55
|
"@azure/storage-blob": ">=12",
|
|
@@ -122,9 +111,13 @@
|
|
|
122
111
|
"vite": "^4.0.0",
|
|
123
112
|
"vitest": "^1.6.0"
|
|
124
113
|
},
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
114
|
+
"scripts": {
|
|
115
|
+
"test": "vitest --run --typecheck",
|
|
116
|
+
"link-rads-db": "symlink-dir ./test/_rads-db ./node_modules/_rads-db",
|
|
117
|
+
"generate-test-schema": "jiti ./src/integrations/cli",
|
|
118
|
+
"dev": "pnpm install && pnpm link-rads-db && pnpm build && pnpm generate-test-schema && vitest --ui --test-timeout 300000 --typecheck",
|
|
119
|
+
"lint": "cross-env NODE_ENV=production eslint src/**/*.* test/**/*.*",
|
|
120
|
+
"typecheck": "tsc --noEmit",
|
|
121
|
+
"build": "unbuild"
|
|
129
122
|
}
|
|
130
|
-
}
|
|
123
|
+
}
|