rads-db 3.2.6 → 3.2.8

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 CHANGED
@@ -1,4 +1,4 @@
1
- import { g as RadsConfig, T as TypeDefinition } from './types-17bcd41b.js';
1
+ import { g as RadsConfig, T as TypeDefinition } from './types-efed26f9.js';
2
2
  import 'mssql';
3
3
  import '_rads-db';
4
4
 
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();
@@ -421,6 +436,9 @@ async function handlePrecomputed(context, docs, ctx) {
421
436
  const { precomputedFields, nestedTypeFields, fields } = schema[typeName];
422
437
  const computed = options.computed;
423
438
  for (const fieldName of precomputedFields || []) {
439
+ if (ctx.skipPrecomputed?.includes(fieldName)) {
440
+ continue;
441
+ }
424
442
  const typeComputed = computed[typeName];
425
443
  let handler = typeComputed?.[fieldName];
426
444
  if (!handler) {
@@ -503,6 +521,7 @@ function verifyComputedPresense(schema, computed, effects) {
503
521
  }
504
522
  for (const dependencyEntity in handler.recomputeWhen) {
505
523
  effects[dependencyEntity].push({
524
+ featureName: "_computed",
506
525
  async afterPut(computedContext, docs, ctx) {
507
526
  const conditionResult = handler.recomputeWhen[dependencyEntity](docs);
508
527
  if (!conditionResult)
@@ -546,13 +565,19 @@ function verifyComputedPresense(schema, computed, effects) {
546
565
  async function handleEffectsBeforePut(context, docs, ctx) {
547
566
  if (context.drivers[context.typeName]?.driverName === "restApi")
548
567
  return [];
549
- return Promise.all(context.effects[context.typeName].map((ef) => ef.beforePut?.(context, docs, ctx)));
568
+ const effects = getEnabledEffects(context.effects[context.typeName], ctx);
569
+ return Promise.all(effects.map((ef) => ef.beforePut?.(context, docs, ctx)));
550
570
  }
551
571
  async function handleEffectsAfterPut(context, docs, beforePutResults, ctx) {
552
572
  if (context.drivers[context.typeName]?.driverName === "restApi")
553
573
  return [];
574
+ const allEffects = context.effects[context.typeName];
575
+ const enabledEffects = getEnabledEffects(allEffects, ctx);
554
576
  return Promise.all(
555
- context.effects[context.typeName].map((ef, i) => ef.afterPut(context, docs, beforePutResults[i], ctx))
577
+ enabledEffects.map((ef) => {
578
+ const originalIndex = allEffects.indexOf(ef);
579
+ return ef.afterPut(context, docs, beforePutResults[originalIndex], ctx);
580
+ })
556
581
  );
557
582
  }
558
583
 
@@ -630,11 +655,12 @@ function verifyRelationsSetup(schema, effects) {
630
655
  for (const fName in entity.fields) {
631
656
  const f = entity.fields[fName];
632
657
  const denormFields = [];
633
- if (!f.isRelation || !denormFields)
658
+ if (!f.isRelation || !denormFields?.length)
634
659
  continue;
635
660
  if (!newEffects[f.type])
636
661
  newEffects[f.type] = [];
637
662
  newEffects[f.type].push({
663
+ featureName: "_relations",
638
664
  async afterPut(context, docs, beforePutResult, ctx) {
639
665
  const { drivers } = context;
640
666
  const changedDocs = docs.filter((d) => denormFields.some((f2) => !___default.isEqual(d.doc[f2], d.oldDoc?.[f2])));
@@ -671,6 +697,7 @@ function verifyRelationsSetup(schema, effects) {
671
697
  }
672
698
  for (const relatedEntityName in newEffects) {
673
699
  effects[relatedEntityName].push({
700
+ featureName: "_relations",
674
701
  async afterPut(computedContext, docs, beforePutResult, ctx) {
675
702
  for (const effect of newEffects[relatedEntityName]) {
676
703
  await effect.afterPut(computedContext, docs, beforePutResult, ctx);
@@ -860,10 +887,10 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
860
887
  }
861
888
  await radsDbRelations.fillDenormFieldsBeforePut(computedContext, docArgsToSave, ctx);
862
889
  const docsToSave = docArgsToSave.map((x) => x.doc);
863
- await driverInstance.putMany(docsToSave, ctx);
890
+ const putManyResponse = await driverInstance.putMany(docsToSave, ctx);
864
891
  await handleEffectsAfterPut(computedContext, docArgsToSave, beforePutResults, ctx);
865
892
  await afterPut(docArgsToSave, ctx, computedContext);
866
- return docsToSave;
893
+ return putManyResponse || docsToSave;
867
894
  }
868
895
  async function verifyMany(args, ctx) {
869
896
  if (driverInstance.verifyMany) {
@@ -1047,25 +1074,44 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
1047
1074
  }
1048
1075
  return result;
1049
1076
  }
1077
+ function getEnabledFeatures(allFeatures, ctx) {
1078
+ if (!ctx)
1079
+ return allFeatures;
1080
+ const { excludeFeatures, includeFeatures } = ctx;
1081
+ if (excludeFeatures && includeFeatures) {
1082
+ throw new Error("Cannot use both excludeFeatures and includeFeatures together");
1083
+ }
1084
+ if (includeFeatures) {
1085
+ return allFeatures.filter((f) => includeFeatures.includes(f.name));
1086
+ }
1087
+ if (excludeFeatures) {
1088
+ return allFeatures.filter((f) => !excludeFeatures.includes(f.name));
1089
+ }
1090
+ return allFeatures;
1091
+ }
1050
1092
  async function beforeGet(args, ctx, computedContext) {
1051
- for (const f of computedContext.options.features) {
1093
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1094
+ for (const f of enabledFeatures) {
1052
1095
  const result = await f.beforeGet?.(args, ctx, computedContext);
1053
1096
  if (result)
1054
1097
  return result;
1055
1098
  }
1056
1099
  }
1057
1100
  async function afterGet(items, args, ctx, computedContext) {
1058
- for (const f of computedContext.options.features) {
1101
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1102
+ for (const f of enabledFeatures) {
1059
1103
  await f.afterGet?.(items, args, ctx, computedContext);
1060
1104
  }
1061
1105
  }
1062
1106
  async function beforePut(items, ctx, computedContext) {
1063
- for (const f of computedContext.options.features) {
1107
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1108
+ for (const f of enabledFeatures) {
1064
1109
  await f.beforePut?.(items, ctx, computedContext);
1065
1110
  }
1066
1111
  }
1067
1112
  async function afterPut(items, ctx, computedContext) {
1068
- for (const f of computedContext.options.features) {
1113
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1114
+ for (const f of enabledFeatures) {
1069
1115
  await f.afterPut?.(items, ctx, computedContext);
1070
1116
  }
1071
1117
  }
@@ -1088,16 +1134,17 @@ function generateMethods(schema, validators, options) {
1088
1134
  const db = {
1089
1135
  _schema: schema,
1090
1136
  _radsUiSlots: getRadsUiSlots(opts.features),
1091
- async uploadFile(args) {
1092
- for (const f of opts.features) {
1137
+ async uploadFile(args, ctx) {
1138
+ const enabledFeatures = getEnabledFeatures(opts.features, ctx);
1139
+ for (const f of enabledFeatures) {
1093
1140
  const result2 = await f.beforeUploadFile?.(args);
1094
1141
  if (result2)
1095
1142
  return result2;
1096
1143
  }
1097
1144
  if (!opts.fileUploadDriver)
1098
1145
  throw new Error(`Missing configuration. Please specify "fileUploadDriver" argument in "createRads()".`);
1099
- const result = await opts.fileUploadDriver.uploadFile(args);
1100
- for (const f of opts.features) {
1146
+ const result = await opts.fileUploadDriver.uploadFile(args, ctx);
1147
+ for (const f of enabledFeatures) {
1101
1148
  await f.afterUploadFile?.(result, args);
1102
1149
  }
1103
1150
  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-17bcd41b.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-17bcd41b.js';
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-efed26f9.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-efed26f9.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();
@@ -414,6 +429,9 @@ async function handlePrecomputed(context, docs, ctx) {
414
429
  const { precomputedFields, nestedTypeFields, fields } = schema[typeName];
415
430
  const computed = options.computed;
416
431
  for (const fieldName of precomputedFields || []) {
432
+ if (ctx.skipPrecomputed?.includes(fieldName)) {
433
+ continue;
434
+ }
417
435
  const typeComputed = computed[typeName];
418
436
  let handler = typeComputed?.[fieldName];
419
437
  if (!handler) {
@@ -496,6 +514,7 @@ function verifyComputedPresense(schema, computed, effects) {
496
514
  }
497
515
  for (const dependencyEntity in handler.recomputeWhen) {
498
516
  effects[dependencyEntity].push({
517
+ featureName: "_computed",
499
518
  async afterPut(computedContext, docs, ctx) {
500
519
  const conditionResult = handler.recomputeWhen[dependencyEntity](docs);
501
520
  if (!conditionResult)
@@ -539,13 +558,19 @@ function verifyComputedPresense(schema, computed, effects) {
539
558
  async function handleEffectsBeforePut(context, docs, ctx) {
540
559
  if (context.drivers[context.typeName]?.driverName === "restApi")
541
560
  return [];
542
- return Promise.all(context.effects[context.typeName].map((ef) => ef.beforePut?.(context, docs, ctx)));
561
+ const effects = getEnabledEffects(context.effects[context.typeName], ctx);
562
+ return Promise.all(effects.map((ef) => ef.beforePut?.(context, docs, ctx)));
543
563
  }
544
564
  async function handleEffectsAfterPut(context, docs, beforePutResults, ctx) {
545
565
  if (context.drivers[context.typeName]?.driverName === "restApi")
546
566
  return [];
567
+ const allEffects = context.effects[context.typeName];
568
+ const enabledEffects = getEnabledEffects(allEffects, ctx);
547
569
  return Promise.all(
548
- context.effects[context.typeName].map((ef, i) => ef.afterPut(context, docs, beforePutResults[i], ctx))
570
+ enabledEffects.map((ef) => {
571
+ const originalIndex = allEffects.indexOf(ef);
572
+ return ef.afterPut(context, docs, beforePutResults[originalIndex], ctx);
573
+ })
549
574
  );
550
575
  }
551
576
 
@@ -623,11 +648,12 @@ function verifyRelationsSetup(schema, effects) {
623
648
  for (const fName in entity.fields) {
624
649
  const f = entity.fields[fName];
625
650
  const denormFields = [];
626
- if (!f.isRelation || !denormFields)
651
+ if (!f.isRelation || !denormFields?.length)
627
652
  continue;
628
653
  if (!newEffects[f.type])
629
654
  newEffects[f.type] = [];
630
655
  newEffects[f.type].push({
656
+ featureName: "_relations",
631
657
  async afterPut(context, docs, beforePutResult, ctx) {
632
658
  const { drivers } = context;
633
659
  const changedDocs = docs.filter((d) => denormFields.some((f2) => !_.isEqual(d.doc[f2], d.oldDoc?.[f2])));
@@ -664,6 +690,7 @@ function verifyRelationsSetup(schema, effects) {
664
690
  }
665
691
  for (const relatedEntityName in newEffects) {
666
692
  effects[relatedEntityName].push({
693
+ featureName: "_relations",
667
694
  async afterPut(computedContext, docs, beforePutResult, ctx) {
668
695
  for (const effect of newEffects[relatedEntityName]) {
669
696
  await effect.afterPut(computedContext, docs, beforePutResult, ctx);
@@ -853,10 +880,10 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
853
880
  }
854
881
  await radsDbRelations.fillDenormFieldsBeforePut(computedContext, docArgsToSave, ctx);
855
882
  const docsToSave = docArgsToSave.map((x) => x.doc);
856
- await driverInstance.putMany(docsToSave, ctx);
883
+ const putManyResponse = await driverInstance.putMany(docsToSave, ctx);
857
884
  await handleEffectsAfterPut(computedContext, docArgsToSave, beforePutResults, ctx);
858
885
  await afterPut(docArgsToSave, ctx, computedContext);
859
- return docsToSave;
886
+ return putManyResponse || docsToSave;
860
887
  }
861
888
  async function verifyMany(args, ctx) {
862
889
  if (driverInstance.verifyMany) {
@@ -1040,25 +1067,44 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
1040
1067
  }
1041
1068
  return result;
1042
1069
  }
1070
+ function getEnabledFeatures(allFeatures, ctx) {
1071
+ if (!ctx)
1072
+ return allFeatures;
1073
+ const { excludeFeatures, includeFeatures } = ctx;
1074
+ if (excludeFeatures && includeFeatures) {
1075
+ throw new Error("Cannot use both excludeFeatures and includeFeatures together");
1076
+ }
1077
+ if (includeFeatures) {
1078
+ return allFeatures.filter((f) => includeFeatures.includes(f.name));
1079
+ }
1080
+ if (excludeFeatures) {
1081
+ return allFeatures.filter((f) => !excludeFeatures.includes(f.name));
1082
+ }
1083
+ return allFeatures;
1084
+ }
1043
1085
  async function beforeGet(args, ctx, computedContext) {
1044
- for (const f of computedContext.options.features) {
1086
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1087
+ for (const f of enabledFeatures) {
1045
1088
  const result = await f.beforeGet?.(args, ctx, computedContext);
1046
1089
  if (result)
1047
1090
  return result;
1048
1091
  }
1049
1092
  }
1050
1093
  async function afterGet(items, args, ctx, computedContext) {
1051
- for (const f of computedContext.options.features) {
1094
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1095
+ for (const f of enabledFeatures) {
1052
1096
  await f.afterGet?.(items, args, ctx, computedContext);
1053
1097
  }
1054
1098
  }
1055
1099
  async function beforePut(items, ctx, computedContext) {
1056
- for (const f of computedContext.options.features) {
1100
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1101
+ for (const f of enabledFeatures) {
1057
1102
  await f.beforePut?.(items, ctx, computedContext);
1058
1103
  }
1059
1104
  }
1060
1105
  async function afterPut(items, ctx, computedContext) {
1061
- for (const f of computedContext.options.features) {
1106
+ const enabledFeatures = getEnabledFeatures(computedContext.options.features, ctx);
1107
+ for (const f of enabledFeatures) {
1062
1108
  await f.afterPut?.(items, ctx, computedContext);
1063
1109
  }
1064
1110
  }
@@ -1081,16 +1127,17 @@ function generateMethods(schema, validators, options) {
1081
1127
  const db = {
1082
1128
  _schema: schema,
1083
1129
  _radsUiSlots: getRadsUiSlots(opts.features),
1084
- async uploadFile(args) {
1085
- for (const f of opts.features) {
1130
+ async uploadFile(args, ctx) {
1131
+ const enabledFeatures = getEnabledFeatures(opts.features, ctx);
1132
+ for (const f of enabledFeatures) {
1086
1133
  const result2 = await f.beforeUploadFile?.(args);
1087
1134
  if (result2)
1088
1135
  return result2;
1089
1136
  }
1090
1137
  if (!opts.fileUploadDriver)
1091
1138
  throw new Error(`Missing configuration. Please specify "fileUploadDriver" argument in "createRads()".`);
1092
- const result = await opts.fileUploadDriver.uploadFile(args);
1093
- for (const f of opts.features) {
1139
+ const result = await opts.fileUploadDriver.uploadFile(args, ctx);
1140
+ for (const f of enabledFeatures) {
1094
1141
  await f.afterUploadFile?.(result, args);
1095
1142
  }
1096
1143
  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, _Field extends keyof EntityMeta[EN]['relations']> = EntityMeta[EN]['type'];
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
  }
@@ -425,10 +425,16 @@ interface RadsRequestContext {
425
425
  silent?: boolean;
426
426
  /** Mostly for internal use. When entity name is specified, indicates that calling put* on this entity is allowed, even if it's marked as @precomputed or @readonly */
427
427
  skipPrecomputedCheckFor?: string;
428
+ /** Skip precomputed calculation for these fields and use provided values instead */
429
+ skipPrecomputed?: string[];
428
430
  /** Method that was called - get, getAll, getMany, getAgg, put, putMany, etc */
429
431
  method?: 'get' | 'getAll' | 'getMany' | 'getAgg' | 'put' | 'putMany' | 'deleteMany' | 'deleteAll';
430
432
  /** if true, all cache layers will be bypassed */
431
433
  noCache?: boolean;
434
+ /** Skip these features for this request (blacklist) */
435
+ excludeFeatures?: string[];
436
+ /** Run only these features, skip all others (whitelist). Cannot be used together with excludeFeatures */
437
+ includeFeatures?: string[];
432
438
  [key: string]: any;
433
439
  }
434
440
  interface FileSystemNode {
@@ -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 => ({
@@ -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
- let events = _lodash.default.orderBy([...docsByAggId[aggId], ...(existingEventsByAggId[aggId] || [])], ["date"], "asc");
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
- let events = _.orderBy([...docsByAggId[aggId], ...existingEventsByAggId[aggId] || []], ["date"], "asc");
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")) {
File without changes
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "rads-db",
3
- "version": "3.2.6",
4
- "packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac",
3
+ "version": "3.2.8",
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
- "pnpm": {
126
- "overrides": {
127
- "mssql": "github:hightouchio/node-mssql"
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
+ }