rads-db 3.2.33 → 3.2.35

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-c56a76fe.js';
1
+ import { g as RadsConfig, T as TypeDefinition } from './types-1fc744a4.js';
2
2
  import 'mssql';
3
3
  import '_rads-db';
4
4
 
package/dist/index.cjs CHANGED
@@ -11,6 +11,66 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
11
11
  const ___default = /*#__PURE__*/_interopDefaultCompat(_);
12
12
  const createMerge__default = /*#__PURE__*/_interopDefaultCompat(createMerge);
13
13
 
14
+ function stashUnknownEnumValues(doc, oldDoc, typeName, schema) {
15
+ const ctx = { stash: [], path: [] };
16
+ walkType(doc, oldDoc, typeName, schema, ctx);
17
+ return ctx.stash;
18
+ }
19
+ function walkType(doc, oldDoc, typeName, schema, ctx) {
20
+ const type = schema[typeName];
21
+ if (!type?.fields || !doc || typeof doc !== "object")
22
+ return;
23
+ for (const [fieldName, field] of Object.entries(type.fields)) {
24
+ if (field.decorators?.computed || field.decorators?.precomputed)
25
+ continue;
26
+ if (field.isInverseRelation || field.isRelation || field.isChange)
27
+ continue;
28
+ const val = doc[fieldName];
29
+ if (val == null)
30
+ continue;
31
+ const fieldType = schema[field.type];
32
+ if (!fieldType)
33
+ continue;
34
+ if (fieldType.enumValues) {
35
+ stashEnumField({ doc, oldDoc, fieldName }, field, fieldType, ctx);
36
+ } else if (fieldType.fields) {
37
+ walkNestedField(doc[fieldName], oldDoc?.[fieldName], field, schema, {
38
+ stash: ctx.stash,
39
+ path: [...ctx.path, fieldName]
40
+ });
41
+ }
42
+ }
43
+ }
44
+ function stashEnumField({ doc, oldDoc, fieldName }, field, fieldType, ctx) {
45
+ const knownValues = new Set(Object.values(fieldType.enumValues).map((v) => v.name));
46
+ const placeholder = Object.values(fieldType.enumValues)[0]?.name;
47
+ if (!placeholder)
48
+ return;
49
+ const val = doc[fieldName];
50
+ const fieldPath = [...ctx.path, fieldName];
51
+ if (field.isArray && Array.isArray(val)) {
52
+ const oldArr = Array.isArray(oldDoc?.[fieldName]) ? oldDoc[fieldName] : [];
53
+ const oldSet = new Set(oldArr);
54
+ const hasUnknownFromDb = val.some((v) => !knownValues.has(v) && oldSet.has(v));
55
+ if (hasUnknownFromDb) {
56
+ ctx.stash.push({ path: fieldPath, original: val });
57
+ doc[fieldName] = val.map((v) => !knownValues.has(v) && oldSet.has(v) ? placeholder : v);
58
+ }
59
+ } else if (!field.isArray && !knownValues.has(val) && val === oldDoc?.[fieldName]) {
60
+ ctx.stash.push({ path: fieldPath, original: val });
61
+ doc[fieldName] = placeholder;
62
+ }
63
+ }
64
+ function walkNestedField(val, oldVal, field, schema, ctx) {
65
+ if (field.isArray && Array.isArray(val)) {
66
+ const oldArr = Array.isArray(oldVal) ? oldVal : [];
67
+ val.forEach((item, i) => {
68
+ walkType(item, oldArr[i], field.type, schema, { stash: ctx.stash, path: [...ctx.path, i] });
69
+ });
70
+ } else if (!field.isArray) {
71
+ walkType(val, oldVal, field.type, schema, ctx);
72
+ }
73
+ }
14
74
  function generateValidators(schema) {
15
75
  const zodSchemas = {};
16
76
  for (const key in schema) {
@@ -19,7 +79,8 @@ function generateValidators(schema) {
19
79
  }
20
80
  const result = {};
21
81
  for (const key in zodSchemas) {
22
- result[key] = (value) => {
82
+ result[key] = (value, oldDoc) => {
83
+ const stash = oldDoc ? stashUnknownEnumValues(value, oldDoc, key, schema) : [];
23
84
  try {
24
85
  value = zodSchemas[key].parse(value);
25
86
  } catch (error) {
@@ -28,6 +89,9 @@ function generateValidators(schema) {
28
89
  else
29
90
  throw error;
30
91
  }
92
+ for (const { path, original } of stash) {
93
+ ___default.set(value, path, original);
94
+ }
31
95
  fillDefaultValues(schema, key, value);
32
96
  return value;
33
97
  };
@@ -887,7 +951,7 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
887
951
  await beforePut(docArgsToSave, ctx, computedContext);
888
952
  const beforePutResults = await handleEffectsBeforePut(computedContext, docArgsToSave, ctx);
889
953
  for (const d of docArgsToSave) {
890
- const validatedDoc = validators[key](d.doc);
954
+ const validatedDoc = validators[key](d.doc, d.oldDoc);
891
955
  for (const f of precomputedFields || []) {
892
956
  ___default.set(validatedDoc, f, ___default.get(d.doc, f));
893
957
  }
@@ -941,7 +1005,7 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
941
1005
  const beforePutResults = await handleEffectsBeforePut(computedContext, docArgsToSave, ctx);
942
1006
  await beforePut(docArgsToSave, ctx, computedContext);
943
1007
  for (const d of docArgsToSave) {
944
- const validatedDoc = validators[key](d.doc);
1008
+ const validatedDoc = validators[key](d.doc, d.oldDoc);
945
1009
  for (const f of precomputedFields || []) {
946
1010
  ___default.set(validatedDoc, f, ___default.get(d.doc, f));
947
1011
  }
@@ -1061,7 +1125,7 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
1061
1125
  await handlePrecomputed(computedContext, docArgsToSave, ctx);
1062
1126
  await beforePut(docArgsToSave, ctx, computedContext);
1063
1127
  const beforePutResults = await handleEffectsBeforePut(computedContext, docArgsToSave, ctx);
1064
- const validatedDoc = validators[key](doc);
1128
+ const validatedDoc = validators[key](doc, oldDoc);
1065
1129
  docArgsToSave[0].doc = validatedDoc;
1066
1130
  if (precomputedFields) {
1067
1131
  for (const f of precomputedFields) {
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-c56a76fe.js';
2
- export { O as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, an as DeepKeys, ai as DeepPartial, af as DeepPartialArrayItem, ad as DeepPartialWithNulls, ae as DeepPartialWithNullsItem, ag as DeepPartialWithoutNulls, ah as DeepPartialWithoutNullsItem, ao 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, ak as InverseRelation, am as JsonPutOperations, M as MinimalDriver, al as Put, 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, aj 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-c56a76fe.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-1fc744a4.js';
2
+ export { O as Change, x as ComputedContextGlobal, k as CreateRadsArgsDrivers, m as CreateRadsDbArgsNormalized, an as DeepKeys, ai as DeepPartial, af as DeepPartialArrayItem, ad as DeepPartialWithNulls, ae as DeepPartialWithNullsItem, ag as DeepPartialWithoutNulls, ah as DeepPartialWithoutNullsItem, ao 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, ak as InverseRelation, am as JsonPutOperations, M as MinimalDriver, al as Put, 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, aj 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-1fc744a4.js';
3
3
  import { RadsDb } from '_rads-db';
4
4
  export { RadsDb } from '_rads-db';
5
5
  import 'mssql';
package/dist/index.mjs CHANGED
@@ -4,6 +4,66 @@ import { v4 } from 'uuid';
4
4
  import createMerge from '@fastify/deepmerge';
5
5
  import { schemas } from '_rads-db';
6
6
 
7
+ function stashUnknownEnumValues(doc, oldDoc, typeName, schema) {
8
+ const ctx = { stash: [], path: [] };
9
+ walkType(doc, oldDoc, typeName, schema, ctx);
10
+ return ctx.stash;
11
+ }
12
+ function walkType(doc, oldDoc, typeName, schema, ctx) {
13
+ const type = schema[typeName];
14
+ if (!type?.fields || !doc || typeof doc !== "object")
15
+ return;
16
+ for (const [fieldName, field] of Object.entries(type.fields)) {
17
+ if (field.decorators?.computed || field.decorators?.precomputed)
18
+ continue;
19
+ if (field.isInverseRelation || field.isRelation || field.isChange)
20
+ continue;
21
+ const val = doc[fieldName];
22
+ if (val == null)
23
+ continue;
24
+ const fieldType = schema[field.type];
25
+ if (!fieldType)
26
+ continue;
27
+ if (fieldType.enumValues) {
28
+ stashEnumField({ doc, oldDoc, fieldName }, field, fieldType, ctx);
29
+ } else if (fieldType.fields) {
30
+ walkNestedField(doc[fieldName], oldDoc?.[fieldName], field, schema, {
31
+ stash: ctx.stash,
32
+ path: [...ctx.path, fieldName]
33
+ });
34
+ }
35
+ }
36
+ }
37
+ function stashEnumField({ doc, oldDoc, fieldName }, field, fieldType, ctx) {
38
+ const knownValues = new Set(Object.values(fieldType.enumValues).map((v) => v.name));
39
+ const placeholder = Object.values(fieldType.enumValues)[0]?.name;
40
+ if (!placeholder)
41
+ return;
42
+ const val = doc[fieldName];
43
+ const fieldPath = [...ctx.path, fieldName];
44
+ if (field.isArray && Array.isArray(val)) {
45
+ const oldArr = Array.isArray(oldDoc?.[fieldName]) ? oldDoc[fieldName] : [];
46
+ const oldSet = new Set(oldArr);
47
+ const hasUnknownFromDb = val.some((v) => !knownValues.has(v) && oldSet.has(v));
48
+ if (hasUnknownFromDb) {
49
+ ctx.stash.push({ path: fieldPath, original: val });
50
+ doc[fieldName] = val.map((v) => !knownValues.has(v) && oldSet.has(v) ? placeholder : v);
51
+ }
52
+ } else if (!field.isArray && !knownValues.has(val) && val === oldDoc?.[fieldName]) {
53
+ ctx.stash.push({ path: fieldPath, original: val });
54
+ doc[fieldName] = placeholder;
55
+ }
56
+ }
57
+ function walkNestedField(val, oldVal, field, schema, ctx) {
58
+ if (field.isArray && Array.isArray(val)) {
59
+ const oldArr = Array.isArray(oldVal) ? oldVal : [];
60
+ val.forEach((item, i) => {
61
+ walkType(item, oldArr[i], field.type, schema, { stash: ctx.stash, path: [...ctx.path, i] });
62
+ });
63
+ } else if (!field.isArray) {
64
+ walkType(val, oldVal, field.type, schema, ctx);
65
+ }
66
+ }
7
67
  function generateValidators(schema) {
8
68
  const zodSchemas = {};
9
69
  for (const key in schema) {
@@ -12,7 +72,8 @@ function generateValidators(schema) {
12
72
  }
13
73
  const result = {};
14
74
  for (const key in zodSchemas) {
15
- result[key] = (value) => {
75
+ result[key] = (value, oldDoc) => {
76
+ const stash = oldDoc ? stashUnknownEnumValues(value, oldDoc, key, schema) : [];
16
77
  try {
17
78
  value = zodSchemas[key].parse(value);
18
79
  } catch (error) {
@@ -21,6 +82,9 @@ function generateValidators(schema) {
21
82
  else
22
83
  throw error;
23
84
  }
85
+ for (const { path, original } of stash) {
86
+ _.set(value, path, original);
87
+ }
24
88
  fillDefaultValues(schema, key, value);
25
89
  return value;
26
90
  };
@@ -880,7 +944,7 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
880
944
  await beforePut(docArgsToSave, ctx, computedContext);
881
945
  const beforePutResults = await handleEffectsBeforePut(computedContext, docArgsToSave, ctx);
882
946
  for (const d of docArgsToSave) {
883
- const validatedDoc = validators[key](d.doc);
947
+ const validatedDoc = validators[key](d.doc, d.oldDoc);
884
948
  for (const f of precomputedFields || []) {
885
949
  _.set(validatedDoc, f, _.get(d.doc, f));
886
950
  }
@@ -934,7 +998,7 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
934
998
  const beforePutResults = await handleEffectsBeforePut(computedContext, docArgsToSave, ctx);
935
999
  await beforePut(docArgsToSave, ctx, computedContext);
936
1000
  for (const d of docArgsToSave) {
937
- const validatedDoc = validators[key](d.doc);
1001
+ const validatedDoc = validators[key](d.doc, d.oldDoc);
938
1002
  for (const f of precomputedFields || []) {
939
1003
  _.set(validatedDoc, f, _.get(d.doc, f));
940
1004
  }
@@ -1054,7 +1118,7 @@ function getRadsDbMethods(key, computedContext, driverInstance) {
1054
1118
  await handlePrecomputed(computedContext, docArgsToSave, ctx);
1055
1119
  await beforePut(docArgsToSave, ctx, computedContext);
1056
1120
  const beforePutResults = await handleEffectsBeforePut(computedContext, docArgsToSave, ctx);
1057
- const validatedDoc = validators[key](doc);
1121
+ const validatedDoc = validators[key](doc, oldDoc);
1058
1122
  docArgsToSave[0].doc = validatedDoc;
1059
1123
  if (precomputedFields) {
1060
1124
  for (const f of precomputedFields) {
@@ -77,12 +77,12 @@ type KeepArray<TMaybeArray, TType> = NonNullable<TMaybeArray> extends any[] ? TT
77
77
  type GetResponseInclude<EN extends keyof EntityMeta, I extends GetArgsInclude<EN>> = I extends {
78
78
  _pick: readonly string[];
79
79
  } ? GetResponseIncludeSelect<EN, I> : {
80
- [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof I ? KeepArray<EntityMeta[EN]['type'][K], GetResponseInclude<EntityMeta[EN]['relations'][K]['entityName'], I[K]>> : KeepArray<EntityMeta[EN]['type'][K], RelationData<EN, K>> : EntityMeta[EN]['type'][K];
80
+ [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof I ? KeepArray<EntityMeta[EN]['type'][K], GetResponseInclude<EntityMeta[EN]['relations'][K]['entityName'], I[K]>> : KeepArray<EntityMeta[EN]['type'][K], RelationData<EN, K>> : K extends keyof EntityMeta[EN]['nestedObjects'] ? K extends keyof I ? GetResponseInclude<EntityMeta[EN]['nestedObjects'][K]['entityName'], I[K]> : EntityMeta[EN]['type'][K] : EntityMeta[EN]['type'][K];
81
81
  };
82
82
  type GetResponseIncludeSelect<EN extends keyof EntityMeta, I extends GetArgsInclude<EN>> = I extends {
83
83
  _pick: readonly (infer P)[];
84
84
  } ? Pick<{
85
- [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof Omit<I, '_pick'> ? KeepArray<EntityMeta[EN]['type'][K], GetResponseInclude<EntityMeta[EN]['relations'][K]['entityName'], Omit<I, '_pick'>[K]>> : KeepArray<EntityMeta[EN]['type'][K], RelationData<EN, K>> : K extends EntityMeta[EN]['jsonFields'] ? K extends keyof Omit<I, '_pick'> ? Omit<I, '_pick'>[K] extends {
85
+ [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof Omit<I, '_pick'> ? KeepArray<EntityMeta[EN]['type'][K], GetResponseInclude<EntityMeta[EN]['relations'][K]['entityName'], Omit<I, '_pick'>[K]>> : KeepArray<EntityMeta[EN]['type'][K], RelationData<EN, K>> : K extends keyof EntityMeta[EN]['nestedObjects'] ? K extends keyof Omit<I, '_pick'> ? GetResponseInclude<EntityMeta[EN]['nestedObjects'][K]['entityName'], Omit<I, '_pick'>[K]> : EntityMeta[EN]['type'][K] : K extends EntityMeta[EN]['jsonFields'] ? K extends keyof Omit<I, '_pick'> ? Omit<I, '_pick'>[K] extends {
86
86
  _pick: (infer JP)[];
87
87
  } ? Pick<NonNullable<EntityMeta[EN]['type'][K]>, JP & string> : EntityMeta[EN]['type'][K] : EntityMeta[EN]['type'][K] : EntityMeta[EN]['type'][K];
88
88
  }, ((P & string) | (Exclude<keyof I, '_pick'> & string)) & keyof EntityMeta[EN]['type']> : never;
@@ -288,7 +288,7 @@ interface SchemaLoadResult {
288
288
  schema: Schema;
289
289
  entitiesDir?: string;
290
290
  }
291
- type SchemaValidators = Record<string, (item: any) => any>;
291
+ type SchemaValidators = Record<string, (item: any, oldDoc?: any) => any>;
292
292
  interface TypeDefinition {
293
293
  name: string;
294
294
  decorators: Record<string, Record<string, any>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rads-db",
3
- "version": "3.2.33",
3
+ "version": "3.2.35",
4
4
  "description": "Say goodbye to boilerplate code and hello to efficient and elegant syntax.",
5
5
  "author": "",
6
6
  "license": "ISC",