@typia/utils 13.0.0-dev.20260426 → 13.0.0-dev.20260427-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/lib/converters/LlmSchemaConverter.js +28 -125
- package/lib/converters/LlmSchemaConverter.js.map +1 -1
- package/lib/converters/LlmSchemaConverter2.mjs +28 -125
- package/lib/converters/LlmSchemaConverter2.mjs.map +1 -1
- package/lib/converters/internal/OpenApiV3_1Upgrader.js +4 -7
- package/lib/converters/internal/OpenApiV3_1Upgrader.js.map +1 -1
- package/lib/converters/internal/OpenApiV3_1Upgrader2.mjs +4 -7
- package/lib/converters/internal/OpenApiV3_1Upgrader2.mjs.map +1 -1
- package/lib/utils/internal/coerceLlmArguments.js +4 -18
- package/lib/utils/internal/coerceLlmArguments.js.map +1 -1
- package/lib/utils/internal/coerceLlmArguments2.mjs +4 -18
- package/lib/utils/internal/coerceLlmArguments2.mjs.map +1 -1
- package/package.json +4 -4
- package/src/converters/LlmSchemaConverter.ts +33 -152
- package/src/converters/internal/OpenApiV3_1Upgrader.ts +4 -7
- package/src/utils/internal/coerceLlmArguments.ts +3 -21
|
@@ -200,29 +200,29 @@ export namespace LlmSchemaConverter {
|
|
|
200
200
|
},
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
203
|
+
const visitConstant = (input: OpenApi.IJsonSchema): void => {
|
|
204
|
+
const insert = (value: any): void => {
|
|
205
|
+
const matched:
|
|
206
|
+
| ILlmSchema.IString
|
|
207
|
+
| ILlmSchema.INumber
|
|
208
|
+
| ILlmSchema.IBoolean
|
|
209
|
+
| undefined = union.find(
|
|
210
|
+
(u) =>
|
|
211
|
+
(u as (IJsonSchemaAttribute & { type: string }) | undefined)
|
|
212
|
+
?.type === typeof value,
|
|
213
|
+
) as ILlmSchema.IString | undefined;
|
|
214
|
+
if (matched !== undefined) {
|
|
215
|
+
matched.enum ??= [];
|
|
216
|
+
matched.enum.push(value);
|
|
217
|
+
} else
|
|
218
|
+
union.push({
|
|
219
|
+
type: typeof value as "number",
|
|
220
|
+
enum: [value],
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
if (OpenApiTypeChecker.isConstant(input)) insert(input.const);
|
|
224
|
+
else if (OpenApiTypeChecker.isOneOf(input))
|
|
225
|
+
input.oneOf.forEach(visitConstant);
|
|
226
226
|
};
|
|
227
227
|
const visit = (input: OpenApi.IJsonSchema, accessor: string): void => {
|
|
228
228
|
if (OpenApiTypeChecker.isOneOf(input)) {
|
|
@@ -347,9 +347,6 @@ export namespace LlmSchemaConverter {
|
|
|
347
347
|
items: items.value,
|
|
348
348
|
},
|
|
349
349
|
);
|
|
350
|
-
} else if (OpenApiTypeChecker.isConstant(input)) {
|
|
351
|
-
const constant: ILlmSchema | null = convertConstant(input);
|
|
352
|
-
if (constant !== null) union.push(constant);
|
|
353
350
|
} else if (OpenApiTypeChecker.isString(input))
|
|
354
351
|
union.push(
|
|
355
352
|
props.config.strict === true
|
|
@@ -371,8 +368,8 @@ export namespace LlmSchemaConverter {
|
|
|
371
368
|
union.push({ ...input });
|
|
372
369
|
};
|
|
373
370
|
|
|
371
|
+
visitConstant(props.schema);
|
|
374
372
|
visit(props.schema, props.accessor ?? "$input.schema");
|
|
375
|
-
const normalized: ILlmSchema[] = normalizeLlmUnion(union);
|
|
376
373
|
|
|
377
374
|
if (reasons.length > 0)
|
|
378
375
|
return {
|
|
@@ -383,7 +380,7 @@ export namespace LlmSchemaConverter {
|
|
|
383
380
|
reasons,
|
|
384
381
|
},
|
|
385
382
|
};
|
|
386
|
-
else if (
|
|
383
|
+
else if (union.length === 0)
|
|
387
384
|
return {
|
|
388
385
|
// unknown type
|
|
389
386
|
success: true,
|
|
@@ -392,25 +389,25 @@ export namespace LlmSchemaConverter {
|
|
|
392
389
|
type: undefined,
|
|
393
390
|
},
|
|
394
391
|
};
|
|
395
|
-
else if (
|
|
392
|
+
else if (union.length === 1)
|
|
396
393
|
return {
|
|
397
394
|
// single type
|
|
398
395
|
success: true,
|
|
399
396
|
value: {
|
|
400
397
|
...attribute,
|
|
401
|
-
...
|
|
398
|
+
...union[0],
|
|
402
399
|
description:
|
|
403
400
|
props.config.strict === true &&
|
|
404
|
-
LlmTypeChecker.isReference(
|
|
401
|
+
LlmTypeChecker.isReference(union[0]!)
|
|
405
402
|
? undefined
|
|
406
|
-
: (
|
|
403
|
+
: (union[0]!.description ?? attribute.description),
|
|
407
404
|
},
|
|
408
405
|
};
|
|
409
406
|
return {
|
|
410
407
|
success: true,
|
|
411
408
|
value: {
|
|
412
409
|
...attribute,
|
|
413
|
-
anyOf:
|
|
410
|
+
anyOf: union.map((u) => ({
|
|
414
411
|
...u,
|
|
415
412
|
description:
|
|
416
413
|
props.config.strict === true && LlmTypeChecker.isReference(u)
|
|
@@ -420,8 +417,8 @@ export namespace LlmSchemaConverter {
|
|
|
420
417
|
"x-discriminator":
|
|
421
418
|
OpenApiTypeChecker.isOneOf(props.schema) &&
|
|
422
419
|
props.schema.discriminator !== undefined &&
|
|
423
|
-
props.schema.oneOf.length ===
|
|
424
|
-
|
|
420
|
+
props.schema.oneOf.length === union.length &&
|
|
421
|
+
union.every(
|
|
425
422
|
(e) => LlmTypeChecker.isReference(e) || LlmTypeChecker.isNull(e),
|
|
426
423
|
)
|
|
427
424
|
? {
|
|
@@ -436,11 +433,7 @@ export namespace LlmSchemaConverter {
|
|
|
436
433
|
],
|
|
437
434
|
),
|
|
438
435
|
)
|
|
439
|
-
:
|
|
440
|
-
propertyName: props.schema.discriminator.propertyName,
|
|
441
|
-
refs: normalized.filter(LlmTypeChecker.isReference),
|
|
442
|
-
$defs: props.$defs,
|
|
443
|
-
}),
|
|
436
|
+
: undefined,
|
|
444
437
|
}
|
|
445
438
|
: undefined,
|
|
446
439
|
},
|
|
@@ -599,118 +592,6 @@ export namespace LlmSchemaConverter {
|
|
|
599
592
|
};
|
|
600
593
|
}
|
|
601
594
|
|
|
602
|
-
const discriminatorMapping = (props: {
|
|
603
|
-
propertyName: string;
|
|
604
|
-
refs: ILlmSchema.IReference[];
|
|
605
|
-
$defs: Record<string, ILlmSchema>;
|
|
606
|
-
}): Record<string, string> | undefined => {
|
|
607
|
-
const entries: Array<[string, string]> = props.refs.flatMap((ref) => {
|
|
608
|
-
const key: string =
|
|
609
|
-
ref.$ref.split("#/$defs/")[1] ?? ref.$ref.split("/").at(-1)!;
|
|
610
|
-
const schema: ILlmSchema | undefined = props.$defs[key];
|
|
611
|
-
if (!schema || !LlmTypeChecker.isObject(schema)) return [];
|
|
612
|
-
const literals: string[] = llmDiscriminatorLiterals(
|
|
613
|
-
schema.properties[props.propertyName],
|
|
614
|
-
props.$defs,
|
|
615
|
-
);
|
|
616
|
-
return literals.map((literal) => [literal, ref.$ref] as [string, string]);
|
|
617
|
-
});
|
|
618
|
-
return entries.length !== 0 ? Object.fromEntries(entries) : undefined;
|
|
619
|
-
};
|
|
620
|
-
|
|
621
|
-
const llmDiscriminatorLiterals = (
|
|
622
|
-
schema: ILlmSchema | undefined,
|
|
623
|
-
$defs: Record<string, ILlmSchema>,
|
|
624
|
-
): string[] => {
|
|
625
|
-
if (schema === undefined) return [];
|
|
626
|
-
if (LlmTypeChecker.isReference(schema)) {
|
|
627
|
-
const key: string =
|
|
628
|
-
schema.$ref.split("#/$defs/")[1] ?? schema.$ref.split("/").at(-1)!;
|
|
629
|
-
return llmDiscriminatorLiterals($defs[key], $defs);
|
|
630
|
-
}
|
|
631
|
-
if (LlmTypeChecker.isString(schema)) return schema.enum ?? [];
|
|
632
|
-
if (LlmTypeChecker.isAnyOf(schema))
|
|
633
|
-
return schema.anyOf.flatMap((child) => llmDiscriminatorLiterals(child, $defs));
|
|
634
|
-
return [];
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
const normalizeLlmUnion = (union: ILlmSchema[]): ILlmSchema[] => {
|
|
638
|
-
if (union.length <= 1) return union;
|
|
639
|
-
if (union.every(isEnumOnlyString)) {
|
|
640
|
-
return [
|
|
641
|
-
{
|
|
642
|
-
type: "string",
|
|
643
|
-
enum: uniqueEnumValues(union.flatMap((schema) => schema.enum ?? [])),
|
|
644
|
-
},
|
|
645
|
-
];
|
|
646
|
-
}
|
|
647
|
-
if (union.every(isEnumOnlyBoolean)) {
|
|
648
|
-
return [
|
|
649
|
-
{
|
|
650
|
-
type: "boolean",
|
|
651
|
-
enum: uniqueEnumValues(union.flatMap((schema) => schema.enum ?? [])),
|
|
652
|
-
},
|
|
653
|
-
];
|
|
654
|
-
}
|
|
655
|
-
if (union.every(isEnumOnlyInteger)) {
|
|
656
|
-
return [
|
|
657
|
-
{
|
|
658
|
-
type: "integer",
|
|
659
|
-
enum: uniqueEnumValues(union.flatMap((schema) => schema.enum ?? [])),
|
|
660
|
-
},
|
|
661
|
-
];
|
|
662
|
-
}
|
|
663
|
-
if (union.every(isEnumOnlyNumber)) {
|
|
664
|
-
return [
|
|
665
|
-
{
|
|
666
|
-
type: "number",
|
|
667
|
-
enum: uniqueEnumValues(union.flatMap((schema) => schema.enum ?? [])),
|
|
668
|
-
},
|
|
669
|
-
];
|
|
670
|
-
}
|
|
671
|
-
return union;
|
|
672
|
-
};
|
|
673
|
-
|
|
674
|
-
const isEnumOnlyString = (
|
|
675
|
-
schema: ILlmSchema,
|
|
676
|
-
): schema is ILlmSchema.IString & { enum: string[] } =>
|
|
677
|
-
LlmTypeChecker.isString(schema) &&
|
|
678
|
-
Array.isArray(schema.enum) &&
|
|
679
|
-
schema.enum.length !== 0 &&
|
|
680
|
-
primitiveSchemaHasOnlyEnum(schema);
|
|
681
|
-
|
|
682
|
-
const isEnumOnlyBoolean = (
|
|
683
|
-
schema: ILlmSchema,
|
|
684
|
-
): schema is ILlmSchema.IBoolean & { enum: boolean[] } =>
|
|
685
|
-
LlmTypeChecker.isBoolean(schema) &&
|
|
686
|
-
Array.isArray(schema.enum) &&
|
|
687
|
-
schema.enum.length !== 0 &&
|
|
688
|
-
primitiveSchemaHasOnlyEnum(schema);
|
|
689
|
-
|
|
690
|
-
const isEnumOnlyInteger = (
|
|
691
|
-
schema: ILlmSchema,
|
|
692
|
-
): schema is ILlmSchema.IInteger & { enum: number[] } =>
|
|
693
|
-
LlmTypeChecker.isInteger(schema) &&
|
|
694
|
-
Array.isArray(schema.enum) &&
|
|
695
|
-
schema.enum.length !== 0 &&
|
|
696
|
-
primitiveSchemaHasOnlyEnum(schema);
|
|
697
|
-
|
|
698
|
-
const isEnumOnlyNumber = (
|
|
699
|
-
schema: ILlmSchema,
|
|
700
|
-
): schema is ILlmSchema.INumber & { enum: number[] } =>
|
|
701
|
-
LlmTypeChecker.isNumber(schema) &&
|
|
702
|
-
Array.isArray(schema.enum) &&
|
|
703
|
-
schema.enum.length !== 0 &&
|
|
704
|
-
primitiveSchemaHasOnlyEnum(schema);
|
|
705
|
-
|
|
706
|
-
const primitiveSchemaHasOnlyEnum = (schema: ILlmSchema): boolean =>
|
|
707
|
-
Object.entries(schema).every(([key, value]) => {
|
|
708
|
-
if (value === undefined) return true;
|
|
709
|
-
return key === "type" || key === "enum";
|
|
710
|
-
});
|
|
711
|
-
|
|
712
|
-
const uniqueEnumValues = <T>(values: T[]): T[] => Array.from(new Set(values));
|
|
713
|
-
|
|
714
595
|
const validateStrict = (
|
|
715
596
|
schema: OpenApi.IJsonSchema,
|
|
716
597
|
accessor: string,
|
|
@@ -532,13 +532,10 @@ export namespace OpenApiV3_1Upgrader {
|
|
|
532
532
|
items: undefined!,
|
|
533
533
|
prefixItems: schema.prefixItems.map(convertSchema(components)),
|
|
534
534
|
additionalItems:
|
|
535
|
-
schema.
|
|
536
|
-
|
|
537
|
-
? convertSchema(components)(schema.
|
|
538
|
-
:
|
|
539
|
-
schema.additionalItems !== null
|
|
540
|
-
? convertSchema(components)(schema.additionalItems)
|
|
541
|
-
: schema.additionalItems,
|
|
535
|
+
typeof schema.additionalItems === "object" &&
|
|
536
|
+
schema.additionalItems !== null
|
|
537
|
+
? convertSchema(components)(schema.additionalItems)
|
|
538
|
+
: schema.additionalItems,
|
|
542
539
|
},
|
|
543
540
|
});
|
|
544
541
|
else if (schema.items === undefined)
|
|
@@ -301,10 +301,10 @@ function findMatchingObjectInAnyOf(
|
|
|
301
301
|
if (!LlmTypeChecker.isObject(resolved)) continue;
|
|
302
302
|
const propSchema: ILlmSchema | undefined = resolved.properties?.[key];
|
|
303
303
|
if (propSchema === undefined) continue;
|
|
304
|
-
const
|
|
304
|
+
const resolvedProp: ILlmSchema = resolveSchema(propSchema, $defs);
|
|
305
305
|
if (
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
LlmTypeChecker.isString(resolvedProp) &&
|
|
307
|
+
resolvedProp.enum?.includes(discriminatorValue as string)
|
|
308
308
|
) {
|
|
309
309
|
return s;
|
|
310
310
|
}
|
|
@@ -312,21 +312,3 @@ function findMatchingObjectInAnyOf(
|
|
|
312
312
|
|
|
313
313
|
return undefined;
|
|
314
314
|
}
|
|
315
|
-
|
|
316
|
-
function discriminatorLiterals(
|
|
317
|
-
schema: ILlmSchema,
|
|
318
|
-
$defs: Record<string, ILlmSchema> | undefined,
|
|
319
|
-
): string[] {
|
|
320
|
-
const resolved: ILlmSchema = resolveSchema(schema, $defs);
|
|
321
|
-
if (LlmTypeChecker.isString(resolved)) return resolved.enum ?? [];
|
|
322
|
-
if (
|
|
323
|
-
"const" in resolved &&
|
|
324
|
-
typeof (resolved as { const?: unknown }).const === "string"
|
|
325
|
-
) {
|
|
326
|
-
return [(resolved as { const: string }).const];
|
|
327
|
-
}
|
|
328
|
-
if (LlmTypeChecker.isAnyOf(resolved)) {
|
|
329
|
-
return resolved.anyOf.flatMap((child) => discriminatorLiterals(child, $defs));
|
|
330
|
-
}
|
|
331
|
-
return [];
|
|
332
|
-
}
|