@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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -0
  3. package/dist/attributesManager.d.ts +36 -0
  4. package/dist/bucketer.d.ts +30 -0
  5. package/dist/compareVersions.d.ts +4 -0
  6. package/dist/conditions.d.ts +20 -0
  7. package/dist/datafileReader.d.ts +29 -0
  8. package/dist/effectsManager.d.ts +33 -0
  9. package/dist/emitter.d.ts +11 -0
  10. package/dist/index.d.ts +12 -0
  11. package/dist/index.js +2 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/index.mjs +2 -0
  14. package/dist/index.mjs.gz +0 -0
  15. package/dist/index.mjs.map +1 -0
  16. package/dist/instance.d.ts +67 -0
  17. package/dist/logger.d.ts +26 -0
  18. package/dist/modulesManager.d.ts +67 -0
  19. package/dist/murmurhash.d.ts +1 -0
  20. package/dist/persister.d.ts +40 -0
  21. package/dist/sourceResolver.d.ts +31 -0
  22. package/dist/transformer.d.ts +21 -0
  23. package/dist/validator.d.ts +28 -0
  24. package/jest.config.js +6 -0
  25. package/lib/attributesManager.d.ts +36 -0
  26. package/lib/bucketer.d.ts +30 -0
  27. package/lib/compareVersions.d.ts +4 -0
  28. package/lib/conditions.d.ts +20 -0
  29. package/lib/datafileReader.d.ts +29 -0
  30. package/lib/effectsManager.d.ts +33 -0
  31. package/lib/emitter.d.ts +11 -0
  32. package/lib/index.d.ts +12 -0
  33. package/lib/instance.d.ts +67 -0
  34. package/lib/logger.d.ts +26 -0
  35. package/lib/modulesManager.d.ts +67 -0
  36. package/lib/murmurhash.d.ts +1 -0
  37. package/lib/persister.d.ts +40 -0
  38. package/lib/sourceResolver.d.ts +31 -0
  39. package/lib/transformer.d.ts +21 -0
  40. package/lib/validator.d.ts +28 -0
  41. package/package.json +45 -0
  42. package/src/attributesManager.ts +181 -0
  43. package/src/bucketer.spec.ts +156 -0
  44. package/src/bucketer.ts +152 -0
  45. package/src/compareVersions.ts +93 -0
  46. package/src/conditions.ts +224 -0
  47. package/src/datafileReader.ts +133 -0
  48. package/src/effectsManager.ts +214 -0
  49. package/src/emitter.ts +64 -0
  50. package/src/index.spec.ts +5 -0
  51. package/src/index.ts +14 -0
  52. package/src/instance.spec.ts +184 -0
  53. package/src/instance.ts +608 -0
  54. package/src/logger.ts +90 -0
  55. package/src/modulesManager.ts +276 -0
  56. package/src/murmurhash.ts +71 -0
  57. package/src/persister.ts +162 -0
  58. package/src/sourceResolver.spec.ts +253 -0
  59. package/src/sourceResolver.ts +213 -0
  60. package/src/transformer.ts +316 -0
  61. package/src/transformer_static.spec.ts +377 -0
  62. package/src/transformer_types.spec.ts +820 -0
  63. package/src/validator.spec.ts +579 -0
  64. package/src/validator.ts +366 -0
  65. package/tsconfig.cjs.json +8 -0
  66. package/tsconfig.esm.json +8 -0
  67. package/webpack.config.js +80 -0
