@cloudflare/cabidela 0.2.2 → 0.2.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.2.4] - 2025-03-24
6
+
7
+ ### Changed
8
+
9
+ - Fixed a bug where root level $ref's were not being resolved correctly
10
+
11
+ ## [0.2.3] - 2025-03-19
12
+
13
+ ### Changed
14
+
15
+ - Documentation typos
16
+
17
+ ### Added
18
+
19
+ - Benchmarking tests for $merge
20
+
5
21
  ## [0.1.2] - 2025-03-07
6
22
 
7
23
  ### Added
package/README.md CHANGED
@@ -280,6 +280,9 @@ Resolves to:
280
280
  {
281
281
  "type": "object",
282
282
  "properties": {
283
+ "p": {
284
+ "type": "string" }
285
+ },
283
286
  "q": {
284
287
  "type": "number"
285
288
  }
@@ -294,6 +297,8 @@ To use `$merge` set the `useMerge` flag to true when creating the instance.
294
297
  new Cabidela(schema, { useMerge: true });
295
298
  ```
296
299
 
300
+ You can combine `$merge` with `$id` and `$ref` keywords, which get resolved first, for even more flexibility.
301
+
297
302
  ## Custom errors
298
303
 
299
304
  If the new instance options has the `errorMessages` flag set to true, you can use the property `errorMessage` in the schema to define custom error messages.
package/dist/index.js CHANGED
@@ -27,49 +27,60 @@ module.exports = __toCommonJS(index_exports);
27
27
  // src/helpers.ts
28
28
  var parse$ref = (ref) => {
29
29
  const parts = ref.split("#");
30
- const $id = parts[0];
31
- const $path = parts[1].split("/").filter((part) => part !== "");
32
- return { $id, $path };
30
+ return {
31
+ $id: parts[0],
32
+ $path: parts[1].split("/").filter((part) => part != "")
33
+ };
33
34
  };
34
35
  function deepMerge(target, source) {
35
- const result = Array.isArray(target) && Array.isArray(source) ? target.concat(source) : { ...target, ...source };
36
+ const result = Array(target) && Array.isArray(source) ? target.concat(source) : { ...target, ...source };
36
37
  for (const key of Object.keys(result)) {
37
38
  result[key] = typeof target[key] == "object" && typeof source[key] == "object" ? deepMerge(target[key], source[key]) : structuredClone(result[key]);
38
39
  }
39
40
  return result;
40
41
  }
41
- var traverseSchema = (options, definitions, obj, cb) => {
42
- let hits;
43
- do {
44
- hits = 0;
45
- Object.keys(obj).forEach((key) => {
46
- if (obj[key] !== null && typeof obj[key] === "object") {
47
- traverseSchema(options, definitions, obj[key], (value) => {
48
- hits++;
49
- obj[key] = value;
50
- });
51
- if (options.useMerge && key === "$merge") {
52
- const merge = deepMerge(obj[key].source, obj[key].with);
53
- if (cb) {
54
- cb(merge);
55
- } else {
56
- Object.assign(obj, merge);
57
- delete obj[key];
42
+ var traverseSchema = (options, definitions, obj) => {
43
+ const ts = (obj2, cb) => {
44
+ let hits;
45
+ do {
46
+ hits = 0;
47
+ for (const key of Object.keys(obj2)) {
48
+ if (typeof obj2[key] == "object") {
49
+ ts(obj2[key], (value) => {
50
+ obj2[key] = value;
51
+ hits++;
52
+ });
53
+ if (options.useMerge && key == "$merge") {
54
+ const merge = deepMerge(obj2[key].source, obj2[key].with);
55
+ if (cb) {
56
+ cb(merge);
57
+ } else {
58
+ hits++;
59
+ Object.assign(obj2, merge);
60
+ delete obj2[key];
61
+ }
58
62
  }
59
- }
60
- } else {
61
- if (key === "$ref") {
62
- const { $id, $path } = parse$ref(obj[key]);
63
- const { resolvedObject } = resolvePayload($path, definitions[$id]);
64
- if (resolvedObject) {
65
- cb(resolvedObject);
66
- } else {
67
- throw new Error(`Could not resolve '${obj[key]}' $ref`);
63
+ } else {
64
+ if (key == "$ref") {
65
+ const { $id, $path } = parse$ref(obj2[key]);
66
+ const { resolvedObject } = resolvePayload($path, definitions[$id]);
67
+ if (resolvedObject) {
68
+ if (cb) {
69
+ cb(resolvedObject);
70
+ } else {
71
+ hits++;
72
+ Object.assign(obj2, resolvedObject);
73
+ delete obj2[key];
74
+ }
75
+ } else {
76
+ throw new Error(`Could not resolve '${obj2[key]}' $ref`);
77
+ }
68
78
  }
69
79
  }
70
80
  }
71
- });
72
- } while (hits > 0);
81
+ } while (hits > 0);
82
+ };
83
+ ts(obj);
73
84
  };
74
85
  var resolvePayload = (path, obj) => {
75
86
  let resolvedObject = path.reduce(function(prev, curr) {
package/dist/index.mjs CHANGED
@@ -1,49 +1,60 @@
1
1
  // src/helpers.ts
2
2
  var parse$ref = (ref) => {
3
3
  const parts = ref.split("#");
4
- const $id = parts[0];
5
- const $path = parts[1].split("/").filter((part) => part !== "");
6
- return { $id, $path };
4
+ return {
5
+ $id: parts[0],
6
+ $path: parts[1].split("/").filter((part) => part != "")
7
+ };
7
8
  };
8
9
  function deepMerge(target, source) {
9
- const result = Array.isArray(target) && Array.isArray(source) ? target.concat(source) : { ...target, ...source };
10
+ const result = Array(target) && Array.isArray(source) ? target.concat(source) : { ...target, ...source };
10
11
  for (const key of Object.keys(result)) {
11
12
  result[key] = typeof target[key] == "object" && typeof source[key] == "object" ? deepMerge(target[key], source[key]) : structuredClone(result[key]);
12
13
  }
13
14
  return result;
14
15
  }
15
- var traverseSchema = (options, definitions, obj, cb) => {
16
- let hits;
17
- do {
18
- hits = 0;
19
- Object.keys(obj).forEach((key) => {
20
- if (obj[key] !== null && typeof obj[key] === "object") {
21
- traverseSchema(options, definitions, obj[key], (value) => {
22
- hits++;
23
- obj[key] = value;
24
- });
25
- if (options.useMerge && key === "$merge") {
26
- const merge = deepMerge(obj[key].source, obj[key].with);
27
- if (cb) {
28
- cb(merge);
29
- } else {
30
- Object.assign(obj, merge);
31
- delete obj[key];
16
+ var traverseSchema = (options, definitions, obj) => {
17
+ const ts = (obj2, cb) => {
18
+ let hits;
19
+ do {
20
+ hits = 0;
21
+ for (const key of Object.keys(obj2)) {
22
+ if (typeof obj2[key] == "object") {
23
+ ts(obj2[key], (value) => {
24
+ obj2[key] = value;
25
+ hits++;
26
+ });
27
+ if (options.useMerge && key == "$merge") {
28
+ const merge = deepMerge(obj2[key].source, obj2[key].with);
29
+ if (cb) {
30
+ cb(merge);
31
+ } else {
32
+ hits++;
33
+ Object.assign(obj2, merge);
34
+ delete obj2[key];
35
+ }
32
36
  }
33
- }
34
- } else {
35
- if (key === "$ref") {
36
- const { $id, $path } = parse$ref(obj[key]);
37
- const { resolvedObject } = resolvePayload($path, definitions[$id]);
38
- if (resolvedObject) {
39
- cb(resolvedObject);
40
- } else {
41
- throw new Error(`Could not resolve '${obj[key]}' $ref`);
37
+ } else {
38
+ if (key == "$ref") {
39
+ const { $id, $path } = parse$ref(obj2[key]);
40
+ const { resolvedObject } = resolvePayload($path, definitions[$id]);
41
+ if (resolvedObject) {
42
+ if (cb) {
43
+ cb(resolvedObject);
44
+ } else {
45
+ hits++;
46
+ Object.assign(obj2, resolvedObject);
47
+ delete obj2[key];
48
+ }
49
+ } else {
50
+ throw new Error(`Could not resolve '${obj2[key]}' $ref`);
51
+ }
42
52
  }
43
53
  }
44
54
  }
45
- });
46
- } while (hits > 0);
55
+ } while (hits > 0);
56
+ };
57
+ ts(obj);
47
58
  };
48
59
  var resolvePayload = (path, obj) => {
49
60
  let resolvedObject = path.reduce(function(prev, curr) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/cabidela",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Cabidela is a small, fast, eval-less, Cloudflare Workers compatible, dynamic JSON Schema validator",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",