@takeshape/json-schema 11.143.2 → 11.154.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takeshape/json-schema",
3
- "version": "11.143.2",
3
+ "version": "11.154.1",
4
4
  "description": "JSON Schema validator",
5
5
  "homepage": "https://www.takeshape.io",
6
6
  "repository": {
@@ -38,7 +38,7 @@
38
38
  "ajv-formats": "3.0.1",
39
39
  "lodash": "4.17.21",
40
40
  "minimatch": "3.1.2",
41
- "@takeshape/util": "11.143.2"
41
+ "@takeshape/util": "11.154.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/json-schema": "7.0.15",
@@ -1 +0,0 @@
1
- export * from './schema-converter.ts';
@@ -1 +0,0 @@
1
- export * from "./schema-converter.js";
@@ -1,64 +0,0 @@
1
- import type { JSONSchema7 } from 'json-schema';
2
- export type SchemaConversionStats = {
3
- propertiesCount: number;
4
- stringLength: number;
5
- enumValuesCount: number;
6
- };
7
- export type SchemaConversionResult = {
8
- schema: JSONSchema7;
9
- warnings: string[];
10
- stats: SchemaConversionStats;
11
- };
12
- export declare enum SchemaConversionTarget {
13
- OpenAI = "OPENAI",
14
- JSONSchema = "JSON_SCHEMA"
15
- }
16
- export type SchemaConversionOptions = {
17
- /**
18
- * A target flavor.
19
- */
20
- target?: SchemaConversionTarget;
21
- /**
22
- * Keys to include
23
- */
24
- propertyFilter?: (key: string) => boolean;
25
- /**
26
- * @default false
27
- */
28
- inlineDefinitions?: boolean;
29
- /**
30
- * @default 5
31
- */
32
- maxDepth?: number;
33
- /**
34
- * Allow unknown keys when processing for the JSONSchema target.
35
- *
36
- * @default false
37
- */
38
- allowUnknownKeys?: boolean;
39
- };
40
- export declare class SchemaConverter {
41
- #private;
42
- warnings: string[];
43
- stats: SchemaConversionStats;
44
- static convert(schema: JSONSchema7, options?: SchemaConversionOptions): SchemaConversionResult;
45
- protected constructor(originalSchema: JSONSchema7, options?: SchemaConversionOptions);
46
- private run;
47
- private processSchema;
48
- private processDefinitions;
49
- private countDefinitions;
50
- private getUsedDefinitions;
51
- private addDefinition;
52
- private addNullable;
53
- private processRefSchema;
54
- private initializeNewSchema;
55
- private processObjectSchema;
56
- private processArraySchema;
57
- private getUnsupportedArrayKeywords;
58
- private processOneOfSchema;
59
- private processAnyOfSchema;
60
- private processAllOfSchema;
61
- private mergeAllOfSchema;
62
- private processEnumSchema;
63
- private checkUnsupportedKeywords;
64
- }
@@ -1,558 +0,0 @@
1
- import { assert, ensureArray } from '@takeshape/util';
2
- import intersection from 'lodash/intersection.js';
3
- import uniq from 'lodash/uniq.js';
4
- import { getReferenceMap, isAllOfSchema, isAnyOfSchema, isArraySchema, isEnumSchema, isListSchema, isObjectSchema, isObjectSchemaWithProperties, isOneOfSchema, isRefSchema, isTupleSchema, pickJSONSchema7 } from "../utils/index.js";
5
- export var SchemaConversionTarget;
6
- (function (SchemaConversionTarget) {
7
- SchemaConversionTarget["OpenAI"] = "OPENAI";
8
- SchemaConversionTarget["JSONSchema"] = "JSON_SCHEMA";
9
- })(SchemaConversionTarget || (SchemaConversionTarget = {}));
10
- var SchemaProcessingMode;
11
- (function (SchemaProcessingMode) {
12
- SchemaProcessingMode["Schema"] = "SCHEMA";
13
- SchemaProcessingMode["Definition"] = "DEFINITION";
14
- SchemaProcessingMode["Count"] = "COUNT";
15
- })(SchemaProcessingMode || (SchemaProcessingMode = {}));
16
- export class SchemaConverter {
17
- warnings = [];
18
- stats = {
19
- propertiesCount: 0,
20
- stringLength: 0,
21
- enumValuesCount: 0
22
- };
23
- #schema;
24
- #config;
25
- #usedDefinitions = new Set();
26
- #definitions = {};
27
- #definitionsReferences = new Map();
28
- static convert(schema, options = {}) {
29
- return new SchemaConverter(schema, options).run();
30
- }
31
- constructor(originalSchema, options = {}) {
32
- const { propertyFilter, target = SchemaConversionTarget.JSONSchema, inlineDefinitions = false, maxDepth = 5, allowUnknownKeys = false } = options;
33
- this.#config = {
34
- target,
35
- maxDepth,
36
- allowUnknownKeys,
37
- propertyFilter,
38
- inlineDefinitions
39
- };
40
- const { $defs, definitions, ...schema } = originalSchema;
41
- this.#schema = schema;
42
- if ($defs || definitions) {
43
- const defs = { ...$defs, ...definitions };
44
- this.#definitionsReferences = getReferenceMap(defs);
45
- this.#definitions = this.processDefinitions(defs);
46
- }
47
- }
48
- run() {
49
- const { target, inlineDefinitions } = this.#config;
50
- // Process the schema
51
- const result = this.processSchema({
52
- processingMode: SchemaProcessingMode.Schema,
53
- isRequired: true,
54
- path: [],
55
- depth: 0
56
- }, this.#schema);
57
- if (!inlineDefinitions && this.#usedDefinitions.size) {
58
- const defs = this.getUsedDefinitions();
59
- if (Object.keys(defs).length) {
60
- result.$defs = defs;
61
- this.countDefinitions(defs);
62
- }
63
- }
64
- // Check the total property count
65
- if (target === SchemaConversionTarget.OpenAI && this.stats.propertiesCount > 100) {
66
- this.warnings.push(`Schema has ${this.stats.propertiesCount} total object properties, exceeding the 100 limit`);
67
- }
68
- // Check string length total
69
- if (target === SchemaConversionTarget.OpenAI && this.stats.stringLength > 15000) {
70
- this.warnings.push(`Total string length of property names, definition names, enum values exceeds the 15,000 limit (${this.stats.stringLength})`);
71
- }
72
- // Check enum values count
73
- if (target === SchemaConversionTarget.OpenAI && this.stats.enumValuesCount > 500) {
74
- this.warnings.push(`Schema has ${this.stats.enumValuesCount} enum values across all properties, exceeding the 500 limit`);
75
- }
76
- // Check if root is an object
77
- if (target === SchemaConversionTarget.OpenAI && !isObjectSchemaWithProperties(result)) {
78
- this.warnings.push('Root level must be an object type, wrapping in an object');
79
- // Attempt to fix by wrapping in an object if possible
80
- return {
81
- schema: {
82
- type: 'object',
83
- properties: {
84
- root: result
85
- },
86
- required: ['root'],
87
- additionalProperties: false
88
- },
89
- warnings: this.warnings,
90
- stats: this.stats
91
- };
92
- }
93
- return {
94
- schema: result,
95
- warnings: this.warnings,
96
- stats: this.stats
97
- };
98
- }
99
- processSchema(context, schema) {
100
- assert(typeof schema === 'object', 'Schema must be an object');
101
- const { depth, path, isRequired, processingMode } = context;
102
- const { target, maxDepth } = this.#config;
103
- // Clone the schema to avoid modifying the original
104
- const schemaCopy = { ...schema };
105
- const currentPath = path.join('.') || 'root';
106
- // Check for unsupported keywords
107
- this.checkUnsupportedKeywords(schemaCopy, currentPath);
108
- // Check depth limit
109
- if (depth > maxDepth) {
110
- this.warnings.push(`Nesting depth exceeds limit (max 5) at ${currentPath}`);
111
- // Simplify the schema at this level
112
- return this.addNullable({ type: 'string', description: 'Simplified due to excessive nesting' }, isRequired);
113
- }
114
- // Handle $ref
115
- if (isRefSchema(schemaCopy)) {
116
- return this.processRefSchema(context, schemaCopy);
117
- }
118
- // Process specific types
119
- if (isObjectSchema(schemaCopy)) {
120
- return this.addNullable(this.processObjectSchema(context, schemaCopy), isRequired);
121
- }
122
- if (isArraySchema(schemaCopy)) {
123
- return this.addNullable(this.processArraySchema(context, schemaCopy), isRequired);
124
- }
125
- if (isAnyOfSchema(schemaCopy)) {
126
- return this.addNullable(this.processAnyOfSchema(context, schemaCopy), isRequired);
127
- }
128
- if (isOneOfSchema(schemaCopy)) {
129
- if (target === SchemaConversionTarget.OpenAI) {
130
- this.warnings.push(`oneOf at ${currentPath} converted to anyOf (OpenAI only supports anyOf)`);
131
- const { oneOf, ...rest } = schemaCopy;
132
- return this.addNullable(this.processAnyOfSchema(context, { ...rest, anyOf: oneOf }), isRequired);
133
- }
134
- return this.addNullable(this.processOneOfSchema(context, schemaCopy), isRequired);
135
- }
136
- if (isAllOfSchema(schemaCopy)) {
137
- if (target === SchemaConversionTarget.OpenAI) {
138
- this.warnings.push(`allOf at ${currentPath} is not directly supported, attempting to merge schemas`);
139
- return this.addNullable(this.mergeAllOfSchema(context, schemaCopy), isRequired);
140
- }
141
- return this.addNullable(this.processAllOfSchema(context, schemaCopy), isRequired);
142
- }
143
- if (isEnumSchema(schemaCopy)) {
144
- return this.addNullable(this.processEnumSchema(context, schemaCopy), isRequired);
145
- }
146
- if (target === SchemaConversionTarget.OpenAI && schemaCopy.default) {
147
- const defaultText = `Default value: ${typeof schemaCopy.default === 'object' ? JSON.stringify(schemaCopy.default) : schemaCopy.default}`;
148
- schemaCopy.description = schema.description ? `${schema.description} ${defaultText}` : defaultText;
149
- // biome-ignore lint/performance/noDelete: don't want to leave cruft
150
- delete schemaCopy.default;
151
- }
152
- // Update string length total for const values
153
- if (schemaCopy.const &&
154
- typeof schemaCopy.const === 'string' &&
155
- (processingMode === SchemaProcessingMode.Schema || processingMode === SchemaProcessingMode.Count)) {
156
- this.stats.stringLength += schemaCopy.const.length;
157
- }
158
- const newSchema = this.initializeNewSchema(schemaCopy, {
159
- type: schemaCopy.type
160
- });
161
- return this.addNullable(newSchema, isRequired);
162
- }
163
- processDefinitions(defs) {
164
- return Object.entries(defs).reduce((acc, [defName, def]) => {
165
- acc[defName] = this.processSchema({
166
- processingMode: SchemaProcessingMode.Definition,
167
- isRequired: true,
168
- path: [],
169
- depth: 0
170
- }, def);
171
- return acc;
172
- }, {});
173
- }
174
- countDefinitions(defs) {
175
- for (const def of Object.values(defs)) {
176
- this.processSchema({
177
- processingMode: SchemaProcessingMode.Count,
178
- isRequired: true,
179
- path: [],
180
- depth: 0
181
- }, def);
182
- }
183
- }
184
- getUsedDefinitions() {
185
- const defs = {};
186
- for (const usedDef of this.#usedDefinitions) {
187
- this.addDefinition(defs, usedDef);
188
- // Add any definitions that are referenced by the used definition
189
- const defRefs = this.#definitionsReferences.get(usedDef);
190
- if (defRefs) {
191
- for (const ref of defRefs) {
192
- this.addDefinition(defs, ref);
193
- }
194
- }
195
- }
196
- return defs;
197
- }
198
- addDefinition(defs, key) {
199
- const definition = this.#definitions[key];
200
- if (definition) {
201
- this.stats.stringLength += key.length;
202
- defs[key] = definition;
203
- }
204
- }
205
- addNullable(schema, isRequired) {
206
- if (this.#config.target === SchemaConversionTarget.JSONSchema) {
207
- return schema;
208
- }
209
- if (isRequired) {
210
- return schema;
211
- }
212
- if (schema.type && !isObjectSchema(schema) && !isArraySchema(schema)) {
213
- return {
214
- ...schema,
215
- type: uniq([...ensureArray(schema.type), 'null'])
216
- };
217
- }
218
- return {
219
- anyOf: [...(schema.anyOf ? schema.anyOf : [schema]), { type: 'null' }]
220
- };
221
- }
222
- processRefSchema(context, schema) {
223
- const { isRequired, processingMode } = context;
224
- const newSchema = {
225
- $ref: schema.$ref
226
- };
227
- // Normalize definitions path
228
- if (newSchema.$ref.startsWith('#/definitions/')) {
229
- newSchema.$ref = newSchema.$ref.replace('#/definitions/', '#/$defs/');
230
- }
231
- const defName = newSchema.$ref.replace('#/$defs/', '');
232
- if (defName && this.#config.inlineDefinitions && this.#definitions[defName]) {
233
- return this.processSchema(context, this.#definitions[defName]);
234
- }
235
- if (processingMode === SchemaProcessingMode.Schema) {
236
- this.#usedDefinitions.add(defName);
237
- }
238
- return this.addNullable(newSchema, isRequired);
239
- }
240
- initializeNewSchema(schema, newSchema) {
241
- // OpenAI will only allow some very specific properties, so start fairly clean
242
- if (this.#config.target === SchemaConversionTarget.OpenAI) {
243
- let base = {
244
- title: schema.title,
245
- description: schema.description
246
- };
247
- if (newSchema.type === 'object') {
248
- base = {
249
- ...base,
250
- required: Object.keys(newSchema.properties ?? schema.properties ?? {}),
251
- additionalProperties: false
252
- };
253
- }
254
- else if (newSchema.type === 'array') {
255
- base = {
256
- ...base,
257
- items: []
258
- };
259
- }
260
- else if (newSchema.type === 'number' ||
261
- newSchema.type === 'integer' ||
262
- newSchema.type === 'string' ||
263
- newSchema.type === 'boolean') {
264
- base = {
265
- ...base,
266
- const: schema.const
267
- };
268
- }
269
- return {
270
- ...base,
271
- ...newSchema
272
- };
273
- }
274
- return {
275
- // We may be converting a schema with non-spec properties
276
- ...(this.#config.allowUnknownKeys ? schema : pickJSONSchema7(schema)),
277
- ...newSchema
278
- };
279
- }
280
- processObjectSchema(context, schema) {
281
- const { depth, path, processingMode } = context;
282
- const { target, propertyFilter } = this.#config;
283
- const newSchema = this.initializeNewSchema(schema, {
284
- type: 'object'
285
- });
286
- const uniqueRequired = new Set(schema.required ?? []);
287
- const newSchemaProperties = {};
288
- // Process properties
289
- if (schema.properties) {
290
- // Process each property
291
- for (const [key, property] of Object.entries(schema.properties)) {
292
- // Skip properties that are not in propertyKeys
293
- if (propertyFilter && !propertyFilter(key)) {
294
- continue;
295
- }
296
- newSchemaProperties[key] = this.processSchema({
297
- ...context,
298
- path: [...path, key],
299
- depth: depth + 1,
300
- isRequired: uniqueRequired.has(key)
301
- }, property);
302
- // Update string length total for property names
303
- if (processingMode === SchemaProcessingMode.Schema || processingMode === SchemaProcessingMode.Count) {
304
- this.stats.stringLength += key.length;
305
- }
306
- }
307
- }
308
- const newPropertyKeys = Object.keys(newSchemaProperties);
309
- // Update total property count
310
- if (processingMode === SchemaProcessingMode.Schema || processingMode === SchemaProcessingMode.Count) {
311
- this.stats.propertiesCount += newPropertyKeys.length;
312
- }
313
- let required = schema.required;
314
- if (target === SchemaConversionTarget.OpenAI) {
315
- // OpenAI requires all properties to be required
316
- required = newPropertyKeys;
317
- }
318
- else if (required) {
319
- required = intersection([...uniqueRequired], newPropertyKeys);
320
- }
321
- return {
322
- ...newSchema,
323
- properties: newSchemaProperties,
324
- // Make all properties required for openai target, for json-schema some may have been removed
325
- required
326
- };
327
- }
328
- processArraySchema(context, schema) {
329
- const { depth, path } = context;
330
- const newSchema = this.initializeNewSchema(schema, {
331
- type: 'array'
332
- });
333
- // Process items schema
334
- if (schema.items) {
335
- if (isTupleSchema(schema)) {
336
- newSchema.items = schema.items.map((item, index) => this.processSchema({
337
- ...context,
338
- path: [...path, 'items', index],
339
- depth: depth + 1
340
- }, item));
341
- }
342
- if (isListSchema(schema)) {
343
- newSchema.items = this.processSchema({
344
- ...context,
345
- path: [...path, 'items'],
346
- depth: depth + 1
347
- }, schema.items);
348
- }
349
- }
350
- else {
351
- this.warnings.push(`Array missing items definition at ${path.join('.') || 'root'}, defaulting to string items`);
352
- newSchema.items = { type: 'string' };
353
- }
354
- for (const keyword of this.getUnsupportedArrayKeywords()) {
355
- if (schema[keyword] !== undefined) {
356
- this.warnings.push(`Unsupported array keyword "${keyword}" at ${path.join('.') || 'root'} will be ignored`);
357
- }
358
- }
359
- return newSchema;
360
- }
361
- getUnsupportedArrayKeywords() {
362
- if (this.#config.target === SchemaConversionTarget.OpenAI) {
363
- return [
364
- // 'unevaluatedItems',
365
- 'contains',
366
- // 'minContains',
367
- // 'maxContains',
368
- 'minItems',
369
- 'maxItems',
370
- 'uniqueItems'
371
- ];
372
- }
373
- return [];
374
- }
375
- processOneOfSchema(context, schema) {
376
- const { depth, path } = context;
377
- const newSchema = this.initializeNewSchema(schema, {
378
- oneOf: []
379
- });
380
- // Process each oneOf schema
381
- newSchema.oneOf = schema.oneOf.map((subSchema, index) => {
382
- return this.processSchema({ ...context, path: [...path, 'oneOf', index], depth: depth + 1 }, subSchema);
383
- });
384
- return newSchema;
385
- }
386
- processAnyOfSchema(context, schema) {
387
- const { target } = this.#config;
388
- const { depth, path } = context;
389
- const newSchema = this.initializeNewSchema(schema, {
390
- anyOf: []
391
- });
392
- // Check if this is at the root level
393
- if (target === SchemaConversionTarget.OpenAI && path.length === 0) {
394
- this.warnings.push('anyOf at root level is not supported by OpenAI Structured Outputs');
395
- }
396
- // Process each anyOf schema
397
- newSchema.anyOf = schema.anyOf.map((subSchema, index) => {
398
- return this.processSchema({ ...context, path: [...path, 'anyOf', index], depth: depth + 1 }, subSchema);
399
- });
400
- return newSchema;
401
- }
402
- processAllOfSchema(context, schema) {
403
- const { depth, path } = context;
404
- const newSchema = this.initializeNewSchema(schema, {
405
- allOf: []
406
- });
407
- // Process each anyOf schema
408
- newSchema.allOf = schema.allOf.map((subSchema, index) => {
409
- return this.processSchema({ ...context, path: [...path, 'allOf', index], depth: depth + 1 }, subSchema);
410
- });
411
- return newSchema;
412
- }
413
- mergeAllOfSchema(context, schema) {
414
- const { depth, path } = context;
415
- const newSchema = this.initializeNewSchema(schema, {
416
- type: 'object'
417
- });
418
- const allOfSchemas = schema.allOf ?? [];
419
- // Try to merge properties from all schemas
420
- for (const [index, value] of allOfSchemas.entries()) {
421
- const subSchema = this.processSchema({ ...context, path: [...path, 'allOf', index] }, value);
422
- if (isObjectSchemaWithProperties(subSchema)) {
423
- // Merge properties
424
- newSchema.properties = {
425
- ...newSchema.properties,
426
- ...subSchema.properties
427
- };
428
- // Merge required fields
429
- if (Array.isArray(subSchema.required)) {
430
- newSchema.required = [...(newSchema.required ?? []), ...subSchema.required];
431
- }
432
- // Preserve description if we don't have one yet
433
- if (!newSchema.description && subSchema.description) {
434
- newSchema.description = subSchema.description;
435
- }
436
- // Preserve title if we don't have one yet
437
- if (!newSchema.title && subSchema.title) {
438
- newSchema.title = subSchema.title;
439
- }
440
- }
441
- else {
442
- this.warnings.push(`Non-object schema in allOf at ${path.join('.') || 'root'} cannot be merged properly`);
443
- }
444
- }
445
- // Remove duplicate required fields
446
- newSchema.required = [...new Set(newSchema.required)];
447
- return this.processObjectSchema({ ...context, depth: depth + 1 }, newSchema);
448
- }
449
- processEnumSchema(context, schema) {
450
- const { target } = this.#config;
451
- const { path, processingMode } = context;
452
- const newSchema = this.initializeNewSchema(schema, {
453
- enum: schema.enum,
454
- type: schema.type
455
- });
456
- if (Array.isArray(newSchema.enum)) {
457
- // Update enum values count
458
- if (processingMode === SchemaProcessingMode.Schema || processingMode === SchemaProcessingMode.Count) {
459
- this.stats.enumValuesCount += newSchema.enum.length;
460
- }
461
- // Check enum size
462
- if (target === SchemaConversionTarget.OpenAI && newSchema.enum.length > 500) {
463
- this.warnings.push(`Enum at ${path.join('.') || 'root'} has ${newSchema.enum.length} values, exceeding the 500 limit`);
464
- newSchema.enum = newSchema.enum.slice(0, 500);
465
- }
466
- // Check string length for large enums
467
- if (newSchema.type === 'string') {
468
- let totalLength = 0;
469
- for (const val of newSchema.enum) {
470
- if (typeof val === 'string') {
471
- totalLength += val.length;
472
- }
473
- }
474
- if (target === SchemaConversionTarget.OpenAI && totalLength > 7500) {
475
- this.warnings.push(`Enum strings at ${path.join('.') || 'root'} exceed 7500 characters (${totalLength}) with ${newSchema.enum.length} values`);
476
- // Truncate enum values to fit within limits
477
- let currentLength = 0;
478
- const truncatedEnum = [];
479
- for (const val of newSchema.enum) {
480
- if (typeof val === 'string') {
481
- if (currentLength + val.length <= 7500) {
482
- truncatedEnum.push(val);
483
- currentLength += val.length;
484
- }
485
- else {
486
- break;
487
- }
488
- }
489
- else {
490
- truncatedEnum.push(val);
491
- }
492
- }
493
- newSchema.enum = truncatedEnum;
494
- }
495
- if (processingMode === SchemaProcessingMode.Schema || processingMode === SchemaProcessingMode.Count) {
496
- this.stats.stringLength += totalLength;
497
- }
498
- }
499
- }
500
- return newSchema;
501
- }
502
- checkUnsupportedKeywords(schema, path) {
503
- if (this.#config.target === SchemaConversionTarget.OpenAI) {
504
- // String-specific unsupported keywords
505
- if (schema.type === 'string' ||
506
- (!schema.type &&
507
- (schema.minLength !== undefined ||
508
- schema.maxLength !== undefined ||
509
- schema.pattern !== undefined ||
510
- schema.format !== undefined))) {
511
- const unsupportedStringKeywords = ['minLength', 'maxLength', 'pattern', 'format'];
512
- for (const keyword of unsupportedStringKeywords) {
513
- if (schema[keyword] !== undefined) {
514
- this.warnings.push(`Unsupported string keyword "${keyword}" at ${path || 'root'} will be ignored`);
515
- delete schema[keyword];
516
- }
517
- }
518
- }
519
- // Number-specific unsupported keywords
520
- if (schema.type === 'number' ||
521
- schema.type === 'integer' ||
522
- (!schema.type &&
523
- (schema.minimum !== undefined || schema.maximum !== undefined || schema.multipleOf !== undefined))) {
524
- const unsupportedNumberKeywords = ['minimum', 'maximum', 'multipleOf'];
525
- for (const keyword of unsupportedNumberKeywords) {
526
- if (schema[keyword] !== undefined) {
527
- this.warnings.push(`Unsupported number keyword "${keyword}" at ${path || 'root'} will be ignored`);
528
- delete schema[keyword];
529
- }
530
- }
531
- }
532
- // Object-specific unsupported keywords
533
- if (schema.type === 'object' || (!schema.type && schema.properties !== undefined)) {
534
- const unsupportedObjectKeywords = [
535
- 'patternProperties',
536
- // 'unevaluatedProperties',
537
- 'propertyNames',
538
- 'minProperties',
539
- 'maxProperties'
540
- ];
541
- for (const keyword of unsupportedObjectKeywords) {
542
- if (schema[keyword] !== undefined) {
543
- this.warnings.push(`Unsupported object keyword "${keyword}" at ${path || 'root'} will be ignored`);
544
- delete schema[keyword];
545
- }
546
- }
547
- }
548
- // Check Draft 7 keywords that aren't supported in OpenAI schema
549
- const draft7Keywords = ['if', 'then', 'else', 'not', 'dependencies'];
550
- for (const keyword of draft7Keywords) {
551
- if (schema[keyword] !== undefined) {
552
- this.warnings.push(`JSON Schema Draft 7 keyword "${keyword}" at ${path || 'root'} is not supported and will be ignored`);
553
- delete schema[keyword];
554
- }
555
- }
556
- }
557
- }
558
- }
package/dist/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from './schema-validator.ts';
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- export * from "./schema-validator.js";
@@ -1,36 +0,0 @@
1
- import type { ErrorObject, Options, SchemaObject } from 'ajv';
2
- import { Ajv } from 'ajv';
3
- import type { JSONSchema7 } from 'json-schema';
4
- export type Data = any;
5
- export type ValidateParams = {
6
- ignoreMissing: boolean;
7
- ignoreNulls: boolean;
8
- errorsText: boolean;
9
- };
10
- export type ValidateResult = {
11
- valid: boolean;
12
- errorsText: string;
13
- errors: ErrorObject[];
14
- };
15
- export type Validator = (data: Data, options?: Partial<ValidateParams>) => ValidateResult;
16
- export declare function parseDataPath(instancePath: string): string[];
17
- export declare function isInvalidPropertyRequired(topLevelSchema: SchemaObject, error: ErrorObject): boolean;
18
- export declare function refToPath(ref: string): string[];
19
- /**
20
- * Given a schema object traverse it using a "instancePath" and return the schema at that path
21
- */
22
- export declare function followSchemaPath(topLevelSchema: SchemaObject, instancePath: string[]): SchemaObject | undefined;
23
- export type MinimalAjv = Pick<Ajv, 'validate' | 'errors' | 'getSchema' | 'errorsText'>;
24
- export declare function validate(ajv: MinimalAjv, id: string, data: Data, options?: Partial<ValidateParams>): ValidateResult;
25
- export { Ajv, type ErrorObject };
26
- export declare function createAjv(options?: Options): Ajv;
27
- /**
28
- * Apply various fixes to the schema to work around AJV issues and bugs.
29
- * See inline comments for more.
30
- */
31
- export declare function fixSchema(schema: SchemaObject): SchemaObject;
32
- export declare function createSchemaValidator(schema: SchemaObject | SchemaObject[], metaSchemas?: SchemaObject[], options?: Options): Validator;
33
- /**
34
- * Returns a compiled validator from a schema which can act as a type guard.
35
- */
36
- export declare function createTypedValidator<T>(schema: JSONSchema7, options?: Options): import("ajv").ValidateFunction<T>;