@zuplo/cli 6.71.23 → 6.71.25

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 (128) hide show
  1. package/node_modules/@fastify/fast-json-stringify-compiler/.github/dependabot.yml +42 -2
  2. package/node_modules/@fastify/fast-json-stringify-compiler/.github/workflows/ci.yml +6 -1
  3. package/node_modules/@fastify/fast-json-stringify-compiler/.github/workflows/lock-threads.yml +19 -0
  4. package/node_modules/@fastify/fast-json-stringify-compiler/LICENSE +1 -1
  5. package/node_modules/@fastify/fast-json-stringify-compiler/README.md +1 -1
  6. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.gitattributes +2 -0
  7. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.github/dependabot.yml +13 -0
  8. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.github/workflows/ci.yml +33 -0
  9. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/.github/workflows/lock-threads.yml +19 -0
  10. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/LICENSE +22 -0
  11. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/README.md +742 -0
  12. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench-cmp-branch.js +116 -0
  13. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench-cmp-lib.js +339 -0
  14. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench-thread.js +33 -0
  15. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/benchmark/bench.js +391 -0
  16. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/build/build-schema-validator.js +26 -0
  17. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/eslint.config.js +9 -0
  18. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/examples/example.js +81 -0
  19. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/examples/server.js +42 -0
  20. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/index.js +1308 -0
  21. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/location.js +24 -0
  22. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/merge-schemas.js +9 -0
  23. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/schema-validator.js +1134 -0
  24. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/serializer.js +141 -0
  25. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/standalone.js +34 -0
  26. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/lib/validator.js +96 -0
  27. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/package.json +89 -0
  28. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/additionalProperties.test.js +332 -0
  29. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/allof.test.js +751 -0
  30. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/any.test.js +231 -0
  31. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/anyof.test.js +812 -0
  32. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/array.test.js +688 -0
  33. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/asNumber.test.js +13 -0
  34. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/basic.test.js +400 -0
  35. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/bigint.test.js +76 -0
  36. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/clean-cache.test.js +47 -0
  37. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/const.test.js +314 -0
  38. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/date.test.js +639 -0
  39. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/debug-mode.test.js +130 -0
  40. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/defaults.test.js +376 -0
  41. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/enum.test.js +37 -0
  42. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/fix-604.test.js +25 -0
  43. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/fixtures/.keep +0 -0
  44. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/if-then-else.test.js +540 -0
  45. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/inferType.test.js +92 -0
  46. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/infinity.test.js +55 -0
  47. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/integer.test.js +194 -0
  48. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/invalidSchema.test.js +38 -0
  49. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-479.test.js +57 -0
  50. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-793.test.js +107 -0
  51. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-794.test.js +177 -0
  52. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/issue-836.test.js +183 -0
  53. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-add-comma.test.js +57 -0
  54. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/README.md +10 -0
  55. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft4/required.json +54 -0
  56. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft4.test.js +12 -0
  57. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft6/required.json +70 -0
  58. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft6.test.js +12 -0
  59. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft7/required.json +70 -0
  60. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/draft7.test.js +12 -0
  61. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/json-schema-test-suite/util.js +31 -0
  62. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/missing-values.test.js +88 -0
  63. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/multi-type-serializer.test.js +19 -0
  64. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/nestedObjects.test.js +63 -0
  65. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/nullable.test.js +543 -0
  66. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/oneof.test.js +510 -0
  67. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/patternProperties.test.js +168 -0
  68. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/recursion.test.js +245 -0
  69. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/ref.json +12 -0
  70. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/ref.test.js +2077 -0
  71. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/regex.test.js +32 -0
  72. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/required.test.js +204 -0
  73. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/requiresAjv.test.js +50 -0
  74. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize.test.js +141 -0
  75. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize2.test.js +18 -0
  76. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize3.test.js +17 -0
  77. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize4.test.js +16 -0
  78. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize5.test.js +16 -0
  79. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize6.test.js +22 -0
  80. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/sanitize7.test.js +68 -0
  81. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/side-effect.test.js +196 -0
  82. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/standalone-mode.test.js +219 -0
  83. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/string.test.js +84 -0
  84. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/surrogate.test.js +67 -0
  85. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/toJSON.test.js +203 -0
  86. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/typebox.test.js +36 -0
  87. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/typesArray.test.js +550 -0
  88. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/unknownFormats.test.js +27 -0
  89. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/test/webpack.test.js +50 -0
  90. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/types/index.d.ts +219 -0
  91. package/node_modules/@fastify/fast-json-stringify-compiler/node_modules/fast-json-stringify/types/index.tst.ts +259 -0
  92. package/node_modules/@fastify/fast-json-stringify-compiler/package.json +6 -11
  93. package/node_modules/@fastify/fast-json-stringify-compiler/types/{index.test-d.ts → index.tst.ts} +34 -32
  94. package/node_modules/@protobufjs/utf8/CHANGELOG.md +8 -0
  95. package/node_modules/@protobufjs/utf8/index.js +29 -18
  96. package/node_modules/@protobufjs/utf8/package.json +2 -2
  97. package/node_modules/@protobufjs/utf8/tests/index.js +5 -0
  98. package/node_modules/@zuplo/core/package.json +1 -1
  99. package/node_modules/@zuplo/graphql/package.json +1 -1
  100. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  101. package/node_modules/@zuplo/otel/package.json +1 -1
  102. package/node_modules/@zuplo/runtime/out/esm/{chunk-5CYWMN74.js → chunk-MJWTZPC2.js} +90 -90
  103. package/node_modules/@zuplo/runtime/out/esm/chunk-MJWTZPC2.js.map +1 -0
  104. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  105. package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
  106. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  107. package/node_modules/@zuplo/runtime/out/types/index.d.ts +154 -0
  108. package/node_modules/@zuplo/runtime/package.json +1 -1
  109. package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -1
  110. package/node_modules/hono/dist/adapter/bun/websocket.js +3 -1
  111. package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -1
  112. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +3 -1
  113. package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +1 -1
  114. package/node_modules/hono/dist/cjs/utils/body.js +12 -4
  115. package/node_modules/hono/dist/cjs/utils/buffer.js +2 -1
  116. package/node_modules/hono/dist/cjs/validator/validator.js +3 -3
  117. package/node_modules/hono/dist/middleware/serve-static/index.js +1 -1
  118. package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +2 -2
  119. package/node_modules/hono/dist/types/utils/body.d.ts +1 -1
  120. package/node_modules/hono/dist/utils/body.js +12 -4
  121. package/node_modules/hono/dist/utils/buffer.js +2 -1
  122. package/node_modules/hono/dist/validator/validator.js +3 -3
  123. package/node_modules/hono/package.json +8 -7
  124. package/package.json +6 -6
  125. package/node_modules/@fastify/fast-json-stringify-compiler/.eslintrc +0 -1
  126. package/node_modules/@zuplo/runtime/out/esm/chunk-5CYWMN74.js.map +0 -1
  127. package/node_modules/hono/dist/tsconfig.build.tsbuildinfo +0 -1
  128. /package/node_modules/@zuplo/runtime/out/esm/{chunk-5CYWMN74.js.LEGAL.txt → chunk-MJWTZPC2.js.LEGAL.txt} +0 -0
