@trayio/commons 5.11.0 → 5.13.0-unstable

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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Utility for converting runtime JavaScript objects to JSON Schema
3
+ * Used for dynamic output schema generation in CDK connectors
4
+ */
5
+ export declare class JsonSchemaIntrospector {
6
+ /**
7
+ * Introspects a JavaScript object and generates a JSON Schema representation
8
+ *
9
+ * @param obj - The object to introspect
10
+ * @param options - Configuration options for introspection
11
+ * @returns A JSON Schema object describing the structure
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const data = { id: 1, name: "John", active: true };
16
+ * const schema = JsonSchemaIntrospector.introspectToJsonSchema(data);
17
+ * // Returns:
18
+ * // {
19
+ * // type: 'object',
20
+ * // properties: {
21
+ * // id: { type: 'number' },
22
+ * // name: { type: 'string' },
23
+ * // active: { type: 'boolean' }
24
+ * // },
25
+ * // required: ['id', 'name', 'active']
26
+ * // }
27
+ * ```
28
+ */
29
+ static introspectToJsonSchema(obj: any, options?: IntrospectionOptions): any;
30
+ private static introspectRecursive;
31
+ }
32
+ /**
33
+ * Configuration options for JSON Schema introspection
34
+ */
35
+ export type IntrospectionOptions = {
36
+ /**
37
+ * Maximum depth for recursive introspection
38
+ * @default 10
39
+ */
40
+ maxDepth?: number;
41
+ /**
42
+ * Whether to include example values in the schema
43
+ * @default false
44
+ */
45
+ includeExamples?: boolean;
46
+ /**
47
+ * Whether to mark all present fields as required
48
+ * If false, only marks non-null/non-undefined fields as required
49
+ * @default true
50
+ */
51
+ strictRequired?: boolean;
52
+ };
53
+ //# sourceMappingURL=JsonSchemaIntrospector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonSchemaIntrospector.d.ts","sourceRoot":"","sources":["../../src/schema/JsonSchemaIntrospector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,sBAAsB;IAClC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,GAAG;IAU5E,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA8FlC;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAClC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JsonSchemaIntrospector = void 0;
4
+ /**
5
+ * Utility for converting runtime JavaScript objects to JSON Schema
6
+ * Used for dynamic output schema generation in CDK connectors
7
+ */
8
+ class JsonSchemaIntrospector {
9
+ /**
10
+ * Introspects a JavaScript object and generates a JSON Schema representation
11
+ *
12
+ * @param obj - The object to introspect
13
+ * @param options - Configuration options for introspection
14
+ * @returns A JSON Schema object describing the structure
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const data = { id: 1, name: "John", active: true };
19
+ * const schema = JsonSchemaIntrospector.introspectToJsonSchema(data);
20
+ * // Returns:
21
+ * // {
22
+ * // type: 'object',
23
+ * // properties: {
24
+ * // id: { type: 'number' },
25
+ * // name: { type: 'string' },
26
+ * // active: { type: 'boolean' }
27
+ * // },
28
+ * // required: ['id', 'name', 'active']
29
+ * // }
30
+ * ```
31
+ */
32
+ static introspectToJsonSchema(obj, options) {
33
+ const opts = {
34
+ maxDepth: options?.maxDepth ?? 10,
35
+ includeExamples: options?.includeExamples ?? false,
36
+ strictRequired: options?.strictRequired ?? true,
37
+ };
38
+ return this.introspectRecursive(obj, 0, opts);
39
+ }
40
+ static introspectRecursive(obj, depth, options) {
41
+ // Prevent infinite recursion
42
+ if (depth >= options.maxDepth) {
43
+ return { type: 'object', additionalProperties: true };
44
+ }
45
+ // Handle null
46
+ if (obj === null) {
47
+ return { type: 'null' };
48
+ }
49
+ // Handle arrays
50
+ if (Array.isArray(obj)) {
51
+ if (obj.length === 0) {
52
+ return { type: 'array', items: {} };
53
+ }
54
+ // Generate schema from first item
55
+ const itemSchema = this.introspectRecursive(obj[0], depth + 1, options);
56
+ const schema = {
57
+ type: 'array',
58
+ items: itemSchema,
59
+ };
60
+ if (options.includeExamples) {
61
+ schema.examples = [obj];
62
+ }
63
+ return schema;
64
+ }
65
+ const type = typeof obj;
66
+ // Handle primitives
67
+ if (type === 'string') {
68
+ const schema = { type: 'string' };
69
+ if (options.includeExamples) {
70
+ schema.examples = [obj];
71
+ }
72
+ return schema;
73
+ }
74
+ if (type === 'number') {
75
+ const schema = { type: 'number' };
76
+ if (options.includeExamples) {
77
+ schema.examples = [obj];
78
+ }
79
+ return schema;
80
+ }
81
+ if (type === 'boolean') {
82
+ const schema = { type: 'boolean' };
83
+ if (options.includeExamples) {
84
+ schema.examples = [obj];
85
+ }
86
+ return schema;
87
+ }
88
+ // Handle objects
89
+ if (type === 'object') {
90
+ const properties = {};
91
+ const required = [];
92
+ for (const [key, value] of Object.entries(obj)) {
93
+ properties[key] = this.introspectRecursive(value, depth + 1, options);
94
+ // Add to required array based on options
95
+ if (options.strictRequired) {
96
+ required.push(key);
97
+ }
98
+ else if (value !== null && value !== undefined) {
99
+ required.push(key);
100
+ }
101
+ }
102
+ const schema = {
103
+ type: 'object',
104
+ properties,
105
+ };
106
+ if (required.length > 0) {
107
+ schema.required = required;
108
+ }
109
+ if (options.includeExamples) {
110
+ schema.examples = [obj];
111
+ }
112
+ return schema;
113
+ }
114
+ // Fallback for unknown types
115
+ return { type: 'string' };
116
+ }
117
+ }
118
+ exports.JsonSchemaIntrospector = JsonSchemaIntrospector;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=JsonSchemaIntrospector.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonSchemaIntrospector.unit.test.d.ts","sourceRoot":"","sources":["../../src/schema/JsonSchemaIntrospector.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const JsonSchemaIntrospector_1 = require("./JsonSchemaIntrospector");
4
+ describe('JsonSchemaIntrospector', () => {
5
+ describe('introspectToJsonSchema', () => {
6
+ it('should handle primitive types', () => {
7
+ expect(JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema('test')).toEqual({
8
+ type: 'string',
9
+ });
10
+ expect(JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(42)).toEqual({
11
+ type: 'number',
12
+ });
13
+ expect(JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(true)).toEqual({
14
+ type: 'boolean',
15
+ });
16
+ expect(JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(null)).toEqual({
17
+ type: 'null',
18
+ });
19
+ });
20
+ it('should handle simple objects', () => {
21
+ const obj = {
22
+ id: 1,
23
+ name: 'John',
24
+ active: true,
25
+ };
26
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj);
27
+ expect(schema).toEqual({
28
+ type: 'object',
29
+ properties: {
30
+ id: { type: 'number' },
31
+ name: { type: 'string' },
32
+ active: { type: 'boolean' },
33
+ },
34
+ required: ['id', 'name', 'active'],
35
+ });
36
+ });
37
+ it('should handle nested objects', () => {
38
+ const obj = {
39
+ user: {
40
+ id: 1,
41
+ profile: {
42
+ name: 'John',
43
+ age: 30,
44
+ },
45
+ },
46
+ };
47
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj);
48
+ expect(schema.type).toBe('object');
49
+ expect(schema.properties.user.type).toBe('object');
50
+ expect(schema.properties.user.properties.profile.type).toBe('object');
51
+ expect(schema.properties.user.properties.profile.properties.name).toEqual({
52
+ type: 'string',
53
+ });
54
+ });
55
+ it('should handle arrays', () => {
56
+ const obj = {
57
+ items: [1, 2, 3],
58
+ };
59
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj);
60
+ expect(schema.properties.items).toEqual({
61
+ type: 'array',
62
+ items: { type: 'number' },
63
+ });
64
+ });
65
+ it('should handle arrays of objects', () => {
66
+ const obj = {
67
+ users: [
68
+ { id: 1, name: 'John' },
69
+ { id: 2, name: 'Jane' },
70
+ ],
71
+ };
72
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj);
73
+ expect(schema.properties.users).toEqual({
74
+ type: 'array',
75
+ items: {
76
+ type: 'object',
77
+ properties: {
78
+ id: { type: 'number' },
79
+ name: { type: 'string' },
80
+ },
81
+ required: ['id', 'name'],
82
+ },
83
+ });
84
+ });
85
+ it('should handle empty arrays', () => {
86
+ const obj = { items: [] };
87
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj);
88
+ expect(schema.properties.items).toEqual({
89
+ type: 'array',
90
+ items: {},
91
+ });
92
+ });
93
+ it('should respect maxDepth option', () => {
94
+ const deepObj = {
95
+ level1: {
96
+ level2: {
97
+ level3: {
98
+ level4: {
99
+ level5: {
100
+ tooDeep: 'value',
101
+ },
102
+ },
103
+ },
104
+ },
105
+ },
106
+ };
107
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(deepObj, {
108
+ maxDepth: 2,
109
+ });
110
+ // Should cut off at depth 2 (level1 -> level2 -> stop)
111
+ expect(schema.properties.level1.properties.level2).toEqual({
112
+ type: 'object',
113
+ additionalProperties: true,
114
+ });
115
+ });
116
+ it('should include examples when requested', () => {
117
+ const obj = { name: 'John' };
118
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj, {
119
+ includeExamples: true,
120
+ });
121
+ expect(schema.examples).toEqual([{ name: 'John' }]);
122
+ expect(schema.properties.name.examples).toEqual(['John']);
123
+ });
124
+ it('should handle strictRequired option', () => {
125
+ const obj = {
126
+ present: 'value',
127
+ // In real use, there might be optional fields
128
+ };
129
+ const strictSchema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj, {
130
+ strictRequired: true,
131
+ });
132
+ expect(strictSchema.required).toEqual(['present']);
133
+ const relaxedSchema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj, {
134
+ strictRequired: false,
135
+ });
136
+ expect(relaxedSchema.required).toEqual(['present']);
137
+ });
138
+ it('should handle complex real-world example', () => {
139
+ const obj = {
140
+ id: 1,
141
+ title: 'Post Title',
142
+ body: 'Post content',
143
+ userId: 10,
144
+ metadata: {
145
+ created: '2024-01-01',
146
+ tags: ['tech', 'tutorial'],
147
+ stats: {
148
+ views: 100,
149
+ likes: 25,
150
+ },
151
+ },
152
+ comments: [
153
+ {
154
+ id: 1,
155
+ text: 'Great post!',
156
+ author: 'Alice',
157
+ },
158
+ ],
159
+ };
160
+ const schema = JsonSchemaIntrospector_1.JsonSchemaIntrospector.introspectToJsonSchema(obj);
161
+ expect(schema.type).toBe('object');
162
+ expect(schema.properties.id.type).toBe('number');
163
+ expect(schema.properties.metadata.type).toBe('object');
164
+ expect(schema.properties.metadata.properties.tags.type).toBe('array');
165
+ expect(schema.properties.comments.type).toBe('array');
166
+ expect(schema.properties.comments.items.type).toBe('object');
167
+ });
168
+ });
169
+ });
@@ -0,0 +1,2 @@
1
+ export { JsonSchemaIntrospector, IntrospectionOptions, } from './JsonSchemaIntrospector';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,sBAAsB,EACtB,oBAAoB,GACpB,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JsonSchemaIntrospector = void 0;
4
+ var JsonSchemaIntrospector_1 = require("./JsonSchemaIntrospector");
5
+ Object.defineProperty(exports, "JsonSchemaIntrospector", { enumerable: true, get: function () { return JsonSchemaIntrospector_1.JsonSchemaIntrospector; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trayio/commons",
3
- "version": "5.11.0",
3
+ "version": "5.13.0-unstable",
4
4
  "description": "Extensions to the standard/core libraries and basic features",
5
5
  "exports": {
6
6
  "./*": "./dist/*.js"
@@ -45,5 +45,6 @@
45
45
  },
46
46
  "files": [
47
47
  "/dist"
48
- ]
48
+ ],
49
+ "stableVersion": "0.0.0"
49
50
  }