@verdant-web/common 1.11.1 → 1.13.0

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.
Files changed (76) hide show
  1. package/dist/cjs/migration.d.ts +7 -0
  2. package/dist/cjs/migration.js +46 -6
  3. package/dist/cjs/migration.js.map +1 -1
  4. package/dist/cjs/oids.d.ts +5 -5
  5. package/dist/cjs/oids.js +37 -22
  6. package/dist/cjs/oids.js.map +1 -1
  7. package/dist/cjs/oids.test.js +62 -44
  8. package/dist/cjs/oids.test.js.map +1 -1
  9. package/dist/cjs/operation.d.ts +2 -2
  10. package/dist/cjs/operation.js +16 -7
  11. package/dist/cjs/operation.js.map +1 -1
  12. package/dist/cjs/operation.test.js +180 -30
  13. package/dist/cjs/operation.test.js.map +1 -1
  14. package/dist/cjs/patch.d.ts +3 -3
  15. package/dist/cjs/patch.js +6 -6
  16. package/dist/cjs/patch.js.map +1 -1
  17. package/dist/cjs/schema/defaults.test.js +4 -4
  18. package/dist/cjs/schema/defaults.test.js.map +1 -1
  19. package/dist/cjs/schema/{defaults.d.ts → fields.d.ts} +3 -0
  20. package/dist/cjs/schema/{defaults.js → fields.js} +48 -3
  21. package/dist/cjs/schema/fields.js.map +1 -0
  22. package/dist/cjs/schema/index.d.ts +1 -1
  23. package/dist/cjs/schema/index.js +1 -1
  24. package/dist/cjs/schema/index.js.map +1 -1
  25. package/dist/cjs/schema/validation.d.ts +3 -0
  26. package/dist/cjs/schema/validation.js +87 -0
  27. package/dist/cjs/schema/validation.js.map +1 -0
  28. package/dist/cjs/utils.d.ts +5 -1
  29. package/dist/cjs/utils.js +9 -5
  30. package/dist/cjs/utils.js.map +1 -1
  31. package/dist/esm/migration.d.ts +7 -0
  32. package/dist/esm/migration.js +47 -7
  33. package/dist/esm/migration.js.map +1 -1
  34. package/dist/esm/oids.d.ts +5 -5
  35. package/dist/esm/oids.js +34 -21
  36. package/dist/esm/oids.js.map +1 -1
  37. package/dist/esm/oids.test.js +62 -44
  38. package/dist/esm/oids.test.js.map +1 -1
  39. package/dist/esm/operation.d.ts +2 -2
  40. package/dist/esm/operation.js +18 -9
  41. package/dist/esm/operation.js.map +1 -1
  42. package/dist/esm/operation.test.js +180 -30
  43. package/dist/esm/operation.test.js.map +1 -1
  44. package/dist/esm/patch.d.ts +3 -3
  45. package/dist/esm/patch.js +6 -6
  46. package/dist/esm/patch.js.map +1 -1
  47. package/dist/esm/schema/defaults.test.js +2 -2
  48. package/dist/esm/schema/defaults.test.js.map +1 -1
  49. package/dist/esm/schema/{defaults.d.ts → fields.d.ts} +3 -0
  50. package/dist/esm/schema/{defaults.js → fields.js} +44 -2
  51. package/dist/esm/schema/fields.js.map +1 -0
  52. package/dist/esm/schema/index.d.ts +1 -1
  53. package/dist/esm/schema/index.js +1 -1
  54. package/dist/esm/schema/index.js.map +1 -1
  55. package/dist/esm/schema/validation.d.ts +3 -0
  56. package/dist/esm/schema/validation.js +82 -0
  57. package/dist/esm/schema/validation.js.map +1 -0
  58. package/dist/esm/utils.d.ts +5 -1
  59. package/dist/esm/utils.js +9 -5
  60. package/dist/esm/utils.js.map +1 -1
  61. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  62. package/dist/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +1 -1
  64. package/src/migration.ts +74 -15
  65. package/src/oids.test.ts +62 -51
  66. package/src/oids.ts +35 -26
  67. package/src/operation.test.ts +189 -41
  68. package/src/operation.ts +23 -19
  69. package/src/patch.ts +5 -15
  70. package/src/schema/defaults.test.ts +2 -2
  71. package/src/schema/{defaults.ts → fields.ts} +55 -1
  72. package/src/schema/index.ts +1 -1
  73. package/src/schema/validation.ts +99 -0
  74. package/src/utils.ts +9 -5
  75. package/dist/cjs/schema/defaults.js.map +0 -1
  76. package/dist/esm/schema/defaults.js.map +0 -1