@@ -0,0 +1,366 @@
1
+ import { JSONSchema, Value } from "@eventvisor/types";
2
+
3
+ import type { GetSourceResolver } from "./sourceResolver";
4
+ import type { Logger } from "./logger";
5
+
6
+ export interface ValidatorOptions {
7
+ logger: Logger;
8
+ getSourceResolver: GetSourceResolver;
9
+ }
10
+
11
+ export class Validator {
12
+ private logger: Logger;
13
+ private getSourceResolver: GetSourceResolver;
14
+
15
+ constructor(options: ValidatorOptions) {
16
+ this.logger = options.logger;
17
+ this.getSourceResolver = options.getSourceResolver;
18
+ }
19
+
20
+ validate(schema: JSONSchema, value: Value): Promise<ValidationResult> {
21
+ const deps: ValidationDependencies = {};
22
+
23
+ return validate(schema, value, deps);
24
+ }
25
+ }
26
+
27
+ export interface ValidationError {
28
+ path: string;
29
+ message: string;
30
+ schema?: JSONSchema;
31
+ value?: Value;
32
+ }
33
+
34
+ export interface ValidationResult {
35
+ valid: boolean;
36
+ errors?: ValidationError[];
37
+ value?: Value;
38
+ }
39
+
40
+ export interface ValidationDependencies {
41
+ [key: string]: any;
42
+ }
43
+
44
+ export async function validate(
45
+ schema: JSONSchema,
46
+ value: Value,
47
+ deps: ValidationDependencies,
48
+ ): Promise<ValidationResult> {
49
+ const errors: ValidationError[] = [];
50
+ const result = validateValue(schema, value, "", errors, deps);
51
+
52
+ // Only apply default if there are no validation errors and result is undefined
53
+ if (result === undefined && errors.length === 0 && schema.default !== undefined) {
54
+ return {
55
+ valid: true,
56
+ value: schema.default,
57
+ errors: [],
58
+ };
59
+ }
60
+
61
+ return {
62
+ valid: errors.length === 0,
63
+ errors: errors.length > 0 ? errors : undefined,
64
+ value: result,
65
+ };
66
+ }
67
+
68
+ function validateValue(
69
+ schema: JSONSchema,
70
+ value: Value,
71
+ path: string,
72
+ errors: ValidationError[],
73
+ deps: ValidationDependencies,
74
+ ): Value | undefined {
75
+ // Handle null values
76
+ if (value === null) {
77
+ if ((schema.type as any) === "null" || schema.enum?.includes(null)) {
78
+ return value;
79
+ }
80
+ if (schema.type && (schema.type as any) !== "null") {
81
+ errors.push({
82
+ path,
83
+ message: `Expected type ${schema.type}, got null`,
84
+ schema,
85
+ value,
86
+ });
87
+ return undefined;
88
+ }
89
+ }
90
+
91
+ // Handle undefined values
92
+ if (value === undefined) {
93
+ if (schema.default !== undefined) {
94
+ return schema.default;
95
+ }
96
+ if (schema.type) {
97
+ errors.push({
98
+ path,
99
+ message: `Required field missing`,
100
+ schema,
101
+ value,
102
+ });
103
+ return undefined;
104
+ }
105
+ return undefined;
106
+ }
107
+
108
+ // Type validation (but allow number for integer type to handle specific validation)
109
+ if (schema.type && schema.type !== "integer") {
110
+ const typeValid = validateType(schema.type, value);
111
+ if (!typeValid) {
112
+ errors.push({
113
+ path,
114
+ message: `Expected type ${schema.type}, got ${typeof value}`,
115
+ schema,
116
+ value,
117
+ });
118
+ return undefined;
119
+ }
120
+ }
121
+
122
+ // Const validation
123
+ if (schema.const !== undefined && value !== schema.const) {
124
+ errors.push({
125
+ path,
126
+ message: `Value must be exactly ${JSON.stringify(schema.const)}`,
127
+ schema,
128
+ value,
129
+ });
130
+ return undefined;
131
+ }
132
+
133
+ // Enum validation
134
+ if (schema.enum && !schema.enum.includes(value)) {
135
+ errors.push({
136
+ path,
137
+ message: `Value must be one of: ${schema.enum.map((v) => JSON.stringify(v)).join(", ")}`,
138
+ schema,
139
+ value,
140
+ });
141
+ return undefined;
142
+ }
143
+
144
+ let result = value;
145
+
146
+ // Object validation
147
+ if (typeof value === "object" && !Array.isArray(value) && schema.properties) {
148
+ // Handle JavaScript Error objects specially
149
+ let obj: Record<string, Value>;
150
+ if (value instanceof Error) {
151
+ obj = {
152
+ name: value.name,
153
+ message: value.message,
154
+ stack: value.stack,
155
+ ...(value as any), // Include any additional properties
156
+ };
157
+ } else {
158
+ obj = value as Record<string, Value>;
159
+ }
160
+ const validatedObj: Record<string, Value> = {};
161
+
162
+ // Validate required properties
163
+ if (schema.required) {
164
+ for (const requiredProp of schema.required) {
165
+ if (!(requiredProp in obj)) {
166
+ if (schema.properties[requiredProp]?.default !== undefined) {
167
+ validatedObj[requiredProp] = schema.properties[requiredProp].default!;
168
+ } else {
169
+ errors.push({
170
+ path: path ? `${path}.${requiredProp}` : requiredProp,
171
+ message: `Required property '${requiredProp}' is missing`,
172
+ schema: schema.properties[requiredProp],
173
+ value: undefined,
174
+ });
175
+ }
176
+ }
177
+ }
178
+ }
179
+
180
+ // Validate all properties
181
+ for (const [prop, propValue] of Object.entries(obj)) {
182
+ if (schema.properties && schema.properties[prop]) {
183
+ const propSchema = schema.properties[prop];
184
+ const propPath = path ? `${path}.${prop}` : prop;
185
+ const validatedProp = validateValue(propSchema, propValue, propPath, errors, deps);
186
+ if (validatedProp !== undefined) {
187
+ validatedObj[prop] = validatedProp;
188
+ }
189
+ } else {
190
+ // Allow additional properties by default (JSON Schema behavior)
191
+ validatedObj[prop] = propValue;
192
+ }
193
+ }
194
+
195
+ // Apply defaults for missing optional properties
196
+ if (schema.properties) {
197
+ for (const [prop, propSchema] of Object.entries(schema.properties)) {
198
+ if (!(prop in validatedObj) && propSchema.default !== undefined) {
199
+ validatedObj[prop] = propSchema.default;
200
+ }
201
+ }
202
+ }
203
+
204
+ result = validatedObj;
205
+ }
206
+
207
+ // Array validation
208
+ if (Array.isArray(value)) {
209
+ // Array length validation - check before processing items
210
+ if (schema.minItems !== undefined && value.length < schema.minItems) {
211
+ errors.push({
212
+ path,
213
+ message: `Array must have at least ${schema.minItems} items, got ${value.length}`,
214
+ schema,
215
+ value,
216
+ });
217
+ return undefined;
218
+ }
219
+
220
+ if (schema.maxItems !== undefined && value.length > schema.maxItems) {
221
+ errors.push({
222
+ path,
223
+ message: `Array must have at most ${schema.maxItems} items, got ${value.length}`,
224
+ schema,
225
+ value,
226
+ });
227
+ return undefined;
228
+ }
229
+
230
+ if (schema.items) {
231
+ const validatedArray: Value[] = [];
232
+
233
+ if (Array.isArray(schema.items)) {
234
+ // Tuple validation
235
+ for (let i = 0; i < value.length; i++) {
236
+ const itemSchema = schema.items[i];
237
+ if (itemSchema) {
238
+ const itemPath = `${path}[${i}]`;
239
+ const validatedItem = validateValue(itemSchema, value[i], itemPath, errors, deps);
240
+ if (validatedItem !== undefined) {
241
+ validatedArray.push(validatedItem);
242
+ }
243
+ } else {
244
+ validatedArray.push(value[i]);
245
+ }
246
+ }
247
+ } else {
248
+ // Single schema for all items
249
+ for (let i = 0; i < value.length; i++) {
250
+ const itemPath = `${path}[${i}]`;
251
+ const validatedItem = validateValue(schema.items, value[i], itemPath, errors, deps);
252
+ if (validatedItem !== undefined) {
253
+ validatedArray.push(validatedItem);
254
+ }
255
+ }
256
+ }
257
+
258
+ result = validatedArray;
259
+ } else {
260
+ result = value;
261
+ }
262
+ }
263
+
264
+ // String validation
265
+ if (typeof value === "string") {
266
+ if (schema.minLength !== undefined && value.length < schema.minLength) {
267
+ errors.push({
268
+ path,
269
+ message: `String must be at least ${schema.minLength} characters long`,
270
+ schema,
271
+ value,
272
+ });
273
+ return undefined;
274
+ }
275
+
276
+ if (schema.maxLength !== undefined && value.length > schema.maxLength) {
277
+ errors.push({
278
+ path,
279
+ message: `String must be at most ${schema.maxLength} characters long`,
280
+ schema,
281
+ value,
282
+ });
283
+ return undefined;
284
+ }
285
+
286
+ if (schema.pattern) {
287
+ const regex = new RegExp(schema.pattern);
288
+ if (!regex.test(value)) {
289
+ errors.push({
290
+ path,
291
+ message: `String must match pattern: ${schema.pattern}`,
292
+ schema,
293
+ value,
294
+ });
295
+ return undefined;
296
+ }
297
+ }
298
+ }
299
+
300
+ // Number validation
301
+ if (typeof value === "number") {
302
+ if (schema.minimum !== undefined && value < schema.minimum) {
303
+ errors.push({
304
+ path,
305
+ message: `Number must be at least ${schema.minimum}`,
306
+ schema,
307
+ value,
308
+ });
309
+ return undefined;
310
+ }
311
+
312
+ if (schema.maximum !== undefined && value > schema.maximum) {
313
+ errors.push({
314
+ path,
315
+ message: `Number must be at most ${schema.maximum}`,
316
+ schema,
317
+ value,
318
+ });
319
+ return undefined;
320
+ }
321
+
322
+ if (schema.type === "integer" && !Number.isInteger(value)) {
323
+ errors.push({
324
+ path,
325
+ message: "Number must be an integer",
326
+ schema,
327
+ value,
328
+ });
329
+ return undefined;
330
+ }
331
+ }
332
+
333
+ // Integer type validation (after number validation)
334
+ if (schema.type === "integer" && typeof value !== "number") {
335
+ errors.push({
336
+ path,
337
+ message: `Expected type integer, got ${typeof value}`,
338
+ schema,
339
+ value,
340
+ });
341
+ return undefined;
342
+ }
343
+
344
+ return result;
345
+ }
346
+
347
+ function validateType(expectedType: string, value: Value): boolean {
348
+ switch (expectedType) {
349
+ case "string":
350
+ return typeof value === "string";
351
+ case "number":
352
+ return typeof value === "number";
353
+ case "integer":
354
+ return typeof value === "number" && Number.isInteger(value);
355
+ case "boolean":
356
+ return typeof value === "boolean";
357
+ case "null":
358
+ return value === null;
359
+ case "object":
360
+ return typeof value === "object" && value !== null && !Array.isArray(value);
361
+ case "array":
362
+ return Array.isArray(value);
363
+ default:
364
+ return true; // Unknown type, assume valid
365
+ }
366
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.cjs.json",
3
+ "compilerOptions": {
4
+ "outDir": "./lib",
5
+ "lib": ["DOM"]
6
+ },
7
+ "include": ["./src/**/*.ts"]
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.esm.json",
3
+ "compilerOptions": {
4
+ "outDir": "./lib",
5
+ "lib": ["DOM"]
6
+ },
7
+ "include": ["./src/**/*.ts"]
8
+ }
@@ -0,0 +1,80 @@
1
+ const path = require("path");
2
+
3
+ module.exports = [
4
+ // cjs
5
+ {
6
+ entry: {
7
+ "index.cjs": path.join(__dirname, "src", "index.ts"),
8
+ },
9
+ output: {
10
+ path: path.join(__dirname, "dist"),
11
+ filename: "index.js",
12
+ library: "EventvisorSDK",
13
+ libraryTarget: "umd",
14
+ globalObject: "this",
15
+ },
16
+ mode: "production",
17
+ devtool: "source-map",
18
+ resolve: {
19
+ extensions: [".ts", ".tsx", ".js"],
20
+ },
21
+ module: {
22
+ rules: [
23
+ {
24
+ test: /\.(ts|tsx)$/,
25
+ exclude: /(node_modules)/,
26
+ use: [
27
+ {
28
+ loader: "ts-loader",
29
+ options: {
30
+ configFile: path.join(__dirname, "tsconfig.cjs.json"),
31
+ transpileOnly: true,
32
+ },
33
+ },
34
+ ],
35
+ },
36
+ ],
37
+ },
38
+ performance: {
39
+ hints: false,
40
+ },
41
+ optimization: {
42
+ minimize: true,
43
+ },
44
+ },
45
+
46
+ // esm
47
+ {
48
+ entry: path.join(__dirname, "src", "index.ts"),
49
+ output: {
50
+ path: path.join(__dirname, "dist"),
51
+ filename: "index.mjs",
52
+ library: {
53
+ type: "module",
54
+ },
55
+ },
56
+ experiments: {
57
+ outputModule: true,
58
+ },
59
+ mode: "production",
60
+ devtool: "source-map",
61
+ resolve: {
62
+ extensions: [".ts", ".tsx", ".js"],
63
+ },
64
+ module: {
65
+ rules: [
66
+ {
67
+ test: /\.(ts|tsx)$/,
68
+ exclude: /(node_modules)/,
69
+ loader: "ts-loader",
70
+ options: {
71
+ configFile: path.join(__dirname, "tsconfig.esm.json"),
72
+ },
73
+ },
74
+ ],
75
+ },
76
+ performance: {
77
+ hints: false,
78
+ },
79
+ },
80
+ ];