@@ -0,0 +1,2077 @@
1
+ 'use strict'
2
+
3
+ const clone = require('rfdc')({ proto: true })
4
+
5
+ const { test } = require('node:test')
6
+ const build = require('..')
7
+
8
+ test('ref internal - properties', (t) => {
9
+ t.plan(2)
10
+
11
+ const schema = {
12
+ title: 'object with $ref',
13
+ definitions: {
14
+ def: {
15
+ type: 'object',
16
+ properties: {
17
+ str: {
18
+ type: 'string'
19
+ }
20
+ }
21
+ }
22
+ },
23
+ type: 'object',
24
+ properties: {
25
+ obj: {
26
+ $ref: '#/definitions/def'
27
+ }
28
+ }
29
+ }
30
+
31
+ const object = {
32
+ obj: {
33
+ str: 'test'
34
+ }
35
+ }
36
+
37
+ const stringify = build(schema)
38
+ const output = stringify(object)
39
+
40
+ t.assert.doesNotThrow(() => JSON.parse(output))
41
+ t.assert.equal(output, '{"obj":{"str":"test"}}')
42
+ })
43
+
44
+ test('ref internal - items', (t) => {
45
+ t.plan(2)
46
+
47
+ const schema = {
48
+ title: 'array with $ref',
49
+ definitions: {
50
+ def: {
51
+ type: 'object',
52
+ properties: {
53
+ str: {
54
+ type: 'string'
55
+ }
56
+ }
57
+ }
58
+ },
59
+ type: 'array',
60
+ items: { $ref: '#/definitions/def' }
61
+ }
62
+
63
+ const array = [{
64
+ str: 'test'
65
+ }]
66
+
67
+ const stringify = build(schema)
68
+ const output = stringify(array)
69
+
70
+ t.assert.doesNotThrow(() => JSON.parse(output))
71
+ t.assert.equal(output, '[{"str":"test"}]')
72
+ })
73
+
74
+ test('ref external - properties', (t) => {
75
+ t.plan(2)
76
+
77
+ const externalSchema = {
78
+ first: require('./ref.json'),
79
+ second: {
80
+ definitions: {
81
+ num: {
82
+ type: 'object',
83
+ properties: {
84
+ int: {
85
+ type: 'integer'
86
+ }
87
+ }
88
+ }
89
+ }
90
+ },
91
+ third: {
92
+ type: 'string'
93
+ }
94
+ }
95
+
96
+ const schema = {
97
+ title: 'object with $ref',
98
+ type: 'object',
99
+ properties: {
100
+ obj: {
101
+ $ref: 'first#/definitions/def'
102
+ },
103
+ num: {
104
+ $ref: 'second#/definitions/num'
105
+ },
106
+ strPlain: {
107
+ $ref: 'third'
108
+ },
109
+ strHash: {
110
+ $ref: 'third#'
111
+ }
112
+ }
113
+ }
114
+
115
+ const object = {
116
+ obj: {
117
+ str: 'test'
118
+ },
119
+ num: {
120
+ int: 42
121
+ },
122
+ strPlain: 'test',
123
+ strHash: 'test'
124
+ }
125
+
126
+ const stringify = build(schema, { schema: externalSchema })
127
+ const output = stringify(object)
128
+
129
+ t.assert.doesNotThrow(() => JSON.parse(output))
130
+ t.assert.equal(output, '{"obj":{"str":"test"},"num":{"int":42},"strPlain":"test","strHash":"test"}')
131
+ })
132
+
133
+ test('ref internal - patternProperties', (t) => {
134
+ t.plan(2)
135
+
136
+ const schema = {
137
+ title: 'object with $ref',
138
+ definitions: {
139
+ def: {
140
+ type: 'object',
141
+ properties: {
142
+ str: {
143
+ type: 'string'
144
+ }
145
+ }
146
+ }
147
+ },
148
+ type: 'object',
149
+ properties: {},
150
+ patternProperties: {
151
+ obj: {
152
+ $ref: '#/definitions/def'
153
+ }
154
+ }
155
+ }
156
+
157
+ const object = {
158
+ obj: {
159
+ str: 'test'
160
+ }
161
+ }
162
+
163
+ const stringify = build(schema)
164
+ const output = stringify(object)
165
+
166
+ t.assert.doesNotThrow(() => JSON.parse(output))
167
+ t.assert.equal(output, '{"obj":{"str":"test"}}')
168
+ })
169
+
170
+ test('ref internal - additionalProperties', (t) => {
171
+ t.plan(2)
172
+
173
+ const schema = {
174
+ title: 'object with $ref',
175
+ definitions: {
176
+ def: {
177
+ type: 'object',
178
+ properties: {
179
+ str: {
180
+ type: 'string'
181
+ }
182
+ }
183
+ }
184
+ },
185
+ type: 'object',
186
+ properties: {},
187
+ additionalProperties: {
188
+ $ref: '#/definitions/def'
189
+ }
190
+ }
191
+
192
+ const object = {
193
+ obj: {
194
+ str: 'test'
195
+ }
196
+ }
197
+
198
+ const stringify = build(schema)
199
+ const output = stringify(object)
200
+
201
+ t.assert.doesNotThrow(() => JSON.parse(output))
202
+ t.assert.equal(output, '{"obj":{"str":"test"}}')
203
+ })
204
+
205
+ test('ref internal - pattern-additional Properties', (t) => {
206
+ t.plan(2)
207
+
208
+ const schema = {
209
+ title: 'object with $ref',
210
+ definitions: {
211
+ def: {
212
+ type: 'object',
213
+ properties: {
214
+ str: {
215
+ type: 'string'
216
+ }
217
+ }
218
+ }
219
+ },
220
+ type: 'object',
221
+ properties: {},
222
+ patternProperties: {
223
+ reg: {
224
+ $ref: '#/definitions/def'
225
+ }
226
+ },
227
+ additionalProperties: {
228
+ $ref: '#/definitions/def'
229
+ }
230
+ }
231
+
232
+ const object = {
233
+ reg: {
234
+ str: 'test'
235
+ },
236
+ obj: {
237
+ str: 'test'
238
+ }
239
+ }
240
+
241
+ const stringify = build(schema)
242
+ const output = stringify(object)
243
+
244
+ t.assert.doesNotThrow(() => JSON.parse(output))
245
+ t.assert.equal(output, '{"reg":{"str":"test"},"obj":{"str":"test"}}')
246
+ })
247
+
248
+ test('ref external - pattern-additional Properties', (t) => {
249
+ t.plan(2)
250
+
251
+ const externalSchema = {
252
+ first: require('./ref.json'),
253
+ second: {
254
+ definitions: {
255
+ num: {
256
+ type: 'object',
257
+ properties: {
258
+ int: {
259
+ type: 'integer'
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ }
266
+
267
+ const schema = {
268
+ title: 'object with $ref',
269
+ type: 'object',
270
+ properties: {},
271
+ patternProperties: {
272
+ reg: {
273
+ $ref: 'first#/definitions/def'
274
+ }
275
+ },
276
+ additionalProperties: {
277
+ $ref: 'second#/definitions/num'
278
+ }
279
+ }
280
+
281
+ const object = {
282
+ reg: {
283
+ str: 'test'
284
+ },
285
+ obj: {
286
+ int: 42
287
+ }
288
+ }
289
+
290
+ const stringify = build(schema, { schema: externalSchema })
291
+ const output = stringify(object)
292
+
293
+ t.assert.doesNotThrow(() => JSON.parse(output))
294
+ t.assert.equal(output, '{"reg":{"str":"test"},"obj":{"int":42}}')
295
+ })
296
+
297
+ test('ref internal - deepObject schema', (t) => {
298
+ t.plan(2)
299
+
300
+ const schema = {
301
+ title: 'object with $ref',
302
+ definitions: {
303
+ def: {
304
+ type: 'object',
305
+ properties: {
306
+ coming: {
307
+ type: 'object',
308
+ properties: {
309
+ where: {
310
+ type: 'string'
311
+ }
312
+ }
313
+ }
314
+ }
315
+ }
316
+ },
317
+ type: 'object',
318
+ properties: {
319
+ winter: {
320
+ type: 'object',
321
+ properties: {
322
+ is: {
323
+ $ref: '#/definitions/def'
324
+ }
325
+ }
326
+ }
327
+ }
328
+ }
329
+
330
+ const object = {
331
+ winter: {
332
+ is: {
333
+ coming: {
334
+ where: 'to town'
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ const stringify = build(schema)
341
+ const output = stringify(object)
342
+
343
+ t.assert.doesNotThrow(() => JSON.parse(output))
344
+ t.assert.equal(output, '{"winter":{"is":{"coming":{"where":"to town"}}}}')
345
+ })
346
+
347
+ test('ref internal - plain name fragment', (t) => {
348
+ t.plan(2)
349
+
350
+ const schema = {
351
+ title: 'object with $ref',
352
+ definitions: {
353
+ def: {
354
+ $id: '#uri',
355
+ type: 'object',
356
+ properties: {
357
+ str: {
358
+ type: 'string'
359
+ }
360
+ },
361
+ required: ['str']
362
+ }
363
+ },
364
+ type: 'object',
365
+ properties: {
366
+ obj: {
367
+ $ref: '#uri'
368
+ }
369
+ }
370
+ }
371
+
372
+ const object = {
373
+ obj: {
374
+ str: 'test'
375
+ }
376
+ }
377
+
378
+ const stringify = build(schema)
379
+ const output = stringify(object)
380
+
381
+ t.assert.doesNotThrow(() => JSON.parse(output))
382
+ t.assert.equal(output, '{"obj":{"str":"test"}}')
383
+ })
384
+
385
+ test('ref external - plain name fragment', (t) => {
386
+ t.plan(2)
387
+
388
+ const externalSchema = {
389
+ first: {
390
+ $id: '#first-schema',
391
+ type: 'object',
392
+ properties: {
393
+ str: {
394
+ type: 'string'
395
+ }
396
+ }
397
+ },
398
+ second: {
399
+ definitions: {
400
+ second: {
401
+ $id: '#second-schema',
402
+ type: 'object',
403
+ properties: {
404
+ int: {
405
+ type: 'integer'
406
+ }
407
+ }
408
+ }
409
+ }
410
+ }
411
+ }
412
+
413
+ const schema = {
414
+ title: 'object with $ref to external plain name fragment',
415
+ type: 'object',
416
+ properties: {
417
+ first: {
418
+ $ref: 'first#first-schema'
419
+ },
420
+ second: {
421
+ $ref: 'second#second-schema'
422
+ }
423
+ }
424
+ }
425
+
426
+ const object = {
427
+ first: {
428
+ str: 'test'
429
+ },
430
+ second: {
431
+ int: 42
432
+ }
433
+ }
434
+
435
+ const stringify = build(schema, { schema: externalSchema })
436
+ const output = stringify(object)
437
+
438
+ t.assert.doesNotThrow(() => JSON.parse(output))
439
+ t.assert.equal(output, '{"first":{"str":"test"},"second":{"int":42}}')
440
+ })
441
+
442
+ test('external reference to $id', (t) => {
443
+ t.plan(2)
444
+
445
+ const externalSchema = {
446
+ first: {
447
+ $id: 'external-reference',
448
+ type: 'object',
449
+ properties: {
450
+ str: {
451
+ type: 'string'
452
+ }
453
+ }
454
+ }
455
+ }
456
+
457
+ const schema = {
458
+ type: 'object',
459
+ properties: {
460
+ first: {
461
+ $ref: 'external-reference'
462
+ }
463
+ }
464
+ }
465
+
466
+ const object = { first: { str: 'test' } }
467
+
468
+ const stringify = build(schema, { schema: externalSchema })
469
+ const output = stringify(object)
470
+
471
+ t.assert.doesNotThrow(() => JSON.parse(output))
472
+ t.assert.equal(output, '{"first":{"str":"test"}}')
473
+ })
474
+
475
+ test('external reference to key#id', (t) => {
476
+ t.plan(2)
477
+
478
+ const externalSchema = {
479
+ first: {
480
+ $id: '#external-reference',
481
+ type: 'object',
482
+ properties: {
483
+ str: {
484
+ type: 'string'
485
+ }
486
+ }
487
+ }
488
+ }
489
+
490
+ const schema = {
491
+ type: 'object',
492
+ properties: {
493
+ first: {
494
+ $ref: 'first#external-reference'
495
+ }
496
+ }
497
+ }
498
+
499
+ const object = { first: { str: 'test' } }
500
+
501
+ const stringify = build(schema, { schema: externalSchema })
502
+ const output = stringify(object)
503
+
504
+ t.assert.doesNotThrow(() => JSON.parse(output))
505
+ t.assert.equal(output, '{"first":{"str":"test"}}')
506
+ })
507
+
508
+ test('external and inner reference', (t) => {
509
+ t.plan(2)
510
+
511
+ const externalSchema = {
512
+ first: {
513
+ $id: 'reference',
514
+ $ref: '#reference',
515
+ definitions: {
516
+ inner: {
517
+ $id: '#reference',
518
+ type: 'object',
519
+ properties: {
520
+ str: {
521
+ type: 'string'
522
+ }
523
+ }
524
+ }
525
+ }
526
+ }
527
+ }
528
+
529
+ const schema = {
530
+ type: 'object',
531
+ properties: {
532
+ first: {
533
+ $ref: 'reference'
534
+ }
535
+ }
536
+ }
537
+
538
+ const object = { first: { str: 'test' } }
539
+
540
+ const stringify = build(schema, { schema: externalSchema })
541
+ const output = stringify(object)
542
+
543
+ t.assert.doesNotThrow(() => JSON.parse(output))
544
+ t.assert.equal(output, '{"first":{"str":"test"}}')
545
+ })
546
+
547
+ test('external reference to key', (t) => {
548
+ t.plan(2)
549
+
550
+ const externalSchema = {
551
+ first: {
552
+ $id: 'external-reference',
553
+ type: 'object',
554
+ properties: {
555
+ str: {
556
+ type: 'string'
557
+ }
558
+ }
559
+ }
560
+ }
561
+
562
+ const schema = {
563
+ type: 'object',
564
+ properties: {
565
+ first: {
566
+ $ref: 'external-reference'
567
+ }
568
+ }
569
+ }
570
+
571
+ const object = { first: { str: 'test' } }
572
+
573
+ const stringify = build(schema, { schema: externalSchema })
574
+ const output = stringify(object)
575
+
576
+ t.assert.doesNotThrow(() => JSON.parse(output))
577
+ t.assert.equal(output, '{"first":{"str":"test"}}')
578
+ })
579
+
580
+ test('ref external - plain name fragment', (t) => {
581
+ t.plan(2)
582
+
583
+ const externalSchema = {
584
+ first: {
585
+ $id: 'first-schema',
586
+ type: 'object',
587
+ properties: {
588
+ str: {
589
+ type: 'string'
590
+ }
591
+ }
592
+ },
593
+ second: {
594
+ definitions: {
595
+ second: {
596
+ $id: 'second-schema',
597
+ type: 'object',
598
+ properties: {
599
+ int: {
600
+ type: 'integer'
601
+ }
602
+ }
603
+ }
604
+ }
605
+ }
606
+ }
607
+
608
+ const schema = {
609
+ title: 'object with $ref to external plain name fragment',
610
+ type: 'object',
611
+ properties: {
612
+ first: {
613
+ $ref: 'first-schema'
614
+ },
615
+ second: {
616
+ $ref: 'second-schema'
617
+ }
618
+ }
619
+ }
620
+
621
+ const object = {
622
+ first: {
623
+ str: 'test'
624
+ },
625
+ second: {
626
+ int: 42
627
+ }
628
+ }
629
+
630
+ const stringify = build(schema, { schema: externalSchema })
631
+ const output = stringify(object)
632
+
633
+ t.assert.doesNotThrow(() => JSON.parse(output))
634
+ t.assert.equal(output, '{"first":{"str":"test"},"second":{"int":42}}')
635
+ })
636
+
637
+ test('ref external - duplicate plain name fragment', (t) => {
638
+ t.plan(2)
639
+
640
+ const externalSchema = {
641
+ external: {
642
+ $id: '#duplicateSchema',
643
+ type: 'object',
644
+ properties: {
645
+ prop: {
646
+ type: 'boolean'
647
+ }
648
+ }
649
+ },
650
+ other: {
651
+ $id: '#otherSchema',
652
+ type: 'object',
653
+ properties: {
654
+ prop: {
655
+ type: 'integer'
656
+ }
657
+ }
658
+ }
659
+ }
660
+
661
+ const schema = {
662
+ title: 'object with $ref to plain name fragment',
663
+ type: 'object',
664
+ definitions: {
665
+ duplicate: {
666
+ $id: '#duplicateSchema',
667
+ type: 'object',
668
+ properties: {
669
+ prop: {
670
+ type: 'string'
671
+ }
672
+ }
673
+ }
674
+ },
675
+ properties: {
676
+ local: {
677
+ $ref: '#duplicateSchema'
678
+ },
679
+ external: {
680
+ $ref: 'external#duplicateSchema'
681
+ },
682
+ other: {
683
+ $ref: 'other#otherSchema'
684
+ }
685
+ }
686
+ }
687
+
688
+ const object = {
689
+ local: {
690
+ prop: 'test'
691
+ },
692
+ external: {
693
+ prop: true
694
+ },
695
+ other: {
696
+ prop: 42
697
+ }
698
+ }
699
+
700
+ const stringify = build(schema, { schema: externalSchema })
701
+ const output = stringify(object)
702
+
703
+ t.assert.doesNotThrow(() => JSON.parse(output))
704
+ t.assert.equal(output, '{"local":{"prop":"test"},"external":{"prop":true},"other":{"prop":42}}')
705
+ })
706
+
707
+ test('ref external - explicit external plain name fragment must not fallback to other external schemas', (t) => {
708
+ t.plan(1)
709
+
710
+ const externalSchema = {
711
+ first: {
712
+ $id: '#target',
713
+ type: 'object',
714
+ properties: {
715
+ prop: {
716
+ type: 'string'
717
+ }
718
+ }
719
+ },
720
+ second: {
721
+ $id: '#wrong',
722
+ type: 'object',
723
+ properties: {
724
+ prop: {
725
+ type: 'integer'
726
+ }
727
+ }
728
+ }
729
+ }
730
+
731
+ const schema = {
732
+ title: 'object with $ref to plain name fragment',
733
+ type: 'object',
734
+ definitions: {
735
+ third: {
736
+ $id: '#wrong',
737
+ type: 'object',
738
+ properties: {
739
+ prop: {
740
+ type: 'boolean'
741
+ }
742
+ }
743
+ }
744
+ },
745
+ properties: {
746
+ target: {
747
+ $ref: 'first#wrong'
748
+ }
749
+ }
750
+ }
751
+
752
+ const object = {
753
+ target: {
754
+ prop: 'test'
755
+ }
756
+ }
757
+
758
+ t.assert.throws(() => {
759
+ const stringify = build(schema, { schema: externalSchema })
760
+ const output = stringify(object)
761
+ JSON.parse(output)
762
+ }, {
763
+ message: 'Cannot find reference "first#wrong"'
764
+ })
765
+ })
766
+
767
+ test('ref internal - multiple $ref format', (t) => {
768
+ t.plan(2)
769
+
770
+ const schema = {
771
+ type: 'object',
772
+ definitions: {
773
+ one: {
774
+ type: 'string',
775
+ definitions: {
776
+ two: {
777
+ $id: '#twos',
778
+ type: 'string'
779
+ }
780
+ }
781
+ }
782
+ },
783
+ properties: {
784
+ zero: {
785
+ $id: '#three',
786
+ type: 'string'
787
+ },
788
+ a: { $ref: '#/definitions/one' },
789
+ b: { $ref: '#three' },
790
+ c: { $ref: '#/properties/zero' },
791
+ d: { $ref: '#twos' },
792
+ e: { $ref: '#/definitions/one/definitions/two' }
793
+ }
794
+ }
795
+
796
+ const object = {
797
+ zero: 'test',
798
+ a: 'test',
799
+ b: 'test',
800
+ c: 'test',
801
+ d: 'test',
802
+ e: 'test'
803
+ }
804
+
805
+ const stringify = build(schema)
806
+ const output = stringify(object)
807
+
808
+ t.assert.doesNotThrow(() => JSON.parse(output))
809
+ t.assert.equal(output, '{"zero":"test","a":"test","b":"test","c":"test","d":"test","e":"test"}')
810
+ })
811
+
812
+ test('ref external - external schema with internal ref (object property)', (t) => {
813
+ t.plan(2)
814
+
815
+ const externalSchema = {
816
+ external: {
817
+ definitions: {
818
+ internal: { type: 'string' },
819
+ def: {
820
+ type: 'object',
821
+ properties: {
822
+ prop: { $ref: '#/definitions/internal' }
823
+ }
824
+ }
825
+ }
826
+ }
827
+ }
828
+
829
+ const schema = {
830
+ title: 'object with $ref',
831
+ type: 'object',
832
+ properties: {
833
+ obj: {
834
+ $ref: 'external#/definitions/def'
835
+ }
836
+ }
837
+ }
838
+
839
+ const object = {
840
+ obj: {
841
+ prop: 'test'
842
+ }
843
+ }
844
+
845
+ const stringify = build(schema, { schema: externalSchema })
846
+ const output = stringify(object)
847
+
848
+ t.assert.doesNotThrow(() => JSON.parse(output))
849
+ t.assert.equal(output, '{"obj":{"prop":"test"}}')
850
+ })
851
+
852
+ test('ref external - external schema with internal ref (array items)', (t) => {
853
+ t.plan(2)
854
+
855
+ const externalSchema = {
856
+ external: {
857
+ definitions: {
858
+ internal: { type: 'string' },
859
+ def: {
860
+ type: 'object',
861
+ properties: {
862
+ prop: { $ref: '#/definitions/internal' }
863
+ }
864
+ }
865
+ }
866
+ }
867
+ }
868
+
869
+ const schema = {
870
+ title: 'object with $ref',
871
+ type: 'object',
872
+ properties: {
873
+ arr: {
874
+ type: 'array',
875
+ items: {
876
+ $ref: 'external#/definitions/def'
877
+ }
878
+ }
879
+ }
880
+ }
881
+
882
+ const object = {
883
+ arr: [{
884
+ prop: 'test'
885
+ }]
886
+ }
887
+
888
+ const stringify = build(schema, { schema: externalSchema })
889
+ const output = stringify(object)
890
+
891
+ t.assert.doesNotThrow(() => JSON.parse(output))
892
+ t.assert.equal(output, '{"arr":[{"prop":"test"}]}')
893
+ })
894
+
895
+ test('ref external - external schema with internal ref (root)', (t) => {
896
+ t.plan(2)
897
+
898
+ const externalSchema = {
899
+ external: {
900
+ definitions: {
901
+ internal: { type: 'string' },
902
+ def: {
903
+ type: 'object',
904
+ properties: {
905
+ prop: { $ref: '#/definitions/internal' }
906
+ }
907
+ }
908
+ }
909
+ }
910
+ }
911
+
912
+ const schema = {
913
+ title: 'object with $ref',
914
+ $ref: 'external#/definitions/def'
915
+ }
916
+
917
+ const object = {
918
+ prop: 'test'
919
+ }
920
+
921
+ const stringify = build(schema, { schema: externalSchema })
922
+ const output = stringify(object)
923
+
924
+ t.assert.doesNotThrow(() => JSON.parse(output))
925
+ t.assert.equal(output, '{"prop":"test"}')
926
+ })
927
+
928
+ test('ref external - external schema with internal ref (pattern properties)', (t) => {
929
+ t.plan(2)
930
+
931
+ const externalSchema = {
932
+ external: {
933
+ definitions: {
934
+ internal: { type: 'string' },
935
+ def: {
936
+ type: 'object',
937
+ patternProperties: {
938
+ '^p': { $ref: '#/definitions/internal' }
939
+ }
940
+ }
941
+ }
942
+ }
943
+ }
944
+
945
+ const schema = {
946
+ title: 'object with $ref',
947
+ type: 'object',
948
+ patternProperties: {
949
+ '^o': {
950
+ $ref: 'external#/definitions/def'
951
+ }
952
+ }
953
+ }
954
+
955
+ const object = {
956
+ obj: {
957
+ prop: 'test'
958
+ }
959
+ }
960
+
961
+ const stringify = build(schema, { schema: externalSchema })
962
+ const output = stringify(object)
963
+
964
+ t.assert.doesNotThrow(() => JSON.parse(output))
965
+ t.assert.equal(output, '{"obj":{"prop":"test"}}')
966
+ })
967
+
968
+ test('ref in root internal', (t) => {
969
+ t.plan(2)
970
+
971
+ const schema = {
972
+ title: 'object with $ref in root schema',
973
+ $ref: '#/definitions/num',
974
+ definitions: {
975
+ num: {
976
+ type: 'object',
977
+ properties: {
978
+ int: {
979
+ $ref: '#/definitions/int'
980
+ }
981
+ }
982
+ },
983
+ int: {
984
+ type: 'integer'
985
+ }
986
+ }
987
+ }
988
+
989
+ const object = { int: 42 }
990
+ const stringify = build(schema)
991
+ const output = stringify(object)
992
+
993
+ t.assert.doesNotThrow(() => JSON.parse(output))
994
+ t.assert.equal(output, '{"int":42}')
995
+ })
996
+
997
+ test('ref in root external', (t) => {
998
+ t.plan(2)
999
+
1000
+ const externalSchema = {
1001
+ numbers: {
1002
+ $id: 'numbers',
1003
+ definitions: {
1004
+ num: {
1005
+ type: 'object',
1006
+ properties: {
1007
+ int: {
1008
+ type: 'integer'
1009
+ }
1010
+ }
1011
+ }
1012
+ }
1013
+ }
1014
+ }
1015
+
1016
+ const schema = {
1017
+ title: 'object with $ref in root schema',
1018
+ type: 'object',
1019
+ $ref: 'numbers#/definitions/num'
1020
+ }
1021
+
1022
+ const object = { int: 42 }
1023
+ const stringify = build(schema, { schema: externalSchema })
1024
+ const output = stringify(object)
1025
+
1026
+ t.assert.doesNotThrow(() => JSON.parse(output))
1027
+ t.assert.equal(output, '{"int":42}')
1028
+ })
1029
+
1030
+ test('ref in root external multiple times', (t) => {
1031
+ t.plan(2)
1032
+
1033
+ const externalSchema = {
1034
+ numbers: {
1035
+ $id: 'numbers',
1036
+ $ref: 'subnumbers#/definitions/num'
1037
+ },
1038
+ subnumbers: {
1039
+ $id: 'subnumbers',
1040
+ definitions: {
1041
+ num: {
1042
+ type: 'object',
1043
+ properties: {
1044
+ int: {
1045
+ type: 'integer'
1046
+ }
1047
+ }
1048
+ }
1049
+ }
1050
+ }
1051
+ }
1052
+
1053
+ const schema = {
1054
+ title: 'object with $ref in root schema',
1055
+ type: 'object',
1056
+ $ref: 'numbers'
1057
+ }
1058
+
1059
+ const object = { int: 42 }
1060
+ const stringify = build(schema, { schema: externalSchema })
1061
+ const output = stringify(object)
1062
+
1063
+ t.assert.doesNotThrow(() => JSON.parse(output))
1064
+ t.assert.equal(output, '{"int":42}')
1065
+ })
1066
+
1067
+ test('ref external to relative definition', (t) => {
1068
+ t.plan(2)
1069
+
1070
+ const externalSchema = {
1071
+ 'relative:to:local': {
1072
+ $id: 'relative:to:local',
1073
+ type: 'object',
1074
+ properties: {
1075
+ foo: { $ref: '#/definitions/foo' }
1076
+ },
1077
+ definitions: {
1078
+ foo: { type: 'string' }
1079
+ }
1080
+ }
1081
+ }
1082
+
1083
+ const schema = {
1084
+ type: 'object',
1085
+ required: ['fooParent'],
1086
+ properties: {
1087
+ fooParent: { $ref: 'relative:to:local' }
1088
+ }
1089
+ }
1090
+
1091
+ const object = { fooParent: { foo: 'bar' } }
1092
+ const stringify = build(schema, { schema: externalSchema })
1093
+ const output = stringify(object)
1094
+
1095
+ t.assert.doesNotThrow(() => JSON.parse(output))
1096
+ t.assert.equal(output, '{"fooParent":{"foo":"bar"}}')
1097
+ })
1098
+
1099
+ test('ref to nested ref definition', (t) => {
1100
+ t.plan(2)
1101
+
1102
+ const externalSchema = {
1103
+ 'a:b:c1': {
1104
+ $id: 'a:b:c1',
1105
+ type: 'object',
1106
+ definitions: {
1107
+ foo: { $ref: 'a:b:c2#/definitions/foo' }
1108
+ }
1109
+ },
1110
+ 'a:b:c2': {
1111
+ $id: 'a:b:c2',
1112
+ type: 'object',
1113
+ definitions: {
1114
+ foo: { type: 'string' }
1115
+ }
1116
+ }
1117
+ }
1118
+
1119
+ const schema = {
1120
+ type: 'object',
1121
+ required: ['foo'],
1122
+ properties: {
1123
+ foo: { $ref: 'a:b:c1#/definitions/foo' }
1124
+ }
1125
+ }
1126
+
1127
+ const object = { foo: 'foo' }
1128
+ const stringify = build(schema, { schema: externalSchema })
1129
+ const output = stringify(object)
1130
+
1131
+ t.assert.doesNotThrow(() => JSON.parse(output))
1132
+ t.assert.equal(output, '{"foo":"foo"}')
1133
+ })
1134
+
1135
+ test('Bad key', async t => {
1136
+ await t.test('Find match', t => {
1137
+ t.plan(1)
1138
+ try {
1139
+ build({
1140
+ definitions: {
1141
+ projectId: {
1142
+ type: 'object',
1143
+ properties: {
1144
+ id: { type: 'integer' }
1145
+ }
1146
+ }
1147
+ },
1148
+ type: 'object',
1149
+ properties: {
1150
+ data: {
1151
+ $ref: '#/definitions/porjectId'
1152
+ }
1153
+ }
1154
+ })
1155
+ t.fail('Should throw')
1156
+ } catch (err) {
1157
+ t.assert.equal(err.message, 'Cannot find reference "#/definitions/porjectId"')
1158
+ }
1159
+ })
1160
+
1161
+ await t.test('No match', t => {
1162
+ t.plan(1)
1163
+
1164
+ t.assert.throws(() => {
1165
+ build({
1166
+ definitions: {
1167
+ projectId: {
1168
+ type: 'object',
1169
+ properties: {
1170
+ id: { type: 'integer' }
1171
+ }
1172
+ }
1173
+ },
1174
+ type: 'object',
1175
+ properties: {
1176
+ data: {
1177
+ $ref: '#/definitions/foobar'
1178
+ }
1179
+ }
1180
+ })
1181
+ }, { message: 'Cannot find reference "#/definitions/foobar"' })
1182
+ })
1183
+
1184
+ await t.test('Find match (external schema)', t => {
1185
+ t.plan(1)
1186
+ t.assert.throws(() => {
1187
+ build({
1188
+ type: 'object',
1189
+ properties: {
1190
+ data: {
1191
+ $ref: 'external#/definitions/porjectId'
1192
+ }
1193
+ }
1194
+ }, {
1195
+ schema: {
1196
+ external: {
1197
+ definitions: {
1198
+ projectId: {
1199
+ type: 'object',
1200
+ properties: {
1201
+ id: { type: 'integer' }
1202
+ }
1203
+ }
1204
+ }
1205
+ }
1206
+ }
1207
+ })
1208
+ t.fail('Should throw')
1209
+ }, { message: 'Cannot find reference "external#/definitions/porjectId"' })
1210
+ })
1211
+
1212
+ await t.test('No match (external schema)', t => {
1213
+ t.plan(1)
1214
+ t.assert.throws(() => {
1215
+ build({
1216
+ type: 'object',
1217
+ properties: {
1218
+ data: {
1219
+ $ref: 'external#/definitions/foobar'
1220
+ }
1221
+ }
1222
+ }, {
1223
+ schema: {
1224
+ external: {
1225
+ definitions: {
1226
+ projectId: {
1227
+ type: 'object',
1228
+ properties: {
1229
+ id: { type: 'integer' }
1230
+ }
1231
+ }
1232
+ }
1233
+ }
1234
+ }
1235
+ })
1236
+ }, { message: 'Cannot find reference "external#/definitions/foobar"' })
1237
+ })
1238
+
1239
+ await t.test('Find match (external definitions typo)', t => {
1240
+ t.plan(1)
1241
+ t.assert.throws(() => {
1242
+ build({
1243
+ type: 'object',
1244
+ properties: {
1245
+ data: {
1246
+ $ref: 'external#/deifnitions/projectId'
1247
+ }
1248
+ }
1249
+ }, {
1250
+ schema: {
1251
+ external: {
1252
+ definitions: {
1253
+ projectId: {
1254
+ type: 'object',
1255
+ properties: {
1256
+ id: { type: 'integer' }
1257
+ }
1258
+ }
1259
+ }
1260
+ }
1261
+ }
1262
+ })
1263
+ }, { message: 'Cannot find reference "external#/deifnitions/projectId"' })
1264
+ })
1265
+
1266
+ await t.test('Find match (definitions typo)', t => {
1267
+ t.plan(1)
1268
+ t.assert.throws(() => {
1269
+ build({
1270
+ definitions: {
1271
+ projectId: {
1272
+ type: 'object',
1273
+ properties: {
1274
+ id: { type: 'integer' }
1275
+ }
1276
+ }
1277
+ },
1278
+ type: 'object',
1279
+ properties: {
1280
+ data: {
1281
+ $ref: '#/deifnitions/projectId'
1282
+ }
1283
+ }
1284
+ })
1285
+ }, { message: 'Cannot find reference "#/deifnitions/projectId"' })
1286
+ })
1287
+
1288
+ await t.test('Find match (external schema typo)', t => {
1289
+ t.plan(1)
1290
+ t.assert.throws(() => {
1291
+ build({
1292
+ type: 'object',
1293
+ properties: {
1294
+ data: {
1295
+ $ref: 'extrenal#/definitions/projectId'
1296
+ }
1297
+ }
1298
+ }, {
1299
+ schema: {
1300
+ external: {
1301
+ definitions: {
1302
+ projectId: {
1303
+ type: 'object',
1304
+ properties: {
1305
+ id: { type: 'integer' }
1306
+ }
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+ })
1312
+ }, { message: 'Cannot resolve ref "extrenal#/definitions/projectId". Schema with id "extrenal" is not found.' })
1313
+ })
1314
+ })
1315
+
1316
+ test('Regression 2.5.2', t => {
1317
+ t.plan(1)
1318
+
1319
+ const externalSchema = {
1320
+ '/models/Bar': {
1321
+ $id: '/models/Bar',
1322
+ $schema: 'http://json-schema.org/schema#',
1323
+ definitions: {
1324
+ entity: {
1325
+ type: 'object',
1326
+ properties: { field: { type: 'string' } }
1327
+ }
1328
+ }
1329
+ },
1330
+ '/models/Foo': {
1331
+ $id: '/models/Foo',
1332
+ $schema: 'http://json-schema.org/schema#',
1333
+ definitions: {
1334
+ entity: {
1335
+ type: 'object',
1336
+ properties: {
1337
+ field: { type: 'string' },
1338
+ sub: {
1339
+ oneOf: [
1340
+ { $ref: '/models/Bar#/definitions/entity' },
1341
+ { type: 'null' }
1342
+ ]
1343
+ }
1344
+ }
1345
+ }
1346
+ }
1347
+ }
1348
+ }
1349
+
1350
+ const schema = {
1351
+ type: 'array',
1352
+ items: {
1353
+ $ref: '/models/Foo#/definitions/entity'
1354
+ }
1355
+ }
1356
+
1357
+ const stringify = build(schema, { schema: externalSchema })
1358
+ const output = stringify([{ field: 'parent', sub: { field: 'joined' } }])
1359
+
1360
+ t.assert.equal(output, '[{"field":"parent","sub":{"field":"joined"}}]')
1361
+ })
1362
+
1363
+ test('Reference through multiple definitions', (t) => {
1364
+ t.plan(2)
1365
+
1366
+ const schema = {
1367
+ $ref: '#/definitions/A',
1368
+ definitions: {
1369
+ A: {
1370
+ type: 'object',
1371
+ additionalProperties: false,
1372
+ properties: { a: { anyOf: [{ $ref: '#/definitions/B' }] } },
1373
+ required: ['a']
1374
+ },
1375
+ B: {
1376
+ type: 'object',
1377
+ properties: { b: { anyOf: [{ $ref: '#/definitions/C' }] } },
1378
+ required: ['b'],
1379
+ additionalProperties: false
1380
+ },
1381
+ C: {
1382
+ type: 'object',
1383
+ properties: { c: { type: 'string', const: 'd' } },
1384
+ required: ['c'],
1385
+ additionalProperties: false
1386
+ }
1387
+ }
1388
+ }
1389
+
1390
+ const object = { a: { b: { c: 'd' } } }
1391
+
1392
+ const stringify = build(schema)
1393
+ const output = stringify(object)
1394
+
1395
+ t.assert.doesNotThrow(() => JSON.parse(output))
1396
+ t.assert.equal(output, JSON.stringify(object))
1397
+ })
1398
+
1399
+ test('issue #350', (t) => {
1400
+ t.plan(2)
1401
+
1402
+ const schema = {
1403
+ title: 'Example Schema',
1404
+ type: 'object',
1405
+ properties: {
1406
+ firstName: { $ref: '#foo' },
1407
+ lastName: { $ref: '#foo' },
1408
+ nested: {
1409
+ type: 'object',
1410
+ properties: {
1411
+ firstName: { $ref: '#foo' },
1412
+ lastName: { $ref: '#foo' }
1413
+ }
1414
+ }
1415
+ },
1416
+ definitions: {
1417
+ foo: {
1418
+ $id: '#foo',
1419
+ type: 'string'
1420
+ }
1421
+ }
1422
+ }
1423
+
1424
+ const object = {
1425
+ firstName: 'Matteo',
1426
+ lastName: 'Collina',
1427
+ nested: {
1428
+ firstName: 'Matteo',
1429
+ lastName: 'Collina'
1430
+ }
1431
+ }
1432
+
1433
+ const stringify = build(schema)
1434
+ const output = stringify(object)
1435
+
1436
+ t.assert.doesNotThrow(() => JSON.parse(output))
1437
+ t.assert.equal(output, JSON.stringify(object))
1438
+ })
1439
+
1440
+ test('deep union type', (t) => {
1441
+ t.plan(1)
1442
+
1443
+ const stringify = build({
1444
+ schema: {
1445
+ type: 'array',
1446
+ items: {
1447
+ oneOf: [
1448
+ {
1449
+ $ref: 'components#/schemas/IDirectory'
1450
+ },
1451
+ {
1452
+ $ref: 'components#/schemas/IImageFile'
1453
+ },
1454
+ {
1455
+ $ref: 'components#/schemas/ITextFile'
1456
+ },
1457
+ {
1458
+ $ref: 'components#/schemas/IZipFile'
1459
+ }
1460
+ ]
1461
+ },
1462
+ nullable: false
1463
+ },
1464
+ components: {
1465
+ schemas: {
1466
+ IDirectory: {
1467
+ $id: 'IDirectory',
1468
+ $recursiveAnchor: true,
1469
+ type: 'object',
1470
+ properties: {
1471
+ children: {
1472
+ type: 'array',
1473
+ items: {
1474
+ oneOf: [
1475
+ {
1476
+ $recursiveRef: '#'
1477
+ },
1478
+ {
1479
+ $ref: 'components#/schemas/IImageFile'
1480
+ },
1481
+ {
1482
+ $ref: 'components#/schemas/ITextFile'
1483
+ },
1484
+ {
1485
+ $ref: 'components#/schemas/IZipFile'
1486
+ }
1487
+ ]
1488
+ },
1489
+ nullable: false
1490
+ },
1491
+ type: {
1492
+ type: 'string',
1493
+ nullable: false
1494
+ },
1495
+ id: {
1496
+ type: 'string',
1497
+ nullable: false
1498
+ },
1499
+ name: {
1500
+ type: 'string',
1501
+ nullable: false
1502
+ }
1503
+ },
1504
+ nullable: false,
1505
+ required: [
1506
+ 'children',
1507
+ 'type',
1508
+ 'id',
1509
+ 'name'
1510
+ ]
1511
+ },
1512
+ IImageFile: {
1513
+ $id: 'IImageFile',
1514
+ type: 'object',
1515
+ properties: {
1516
+ width: {
1517
+ type: 'number',
1518
+ nullable: false
1519
+ },
1520
+ height: {
1521
+ type: 'number',
1522
+ nullable: false
1523
+ },
1524
+ url: {
1525
+ type: 'string',
1526
+ nullable: false
1527
+ },
1528
+ extension: {
1529
+ type: 'string',
1530
+ nullable: false
1531
+ },
1532
+ size: {
1533
+ type: 'number',
1534
+ nullable: false
1535
+ },
1536
+ type: {
1537
+ type: 'string',
1538
+ nullable: false
1539
+ },
1540
+ id: {
1541
+ type: 'string',
1542
+ nullable: false
1543
+ },
1544
+ name: {
1545
+ type: 'string',
1546
+ nullable: false
1547
+ }
1548
+ },
1549
+ nullable: false,
1550
+ required: [
1551
+ 'width',
1552
+ 'height',
1553
+ 'url',
1554
+ 'extension',
1555
+ 'size',
1556
+ 'type',
1557
+ 'id',
1558
+ 'name'
1559
+ ]
1560
+ },
1561
+ ITextFile: {
1562
+ $id: 'ITextFile',
1563
+ type: 'object',
1564
+ properties: {
1565
+ content: {
1566
+ type: 'string',
1567
+ nullable: false
1568
+ },
1569
+ extension: {
1570
+ type: 'string',
1571
+ nullable: false
1572
+ },
1573
+ size: {
1574
+ type: 'number',
1575
+ nullable: false
1576
+ },
1577
+ type: {
1578
+ type: 'string',
1579
+ nullable: false
1580
+ },
1581
+ id: {
1582
+ type: 'string',
1583
+ nullable: false
1584
+ },
1585
+ name: {
1586
+ type: 'string',
1587
+ nullable: false
1588
+ }
1589
+ },
1590
+ nullable: false,
1591
+ required: [
1592
+ 'content',
1593
+ 'extension',
1594
+ 'size',
1595
+ 'type',
1596
+ 'id',
1597
+ 'name'
1598
+ ]
1599
+ },
1600
+ IZipFile: {
1601
+ $id: 'IZipFile',
1602
+ type: 'object',
1603
+ properties: {
1604
+ files: {
1605
+ type: 'number',
1606
+ nullable: false
1607
+ },
1608
+ extension: {
1609
+ type: 'string',
1610
+ nullable: false
1611
+ },
1612
+ size: {
1613
+ type: 'number',
1614
+ nullable: false
1615
+ },
1616
+ type: {
1617
+ type: 'string',
1618
+ nullable: false
1619
+ },
1620
+ id: {
1621
+ type: 'string',
1622
+ nullable: false
1623
+ },
1624
+ name: {
1625
+ type: 'string',
1626
+ nullable: false
1627
+ }
1628
+ },
1629
+ nullable: false,
1630
+ required: [
1631
+ 'files',
1632
+ 'extension',
1633
+ 'size',
1634
+ 'type',
1635
+ 'id',
1636
+ 'name'
1637
+ ]
1638
+ }
1639
+ }
1640
+ }
1641
+ })
1642
+
1643
+ const obj = [
1644
+ {
1645
+ type: 'directory',
1646
+ id: '7b1068a4-dd6e-474a-8d85-09a2d77639cb',
1647
+ name: 'ixcWGOKI',
1648
+ children: [
1649
+ {
1650
+ type: 'directory',
1651
+ id: '5883e17c-b207-46d4-ad2d-be72249711ce',
1652
+ name: 'vecQwFGS',
1653
+ children: []
1654
+ },
1655
+ {
1656
+ type: 'file',
1657
+ id: '670b6556-a610-4a48-8a16-9c2da97a0d18',
1658
+ name: 'eStFddzX',
1659
+ extension: 'jpg',
1660
+ size: 7,
1661
+ width: 300,
1662
+ height: 1200,
1663
+ url: 'https://github.com/samchon/typescript-json'
1664
+ },
1665
+ {
1666
+ type: 'file',
1667
+ id: '85dc796d-9593-4833-b1a1-addc8ebf74ea',
1668
+ name: 'kTdUfwRJ',
1669
+ extension: 'ts',
1670
+ size: 86,
1671
+ content: 'console.log("Hello world");'
1672
+ },
1673
+ {
1674
+ type: 'file',
1675
+ id: '8933c86a-7a1e-4d4a-b0a6-17d6896fdf89',
1676
+ name: 'NBPkefUG',
1677
+ extension: 'zip',
1678
+ size: 22,
1679
+ files: 20
1680
+ }
1681
+ ]
1682
+ }
1683
+ ]
1684
+ t.assert.equal(JSON.stringify(obj), stringify(obj))
1685
+ })
1686
+
1687
+ test('ref with same id in properties', async (t) => {
1688
+ t.plan(2)
1689
+
1690
+ const externalSchema = {
1691
+ ObjectId: {
1692
+ $id: 'ObjectId',
1693
+ type: 'string'
1694
+ },
1695
+ File: {
1696
+ $id: 'File',
1697
+ type: 'object',
1698
+ properties: {
1699
+ _id: { $ref: 'ObjectId' },
1700
+ name: { type: 'string' },
1701
+ owner: { $ref: 'ObjectId' }
1702
+ }
1703
+ }
1704
+ }
1705
+
1706
+ await t.test('anyOf', (t) => {
1707
+ t.plan(1)
1708
+
1709
+ const schema = {
1710
+ $id: 'Article',
1711
+ type: 'object',
1712
+ properties: {
1713
+ _id: { $ref: 'ObjectId' },
1714
+ image: {
1715
+ anyOf: [
1716
+ { $ref: 'File' },
1717
+ { type: 'null' }
1718
+ ]
1719
+ }
1720
+ }
1721
+ }
1722
+
1723
+ const stringify = build(schema, { schema: externalSchema })
1724
+ const output = stringify({ _id: 'foo', image: { _id: 'bar', name: 'hello', owner: 'baz' } })
1725
+
1726
+ t.assert.equal(output, '{"_id":"foo","image":{"_id":"bar","name":"hello","owner":"baz"}}')
1727
+ })
1728
+
1729
+ await t.test('oneOf', (t) => {
1730
+ t.plan(1)
1731
+
1732
+ const schema = {
1733
+ $id: 'Article',
1734
+ type: 'object',
1735
+ properties: {
1736
+ _id: { $ref: 'ObjectId' },
1737
+ image: {
1738
+ oneOf: [
1739
+ { $ref: 'File' },
1740
+ { type: 'null' }
1741
+ ]
1742
+ }
1743
+ }
1744
+ }
1745
+
1746
+ const stringify = build(schema, { schema: externalSchema })
1747
+ const output = stringify({ _id: 'foo', image: { _id: 'bar', name: 'hello', owner: 'baz' } })
1748
+
1749
+ t.assert.equal(output, '{"_id":"foo","image":{"_id":"bar","name":"hello","owner":"baz"}}')
1750
+ })
1751
+ })
1752
+
1753
+ test('Should not modify external schemas', (t) => {
1754
+ t.plan(2)
1755
+
1756
+ const externalSchema = {
1757
+ uuid: {
1758
+ format: 'uuid',
1759
+ $id: 'UUID',
1760
+ type: 'string'
1761
+ },
1762
+ Entity: {
1763
+ $id: 'Entity',
1764
+ type: 'object',
1765
+ properties: {
1766
+ id: { $ref: 'UUID' },
1767
+ id2: { $ref: 'UUID' }
1768
+ }
1769
+ }
1770
+ }
1771
+
1772
+ const options = { schema: externalSchema }
1773
+ const optionsClone = clone(options)
1774
+
1775
+ const stringify = build({ $ref: 'Entity' }, options)
1776
+
1777
+ const data = { id: 'a4e4c954-9f5f-443a-aa65-74d95732249a' }
1778
+ const output = stringify(data)
1779
+
1780
+ t.assert.equal(output, JSON.stringify(data))
1781
+ t.assert.deepStrictEqual(options, optionsClone)
1782
+ })
1783
+
1784
+ test('input schema is not mutated', (t) => {
1785
+ t.plan(3)
1786
+
1787
+ const schema = {
1788
+ title: 'object with $ref',
1789
+ type: 'object',
1790
+ definitions: {
1791
+ def: { type: 'string' }
1792
+ },
1793
+ properties: {
1794
+ obj: {
1795
+ $ref: '#/definitions/def'
1796
+ }
1797
+ }
1798
+ }
1799
+
1800
+ const clonedSchema = JSON.parse(JSON.stringify(schema))
1801
+
1802
+ const object = {
1803
+ obj: 'test'
1804
+ }
1805
+
1806
+ const stringify = build(schema)
1807
+ const output = stringify(object)
1808
+
1809
+ t.assert.doesNotThrow(() => JSON.parse(output))
1810
+ t.assert.equal(output, '{"obj":"test"}')
1811
+ t.assert.deepStrictEqual(schema, clonedSchema)
1812
+ })
1813
+
1814
+ test('anyOf inside allOf', (t) => {
1815
+ t.plan(1)
1816
+
1817
+ const schema = {
1818
+ anyOf: [
1819
+ {
1820
+ type: 'object',
1821
+ allOf: [
1822
+ {
1823
+ properties: {
1824
+ a: {
1825
+ anyOf: [
1826
+ { const: 'A1' },
1827
+ { const: 'A2' }
1828
+ ]
1829
+ }
1830
+ }
1831
+ },
1832
+ {
1833
+ properties: {
1834
+ b: { const: 'B' }
1835
+ }
1836
+ }
1837
+ ]
1838
+ }
1839
+ ]
1840
+ }
1841
+
1842
+ const object = { a: 'A1', b: 'B' }
1843
+ const stringify = build(schema)
1844
+ const output = stringify(object)
1845
+
1846
+ t.assert.equal(output, JSON.stringify(object))
1847
+ })
1848
+
1849
+ test('should resolve absolute $refs', (t) => {
1850
+ t.plan(1)
1851
+
1852
+ const externalSchema = {
1853
+ FooSchema: {
1854
+ $id: 'FooSchema',
1855
+ type: 'object',
1856
+ properties: {
1857
+ type: {
1858
+ anyOf: [
1859
+ { type: 'string', const: 'bar' },
1860
+ { type: 'string', const: 'baz' }
1861
+ ]
1862
+ }
1863
+ }
1864
+ }
1865
+ }
1866
+
1867
+ const schema = { $ref: 'FooSchema' }
1868
+
1869
+ const object = { type: 'bar' }
1870
+ const stringify = build(schema, { schema: externalSchema })
1871
+ const output = stringify(object)
1872
+
1873
+ t.assert.equal(output, JSON.stringify(object))
1874
+ })
1875
+
1876
+ test('nested schema should overwrite anchor scope', (t) => {
1877
+ t.plan(2)
1878
+
1879
+ const externalSchema = {
1880
+ root: {
1881
+ $id: 'root',
1882
+ definitions: {
1883
+ subschema: {
1884
+ $id: 'subschema',
1885
+ definitions: {
1886
+ anchorSchema: {
1887
+ $id: '#anchor',
1888
+ type: 'string'
1889
+ }
1890
+ }
1891
+ }
1892
+ }
1893
+ }
1894
+ }
1895
+
1896
+ const data = 'test'
1897
+ const stringify = build({ $ref: 'subschema#anchor' }, { schema: externalSchema })
1898
+ const output = stringify(data)
1899
+
1900
+ t.assert.equal(output, JSON.stringify(data))
1901
+ t.assert.throws(() => build({ $ref: 'root#anchor' }, { schema: externalSchema }))
1902
+ })
1903
+
1904
+ test('object property reference with default value', (t) => {
1905
+ t.plan(1)
1906
+
1907
+ const schema = {
1908
+ definitions: {
1909
+ prop: {
1910
+ type: 'string',
1911
+ default: 'foo'
1912
+ }
1913
+ },
1914
+ type: 'object',
1915
+ properties: {
1916
+ prop: {
1917
+ $ref: '#/definitions/prop'
1918
+ }
1919
+ }
1920
+ }
1921
+
1922
+ const stringify = build(schema)
1923
+ const output = stringify({})
1924
+
1925
+ t.assert.equal(output, '{"prop":"foo"}')
1926
+ })
1927
+
1928
+ test('should throw an Error if two non-identical schemas with same id are provided', (t) => {
1929
+ t.plan(1)
1930
+
1931
+ const schema = {
1932
+ $id: 'schema',
1933
+ type: 'object',
1934
+ allOf: [
1935
+ {
1936
+ $id: 'base',
1937
+ type: 'object',
1938
+ properties: {
1939
+ name: {
1940
+ type: 'string'
1941
+ }
1942
+ },
1943
+ required: [
1944
+ 'name'
1945
+ ]
1946
+ },
1947
+ {
1948
+ $id: 'inner_schema',
1949
+ type: 'object',
1950
+ properties: {
1951
+ union: {
1952
+ $id: '#id',
1953
+ anyOf: [
1954
+ {
1955
+
1956
+ $id: 'guid',
1957
+ type: 'string'
1958
+ },
1959
+ {
1960
+
1961
+ $id: 'email',
1962
+ type: 'string'
1963
+ }
1964
+ ]
1965
+ }
1966
+ },
1967
+ required: [
1968
+ 'union'
1969
+ ]
1970
+ },
1971
+ {
1972
+ $id: 'inner_schema',
1973
+ type: 'object',
1974
+ properties: {
1975
+ union: {
1976
+ $id: '#id',
1977
+ anyOf: [
1978
+ {
1979
+
1980
+ $id: 'guid',
1981
+ type: 'string'
1982
+ },
1983
+ {
1984
+
1985
+ $id: 'mail',
1986
+ type: 'string'
1987
+ }
1988
+ ]
1989
+ }
1990
+ },
1991
+ required: [
1992
+ 'union'
1993
+ ]
1994
+ }
1995
+ ]
1996
+ }
1997
+
1998
+ try {
1999
+ build(schema)
2000
+ } catch (err) {
2001
+ t.assert.equal(err.message, 'There is already another schema with id "inner_schema".')
2002
+ }
2003
+ })
2004
+
2005
+ test('ref internal - throw if schema has definition twice with different shape', (t) => {
2006
+ t.plan(1)
2007
+
2008
+ const schema = {
2009
+ $id: 'test',
2010
+ title: 'object with $ref',
2011
+ definitions: {
2012
+ def: {
2013
+ $id: '#uri',
2014
+ type: 'object',
2015
+ properties: {
2016
+ str: {
2017
+ type: 'string'
2018
+ }
2019
+ },
2020
+ required: ['str']
2021
+ },
2022
+ def2: {
2023
+ $id: '#uri',
2024
+ type: 'object',
2025
+ properties: {
2026
+ num: {
2027
+ type: 'number'
2028
+ }
2029
+ },
2030
+ required: ['num']
2031
+ }
2032
+ },
2033
+ type: 'object',
2034
+ properties: {
2035
+ obj: {
2036
+ $ref: '#uri'
2037
+ }
2038
+ }
2039
+ }
2040
+
2041
+ try {
2042
+ build(schema)
2043
+ } catch (err) {
2044
+ t.assert.equal(err.message, 'There is already another anchor "#uri" in schema "test".')
2045
+ }
2046
+ })
2047
+
2048
+ test('ref nested', (t) => {
2049
+ t.plan(2)
2050
+
2051
+ const schema = {
2052
+ definitions: {
2053
+ def1: {
2054
+ $ref: '#/definitions/def2'
2055
+ },
2056
+ def2: {
2057
+ type: 'string'
2058
+ }
2059
+ },
2060
+ type: 'object',
2061
+ properties: {
2062
+ str: {
2063
+ $ref: '#/definitions/def1'
2064
+ }
2065
+ }
2066
+ }
2067
+
2068
+ const object = {
2069
+ str: 'test'
2070
+ }
2071
+
2072
+ const stringify = build(schema)
2073
+ const output = stringify(object)
2074
+
2075
+ t.assert.doesNotThrow(() => JSON.parse(output))
2076
+ t.assert.equal(output, '{"str":"test"}')
2077
+ })