@@ -0,0 +1,99 @@
1
+ import { LEGACY_OID_KEY, OID_KEY } from '../oids.js';
2
+ import { isObject } from '../utils.js';
3
+ import { StorageCollectionSchema, StorageFieldSchema } from './types.js';
4
+
5
+ export function validateEntity(schema: StorageCollectionSchema, entity: any) {
6
+ for (const [key, value] of Object.entries(entity)) {
7
+ if (!schema.fields[key]) {
8
+ throw new Error(`Invalid field "${key}"`);
9
+ }
10
+ if (value) {
11
+ validateEntityField(schema.fields[key], value);
12
+ }
13
+ }
14
+ }
15
+
16
+ export function validateEntityField(
17
+ field: StorageFieldSchema,
18
+ value: any,
19
+ fieldPath: string[] = [],
20
+ ) {
21
+ if (field.type === 'object') {
22
+ if (!isObject(value)) {
23
+ if (value === null && field.nullable) return;
24
+ throw new Error(
25
+ `Expected object${
26
+ field.nullable ? ' or null' : ''
27
+ } for field ${formatField(fieldPath)}}`,
28
+ );
29
+ }
30
+ for (const [key, subField] of Object.entries(field.properties)) {
31
+ if (value[key]) {
32
+ validateEntityField(subField, value[key]);
33
+ }
34
+ }
35
+ for (const key of Object.keys(value)) {
36
+ if (!field.properties[key]) {
37
+ throw new Error(
38
+ `Invalid field "${key}" on value ${formatField(fieldPath)}`,
39
+ );
40
+ }
41
+ }
42
+ } else if (field.type === 'array') {
43
+ if (!Array.isArray(value)) {
44
+ if (value === null && field.nullable) return;
45
+ throw new Error(
46
+ `Expected array${
47
+ field.nullable ? ' or null' : ''
48
+ } for field ${formatField(fieldPath)}}`,
49
+ );
50
+ }
51
+ for (const item of value) {
52
+ validateEntityField(field.items, item);
53
+ }
54
+ } else if (field.type === 'map') {
55
+ if (!isObject(value)) {
56
+ throw new Error(`Expected map for field ${formatField(fieldPath)}}`);
57
+ }
58
+ for (const [key, item] of Object.entries(value)) {
59
+ // santiy check to weed out any id field
60
+ if (key === OID_KEY || key === LEGACY_OID_KEY) continue;
61
+ validateEntityField(field.values, item);
62
+ }
63
+ } else if (field.type === 'string') {
64
+ if (typeof value !== 'string') {
65
+ if (value === null && field.nullable) return;
66
+ throw new Error(
67
+ `Expected string ${
68
+ field.nullable ? ' or null' : ''
69
+ } for field ${formatField(fieldPath)}}`,
70
+ );
71
+ }
72
+ } else if (field.type === 'boolean') {
73
+ if (typeof value !== 'boolean') {
74
+ if (value === null && field.nullable) return;
75
+ throw new Error(
76
+ `Expected boolean ${
77
+ field.nullable ? ' or null' : ''
78
+ } for field ${formatField(fieldPath)}}`,
79
+ );
80
+ }
81
+ } else if (field.type === 'number') {
82
+ if (typeof value !== 'number') {
83
+ if (value === null && field.nullable) return;
84
+ throw new Error(
85
+ `Expected number ${
86
+ field.nullable ? ' or null' : ''
87
+ } for field ${formatField(fieldPath)}}`,
88
+ );
89
+ }
90
+ } else if (field.type === 'file') {
91
+ if (value === null && !field.nullable) {
92
+ throw new Error(`Expected file for field ${formatField(fieldPath)}}`);
93
+ }
94
+ }
95
+ }
96
+
97
+ function formatField(fieldPath: string[]) {
98
+ return fieldPath.join('.');
99
+ }
package/src/utils.ts CHANGED
@@ -60,19 +60,23 @@ export function stableStringify(obj: any) {
60
60
  return JSON.stringify(obj, orderedReplacer);
61
61
  }
62
62
 
63
- export function cloneDeep<T>(obj: T): T {
64
- if (isObject(obj)) {
63
+ /**
64
+ * A version of structured cloning which preserves object identity
65
+ * references in the system.
66
+ */
67
+ export function cloneDeep<T>(obj: T, copyOids = true): T {
68
+ if (isObject(obj) || Array.isArray(obj)) {
65
69
  const oid = maybeGetOid(obj);
66
70
  let clone: any;
67
71
  if (Array.isArray(obj)) {
68
- clone = obj.map(cloneDeep) as T;
72
+ clone = obj.map((v) => cloneDeep(v, copyOids)) as T;
69
73
  } else {
70
74
  clone = {};
71
75
  for (const [key, value] of Object.entries(obj as any)) {
72
- clone[key] = cloneDeep(value);
76
+ clone[key] = cloneDeep(value, copyOids);
73
77
  }
74
78
  }
75
- if (oid) {
79
+ if (copyOids && oid) {
76
80
  assignOid(clone, oid);
77
81
  }
78
82
  return clone;
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../src/schema/defaults.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../src/schema/defaults.ts"],"names":[],"mappings":"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"}