@eventvisor/sdk 0.0.2
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/LICENSE +21 -0
- package/README.md +9 -0
- package/dist/attributesManager.d.ts +36 -0
- package/dist/bucketer.d.ts +30 -0
- package/dist/compareVersions.d.ts +4 -0
- package/dist/conditions.d.ts +20 -0
- package/dist/datafileReader.d.ts +29 -0
- package/dist/effectsManager.d.ts +33 -0
- package/dist/emitter.d.ts +11 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/index.mjs.map +1 -0
- package/dist/instance.d.ts +67 -0
- package/dist/logger.d.ts +26 -0
- package/dist/modulesManager.d.ts +67 -0
- package/dist/murmurhash.d.ts +1 -0
- package/dist/persister.d.ts +40 -0
- package/dist/sourceResolver.d.ts +31 -0
- package/dist/transformer.d.ts +21 -0
- package/dist/validator.d.ts +28 -0
- package/jest.config.js +6 -0
- package/lib/attributesManager.d.ts +36 -0
- package/lib/bucketer.d.ts +30 -0
- package/lib/compareVersions.d.ts +4 -0
- package/lib/conditions.d.ts +20 -0
- package/lib/datafileReader.d.ts +29 -0
- package/lib/effectsManager.d.ts +33 -0
- package/lib/emitter.d.ts +11 -0
- package/lib/index.d.ts +12 -0
- package/lib/instance.d.ts +67 -0
- package/lib/logger.d.ts +26 -0
- package/lib/modulesManager.d.ts +67 -0
- package/lib/murmurhash.d.ts +1 -0
- package/lib/persister.d.ts +40 -0
- package/lib/sourceResolver.d.ts +31 -0
- package/lib/transformer.d.ts +21 -0
- package/lib/validator.d.ts +28 -0
- package/package.json +45 -0
- package/src/attributesManager.ts +181 -0
- package/src/bucketer.spec.ts +156 -0
- package/src/bucketer.ts +152 -0
- package/src/compareVersions.ts +93 -0
- package/src/conditions.ts +224 -0
- package/src/datafileReader.ts +133 -0
- package/src/effectsManager.ts +214 -0
- package/src/emitter.ts +64 -0
- package/src/index.spec.ts +5 -0
- package/src/index.ts +14 -0
- package/src/instance.spec.ts +184 -0
- package/src/instance.ts +608 -0
- package/src/logger.ts +90 -0
- package/src/modulesManager.ts +276 -0
- package/src/murmurhash.ts +71 -0
- package/src/persister.ts +162 -0
- package/src/sourceResolver.spec.ts +253 -0
- package/src/sourceResolver.ts +213 -0
- package/src/transformer.ts +316 -0
- package/src/transformer_static.spec.ts +377 -0
- package/src/transformer_types.spec.ts +820 -0
- package/src/validator.spec.ts +579 -0
- package/src/validator.ts +366 -0
- package/tsconfig.cjs.json +8 -0
- package/tsconfig.esm.json +8 -0
- package/webpack.config.js +80 -0
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
import { validate } from "./validator";
|
|
2
|
+
import { JSONSchema } from "@eventvisor/types";
|
|
3
|
+
|
|
4
|
+
describe("Validator", () => {
|
|
5
|
+
describe("Basic Type Validation", () => {
|
|
6
|
+
it("should validate string type correctly", async () => {
|
|
7
|
+
const schema: JSONSchema = { type: "string" };
|
|
8
|
+
const result = await validate(schema, "hello", {});
|
|
9
|
+
|
|
10
|
+
expect(result.valid).toBe(true);
|
|
11
|
+
expect(result.value).toBe("hello");
|
|
12
|
+
expect(result.errors).toBeUndefined();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("should reject invalid string type", async () => {
|
|
16
|
+
const schema: JSONSchema = { type: "string" };
|
|
17
|
+
const result = await validate(schema, 123, {});
|
|
18
|
+
|
|
19
|
+
expect(result.valid).toBe(false);
|
|
20
|
+
expect(result.errors).toHaveLength(1);
|
|
21
|
+
expect(result.errors![0].message).toContain("Expected type string");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should validate number type correctly", async () => {
|
|
25
|
+
const schema: JSONSchema = { type: "number" };
|
|
26
|
+
const result = await validate(schema, 42, {});
|
|
27
|
+
|
|
28
|
+
expect(result.valid).toBe(true);
|
|
29
|
+
expect(result.value).toBe(42);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should validate integer type correctly", async () => {
|
|
33
|
+
const schema: JSONSchema = { type: "integer" };
|
|
34
|
+
const result = await validate(schema, 42, {});
|
|
35
|
+
|
|
36
|
+
expect(result.valid).toBe(true);
|
|
37
|
+
expect(result.value).toBe(42);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should reject non-integer for integer type", async () => {
|
|
41
|
+
const schema: JSONSchema = { type: "integer" };
|
|
42
|
+
const result = await validate(schema, 42.5, {});
|
|
43
|
+
|
|
44
|
+
expect(result.valid).toBe(false);
|
|
45
|
+
expect(result.errors![0].message).toContain("Number must be an integer");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should validate boolean type correctly", async () => {
|
|
49
|
+
const schema: JSONSchema = { type: "boolean" };
|
|
50
|
+
const result = await validate(schema, true, {});
|
|
51
|
+
|
|
52
|
+
expect(result.valid).toBe(true);
|
|
53
|
+
expect(result.value).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should validate null type correctly", async () => {
|
|
57
|
+
const schema: JSONSchema = { type: "null" as any };
|
|
58
|
+
const result = await validate(schema, null, {});
|
|
59
|
+
|
|
60
|
+
expect(result.valid).toBe(true);
|
|
61
|
+
expect(result.value).toBe(null);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should validate object type correctly", async () => {
|
|
65
|
+
const schema: JSONSchema = { type: "object" };
|
|
66
|
+
const result = await validate(schema, { key: "value" }, {});
|
|
67
|
+
|
|
68
|
+
expect(result.valid).toBe(true);
|
|
69
|
+
expect(result.value).toEqual({ key: "value" });
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should validate array type correctly", async () => {
|
|
73
|
+
const schema: JSONSchema = { type: "array" };
|
|
74
|
+
const result = await validate(schema, [1, 2, 3], {});
|
|
75
|
+
|
|
76
|
+
expect(result.valid).toBe(true);
|
|
77
|
+
expect(result.value).toEqual([1, 2, 3]);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("String Validation", () => {
|
|
82
|
+
it("should validate minLength constraint", async () => {
|
|
83
|
+
const schema: JSONSchema = { type: "string", minLength: 3 };
|
|
84
|
+
const result = await validate(schema, "ab", {});
|
|
85
|
+
|
|
86
|
+
expect(result.valid).toBe(false);
|
|
87
|
+
expect(result.errors![0].message).toContain("at least 3 characters");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should validate maxLength constraint", async () => {
|
|
91
|
+
const schema: JSONSchema = { type: "string", maxLength: 5 };
|
|
92
|
+
const result = await validate(schema, "abcdef", {});
|
|
93
|
+
|
|
94
|
+
expect(result.valid).toBe(false);
|
|
95
|
+
expect(result.errors![0].message).toContain("at most 5 characters");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("should validate pattern constraint", async () => {
|
|
99
|
+
const schema: JSONSchema = { type: "string", pattern: "^[A-Z]+$" };
|
|
100
|
+
const result = await validate(schema, "hello", {});
|
|
101
|
+
|
|
102
|
+
expect(result.valid).toBe(false);
|
|
103
|
+
expect(result.errors![0].message).toContain("match pattern");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should accept valid pattern", async () => {
|
|
107
|
+
const schema: JSONSchema = { type: "string", pattern: "^[A-Z]+$" };
|
|
108
|
+
const result = await validate(schema, "HELLO", {});
|
|
109
|
+
|
|
110
|
+
expect(result.valid).toBe(true);
|
|
111
|
+
expect(result.value).toBe("HELLO");
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("Number Validation", () => {
|
|
116
|
+
it("should validate minimum constraint", async () => {
|
|
117
|
+
const schema: JSONSchema = { type: "number", minimum: 10 };
|
|
118
|
+
const result = await validate(schema, 5, {});
|
|
119
|
+
|
|
120
|
+
expect(result.valid).toBe(false);
|
|
121
|
+
expect(result.errors![0].message).toContain("at least 10");
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should validate maximum constraint", async () => {
|
|
125
|
+
const schema: JSONSchema = { type: "number", maximum: 100 };
|
|
126
|
+
const result = await validate(schema, 150, {});
|
|
127
|
+
|
|
128
|
+
expect(result.valid).toBe(false);
|
|
129
|
+
expect(result.errors![0].message).toContain("at most 100");
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("Array Validation", () => {
|
|
134
|
+
it("should validate minItems constraint", async () => {
|
|
135
|
+
const schema: JSONSchema = { type: "array", minItems: 3 };
|
|
136
|
+
const result = await validate(schema, [1, 2], {});
|
|
137
|
+
|
|
138
|
+
expect(result.valid).toBe(false);
|
|
139
|
+
expect(result.errors![0].message).toContain("at least 3 items");
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("should validate maxItems constraint", async () => {
|
|
143
|
+
const schema: JSONSchema = { type: "array", maxItems: 2 };
|
|
144
|
+
const result = await validate(schema, [1, 2, 3], {});
|
|
145
|
+
|
|
146
|
+
expect(result.valid).toBe(false);
|
|
147
|
+
expect(result.errors![0].message).toContain("at most 2 items");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("should validate array items with single schema", async () => {
|
|
151
|
+
const schema: JSONSchema = {
|
|
152
|
+
type: "array",
|
|
153
|
+
items: { type: "number" },
|
|
154
|
+
};
|
|
155
|
+
const result = await validate(schema, [1, "two", 3], {});
|
|
156
|
+
|
|
157
|
+
expect(result.valid).toBe(false);
|
|
158
|
+
expect(result.errors).toHaveLength(1);
|
|
159
|
+
expect(result.errors![0].path).toBe("[1]");
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("should validate array items with tuple schema", async () => {
|
|
163
|
+
const schema: JSONSchema = {
|
|
164
|
+
type: "array",
|
|
165
|
+
items: [{ type: "string" }, { type: "number" }],
|
|
166
|
+
};
|
|
167
|
+
const result = await validate(schema, ["hello", 42, "extra"], {});
|
|
168
|
+
|
|
169
|
+
expect(result.valid).toBe(true);
|
|
170
|
+
expect(result.value).toEqual(["hello", 42, "extra"]);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("Object Validation", () => {
|
|
175
|
+
it("should validate required properties", async () => {
|
|
176
|
+
const schema: JSONSchema = {
|
|
177
|
+
type: "object",
|
|
178
|
+
properties: {
|
|
179
|
+
name: { type: "string" },
|
|
180
|
+
age: { type: "number" },
|
|
181
|
+
},
|
|
182
|
+
required: ["name"],
|
|
183
|
+
};
|
|
184
|
+
const result = await validate(schema, { age: 25 }, {});
|
|
185
|
+
|
|
186
|
+
expect(result.valid).toBe(false);
|
|
187
|
+
expect(result.errors![0].message).toContain("Required property");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("should validate object properties", async () => {
|
|
191
|
+
const schema: JSONSchema = {
|
|
192
|
+
type: "object",
|
|
193
|
+
properties: {
|
|
194
|
+
name: { type: "string" },
|
|
195
|
+
age: { type: "number" },
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
const result = await validate(schema, { name: "John", age: "thirty" }, {});
|
|
199
|
+
|
|
200
|
+
expect(result.valid).toBe(false);
|
|
201
|
+
expect(result.errors![0].message).toContain("Expected type number");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("should allow additional properties by default", async () => {
|
|
205
|
+
const schema: JSONSchema = {
|
|
206
|
+
type: "object",
|
|
207
|
+
properties: {
|
|
208
|
+
name: { type: "string" },
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
const result = await validate(schema, { name: "John", extra: "value" }, {});
|
|
212
|
+
|
|
213
|
+
expect(result.valid).toBe(true);
|
|
214
|
+
expect(result.value).toEqual({ name: "John", extra: "value" });
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe("Enum and Const Validation", () => {
|
|
219
|
+
it("should validate enum values", async () => {
|
|
220
|
+
const schema: JSONSchema = {
|
|
221
|
+
type: "string",
|
|
222
|
+
enum: ["red", "green", "blue"],
|
|
223
|
+
};
|
|
224
|
+
const result = await validate(schema, "yellow", {});
|
|
225
|
+
|
|
226
|
+
expect(result.valid).toBe(false);
|
|
227
|
+
expect(result.errors![0].message).toContain("one of:");
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("should accept valid enum values", async () => {
|
|
231
|
+
const schema: JSONSchema = {
|
|
232
|
+
type: "string",
|
|
233
|
+
enum: ["red", "green", "blue"],
|
|
234
|
+
};
|
|
235
|
+
const result = await validate(schema, "red", {});
|
|
236
|
+
|
|
237
|
+
expect(result.valid).toBe(true);
|
|
238
|
+
expect(result.value).toBe("red");
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it("should validate const values", async () => {
|
|
242
|
+
const schema: JSONSchema = {
|
|
243
|
+
type: "string",
|
|
244
|
+
const: "exact",
|
|
245
|
+
};
|
|
246
|
+
const result = await validate(schema, "different", {});
|
|
247
|
+
|
|
248
|
+
expect(result.valid).toBe(false);
|
|
249
|
+
expect(result.errors![0].message).toContain("exactly");
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
describe("Default Values", () => {
|
|
254
|
+
it("should apply default for missing required field", async () => {
|
|
255
|
+
const schema: JSONSchema = {
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
name: { type: "string", default: "Anonymous" },
|
|
259
|
+
age: { type: "number" },
|
|
260
|
+
},
|
|
261
|
+
required: ["name", "age"],
|
|
262
|
+
};
|
|
263
|
+
const result = await validate(schema, { age: 25 }, {});
|
|
264
|
+
|
|
265
|
+
expect(result.valid).toBe(true);
|
|
266
|
+
expect(result.value).toEqual({ name: "Anonymous", age: 25 });
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("should apply default for missing optional field", async () => {
|
|
270
|
+
const schema: JSONSchema = {
|
|
271
|
+
type: "object",
|
|
272
|
+
properties: {
|
|
273
|
+
name: { type: "string" },
|
|
274
|
+
status: { type: "string", default: "active" },
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
const result = await validate(schema, { name: "John" }, {});
|
|
278
|
+
|
|
279
|
+
expect(result.valid).toBe(true);
|
|
280
|
+
expect(result.value).toEqual({ name: "John", status: "active" });
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it("should apply default for undefined value", async () => {
|
|
284
|
+
const schema: JSONSchema = {
|
|
285
|
+
type: "string",
|
|
286
|
+
default: "default value",
|
|
287
|
+
};
|
|
288
|
+
const result = await validate(schema, undefined, {});
|
|
289
|
+
|
|
290
|
+
expect(result.valid).toBe(true);
|
|
291
|
+
expect(result.value).toBe("default value");
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("should return default when validation fails and default exists", async () => {
|
|
295
|
+
const schema: JSONSchema = {
|
|
296
|
+
type: "number",
|
|
297
|
+
default: 42,
|
|
298
|
+
};
|
|
299
|
+
const result = await validate(schema, "not a number", {});
|
|
300
|
+
|
|
301
|
+
expect(result.valid).toBe(false);
|
|
302
|
+
expect(result.value).toBeUndefined();
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
describe("Complex Nested Validation", () => {
|
|
307
|
+
it("should validate deeply nested objects", async () => {
|
|
308
|
+
const schema: JSONSchema = {
|
|
309
|
+
type: "object",
|
|
310
|
+
properties: {
|
|
311
|
+
user: {
|
|
312
|
+
type: "object",
|
|
313
|
+
properties: {
|
|
314
|
+
profile: {
|
|
315
|
+
type: "object",
|
|
316
|
+
properties: {
|
|
317
|
+
name: { type: "string" },
|
|
318
|
+
age: { type: "number" },
|
|
319
|
+
},
|
|
320
|
+
required: ["name"],
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
required: ["profile"],
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const result = await validate(
|
|
329
|
+
schema,
|
|
330
|
+
{
|
|
331
|
+
user: {
|
|
332
|
+
profile: {
|
|
333
|
+
name: "John",
|
|
334
|
+
age: "invalid",
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
{},
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
expect(result.valid).toBe(false);
|
|
342
|
+
expect(result.errors![0].path).toBe("user.profile.age");
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it("should validate arrays of objects", async () => {
|
|
346
|
+
const schema: JSONSchema = {
|
|
347
|
+
type: "array",
|
|
348
|
+
items: {
|
|
349
|
+
type: "object",
|
|
350
|
+
properties: {
|
|
351
|
+
id: { type: "number" },
|
|
352
|
+
name: { type: "string" },
|
|
353
|
+
},
|
|
354
|
+
required: ["id"],
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const result = await validate(
|
|
359
|
+
schema,
|
|
360
|
+
[
|
|
361
|
+
{ id: 1, name: "John" },
|
|
362
|
+
{ name: "Jane" }, // missing id
|
|
363
|
+
{ id: 3, name: "Bob" },
|
|
364
|
+
],
|
|
365
|
+
{},
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
expect(result.valid).toBe(false);
|
|
369
|
+
expect(result.errors![0].path).toBe("[1].id");
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
describe("Edge Cases", () => {
|
|
374
|
+
it("should handle empty objects", async () => {
|
|
375
|
+
const schema: JSONSchema = { type: "object" };
|
|
376
|
+
const result = await validate(schema, {}, {});
|
|
377
|
+
|
|
378
|
+
expect(result.valid).toBe(true);
|
|
379
|
+
expect(result.value).toEqual({});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it("should handle empty arrays", async () => {
|
|
383
|
+
const schema: JSONSchema = { type: "array" };
|
|
384
|
+
const result = await validate(schema, [], {});
|
|
385
|
+
|
|
386
|
+
expect(result.valid).toBe(true);
|
|
387
|
+
expect(result.value).toEqual([]);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it("should handle null in enum", async () => {
|
|
391
|
+
const schema: JSONSchema = {
|
|
392
|
+
type: "string",
|
|
393
|
+
enum: ["value", null],
|
|
394
|
+
};
|
|
395
|
+
const result = await validate(schema, null, {});
|
|
396
|
+
|
|
397
|
+
expect(result.valid).toBe(true);
|
|
398
|
+
expect(result.value).toBe(null);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it("should handle undefined values gracefully", async () => {
|
|
402
|
+
const schema: JSONSchema = { type: "string" };
|
|
403
|
+
const result = await validate(schema, undefined, {});
|
|
404
|
+
|
|
405
|
+
expect(result.valid).toBe(false);
|
|
406
|
+
expect(result.errors![0].message).toContain("Required field missing");
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
describe("Error Reporting", () => {
|
|
411
|
+
it("should provide detailed error paths", async () => {
|
|
412
|
+
const schema: JSONSchema = {
|
|
413
|
+
type: "object",
|
|
414
|
+
properties: {
|
|
415
|
+
users: {
|
|
416
|
+
type: "array",
|
|
417
|
+
items: {
|
|
418
|
+
type: "object",
|
|
419
|
+
properties: {
|
|
420
|
+
name: { type: "string" },
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
const result = await validate(
|
|
428
|
+
schema,
|
|
429
|
+
{
|
|
430
|
+
users: [{ name: 123 }, { name: "valid" }],
|
|
431
|
+
},
|
|
432
|
+
{},
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
expect(result.valid).toBe(false);
|
|
436
|
+
expect(result.errors![0].path).toBe("users[0].name");
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it("should include schema and value in errors", async () => {
|
|
440
|
+
const schema: JSONSchema = { type: "number" };
|
|
441
|
+
const result = await validate(schema, "not a number", {});
|
|
442
|
+
|
|
443
|
+
expect(result.errors![0].schema).toBe(schema);
|
|
444
|
+
expect(result.errors![0].value).toBe("not a number");
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
describe("JavaScript Error Object Validation", () => {
|
|
449
|
+
it("should validate JavaScript Error objects with name, message, stack properties", async () => {
|
|
450
|
+
const schema: JSONSchema = {
|
|
451
|
+
type: "object",
|
|
452
|
+
properties: {
|
|
453
|
+
name: { type: "string" },
|
|
454
|
+
message: { type: "string" },
|
|
455
|
+
stack: { type: "string" },
|
|
456
|
+
errors: {
|
|
457
|
+
type: "array",
|
|
458
|
+
items: {
|
|
459
|
+
type: "object",
|
|
460
|
+
properties: {
|
|
461
|
+
name: { type: "string" },
|
|
462
|
+
message: { type: "string" },
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
},
|
|
467
|
+
required: ["message"],
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
const errorObj = new Error("Test error message");
|
|
471
|
+
errorObj.name = "TestError";
|
|
472
|
+
errorObj.stack = "Error: Test error message\n at test.js:1:1";
|
|
473
|
+
|
|
474
|
+
const result = await validate(schema, errorObj as any, {});
|
|
475
|
+
|
|
476
|
+
expect(result.valid).toBe(true);
|
|
477
|
+
expect(result.value).toEqual({
|
|
478
|
+
name: "TestError",
|
|
479
|
+
message: "Test error message",
|
|
480
|
+
stack: "Error: Test error message\n at test.js:1:1",
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it("should validate Error objects with additional errors array", async () => {
|
|
485
|
+
const schema: JSONSchema = {
|
|
486
|
+
type: "object",
|
|
487
|
+
properties: {
|
|
488
|
+
name: { type: "string" },
|
|
489
|
+
message: { type: "string" },
|
|
490
|
+
stack: { type: "string" },
|
|
491
|
+
errors: {
|
|
492
|
+
type: "array",
|
|
493
|
+
items: {
|
|
494
|
+
type: "object",
|
|
495
|
+
properties: {
|
|
496
|
+
name: { type: "string" },
|
|
497
|
+
message: { type: "string" },
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
required: ["message"],
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
const errorObj = {
|
|
506
|
+
name: "ValidationError",
|
|
507
|
+
message: "Multiple validation errors occurred",
|
|
508
|
+
stack: "ValidationError: Multiple validation errors occurred",
|
|
509
|
+
errors: [
|
|
510
|
+
{ name: "TypeError", message: "Expected string, got number" },
|
|
511
|
+
{ name: "ReferenceError", message: "Variable not defined" },
|
|
512
|
+
],
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const result = await validate(schema, errorObj, {});
|
|
516
|
+
|
|
517
|
+
expect(result.valid).toBe(true);
|
|
518
|
+
expect(result.value).toEqual(errorObj);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it("should fail validation when required message property is missing", async () => {
|
|
522
|
+
const schema: JSONSchema = {
|
|
523
|
+
type: "object",
|
|
524
|
+
properties: {
|
|
525
|
+
name: { type: "string" },
|
|
526
|
+
message: { type: "string" },
|
|
527
|
+
stack: { type: "string" },
|
|
528
|
+
},
|
|
529
|
+
required: ["message"],
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
const errorObj = {
|
|
533
|
+
name: "TestError",
|
|
534
|
+
stack: "Error stack trace",
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
const result = await validate(schema, errorObj, {});
|
|
538
|
+
|
|
539
|
+
expect(result.valid).toBe(false);
|
|
540
|
+
expect(result.errors![0].message).toContain("Required property 'message' is missing");
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
it("should fail validation when errors array contains invalid items", async () => {
|
|
544
|
+
const schema: JSONSchema = {
|
|
545
|
+
type: "object",
|
|
546
|
+
properties: {
|
|
547
|
+
name: { type: "string" },
|
|
548
|
+
message: { type: "string" },
|
|
549
|
+
errors: {
|
|
550
|
+
type: "array",
|
|
551
|
+
items: {
|
|
552
|
+
type: "object",
|
|
553
|
+
properties: {
|
|
554
|
+
name: { type: "string" },
|
|
555
|
+
message: { type: "string" },
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
required: ["message"],
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const errorObj = {
|
|
564
|
+
name: "TestError",
|
|
565
|
+
message: "Test error",
|
|
566
|
+
errors: [
|
|
567
|
+
{ name: "ValidError", message: "Valid message" },
|
|
568
|
+
{ name: 123, message: "Invalid name type" }, // name should be string
|
|
569
|
+
],
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
const result = await validate(schema, errorObj, {});
|
|
573
|
+
|
|
574
|
+
expect(result.valid).toBe(false);
|
|
575
|
+
expect(result.errors![0].path).toBe("errors[1].name");
|
|
576
|
+
expect(result.errors![0].message).toContain("Expected type string");
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
});
|