toolcraft-openapi 0.0.13 → 0.0.14
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/dist/generate.d.ts +4 -1
- package/dist/generate.js +40 -12
- package/package.json +2 -2
package/dist/generate.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ import { type HttpMethod } from "./naming.js";
|
|
|
2
2
|
type OpenApiOperation = OpenApiOperationObject | OpenApiReferenceObject;
|
|
3
3
|
type OpenApiOperationMap = Partial<Record<HttpMethod, OpenApiOperation>>;
|
|
4
4
|
type OpenApiParameterLocation = "path" | "query" | "header" | "cookie";
|
|
5
|
+
type OpenApiScalarType = "string" | "number" | "integer" | "boolean";
|
|
6
|
+
type OpenApiSchemaType = OpenApiScalarType | "object" | "array";
|
|
7
|
+
type OpenApiJsonSchemaType = OpenApiSchemaType | "null";
|
|
5
8
|
export type GeneratedRequestLocation = Exclude<GeneratedParam["location"], "transport">;
|
|
6
9
|
export interface OpenApiDocument {
|
|
7
10
|
openapi?: string;
|
|
@@ -57,7 +60,7 @@ export interface OpenApiMediaTypeObject {
|
|
|
57
60
|
schema?: OpenApiSchemaObject | OpenApiReferenceObject;
|
|
58
61
|
}
|
|
59
62
|
export interface OpenApiSchemaObject {
|
|
60
|
-
type?:
|
|
63
|
+
type?: OpenApiJsonSchemaType | readonly OpenApiJsonSchemaType[];
|
|
61
64
|
additionalProperties?: boolean | OpenApiSchemaObject | OpenApiReferenceObject;
|
|
62
65
|
allOf?: Array<OpenApiSchemaObject | OpenApiReferenceObject>;
|
|
63
66
|
anyOf?: Array<OpenApiSchemaObject | OpenApiReferenceObject>;
|
package/dist/generate.js
CHANGED
|
@@ -324,17 +324,11 @@ function assertSupportedSuccessResponseSchema(document, schema, operationId, con
|
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
function expectSupportedSuccessResponseSchema(document, schema, operationId, context) {
|
|
327
|
-
const resolvedSchema = resolveSchema(document, schema, operationId, context);
|
|
327
|
+
const resolvedSchema = normalizeNullableSchema(document, resolveSchema(document, schema, operationId, context), operationId, context);
|
|
328
328
|
const compositionKeyword = getCompositionKeyword(resolvedSchema);
|
|
329
329
|
if (compositionKeyword === undefined) {
|
|
330
330
|
return resolvedSchema;
|
|
331
331
|
}
|
|
332
|
-
const nullableAnyOfSchema = compositionKeyword === "anyOf"
|
|
333
|
-
? resolveNullableAnyOfSchema(document, resolvedSchema, operationId, context)
|
|
334
|
-
: undefined;
|
|
335
|
-
if (nullableAnyOfSchema !== undefined) {
|
|
336
|
-
return nullableAnyOfSchema;
|
|
337
|
-
}
|
|
338
332
|
throw new UserError(`Operation ${JSON.stringify(operationId)} uses unsupported ${context}. JSON Schema composition keyword ${JSON.stringify(compositionKeyword)} is not supported in v1.`);
|
|
339
333
|
}
|
|
340
334
|
function createGeneratedParameter(document, parameter, operationId) {
|
|
@@ -578,6 +572,9 @@ function createCollectedRequestBodyParams(assemblies, bodyOptional, requestBodyD
|
|
|
578
572
|
};
|
|
579
573
|
}
|
|
580
574
|
function createParamDefinition(document, schema, operationId, context) {
|
|
575
|
+
if (Array.isArray(schema.type)) {
|
|
576
|
+
throw new UserError(`Operation ${JSON.stringify(operationId)} uses unsupported ${context}. JSON Schema type arrays with multiple non-null types are not supported in v1.`);
|
|
577
|
+
}
|
|
581
578
|
if (schema.type === "array") {
|
|
582
579
|
const itemSchema = expectArrayItemsSchema(document, schema, operationId, context);
|
|
583
580
|
return {
|
|
@@ -589,9 +586,9 @@ function createParamDefinition(document, schema, operationId, context) {
|
|
|
589
586
|
...(schema.nullable === true ? { nullable: true } : {})
|
|
590
587
|
};
|
|
591
588
|
}
|
|
592
|
-
const scalarDefinition =
|
|
593
|
-
?
|
|
594
|
-
:
|
|
589
|
+
const scalarDefinition = isOpenApiScalarType(schema.type)
|
|
590
|
+
? SCHEMA_TYPE_TO_KIND[schema.type]
|
|
591
|
+
: undefined;
|
|
595
592
|
const enumValues = normalizeEnumValues(schema.enum, operationId, context, schema.nullable === true, schema.type);
|
|
596
593
|
if (enumValues !== undefined) {
|
|
597
594
|
return {
|
|
@@ -747,6 +744,9 @@ function expectOperation(document, operation, method, path, refChain = []) {
|
|
|
747
744
|
function isEnumPrimitiveValue(value) {
|
|
748
745
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
749
746
|
}
|
|
747
|
+
function isOpenApiScalarType(type) {
|
|
748
|
+
return typeof type === "string" && type in SCHEMA_TYPE_TO_KIND;
|
|
749
|
+
}
|
|
750
750
|
function expectRequestBody(document, requestBody, operationId, context, refChain = []) {
|
|
751
751
|
if (!isReferenceObject(requestBody)) {
|
|
752
752
|
return requestBody;
|
|
@@ -763,7 +763,7 @@ function expectResponse(document, response, operationId, statusCode, refChain =
|
|
|
763
763
|
return expectResponse(document, resolveLocalReference(document, response.$ref, operationId, context), operationId, statusCode, [...refChain, response.$ref]);
|
|
764
764
|
}
|
|
765
765
|
function expectSchema(document, schema, operationId, context, refChain = []) {
|
|
766
|
-
const resolvedSchema = resolveSchema(document, schema, operationId, context, refChain);
|
|
766
|
+
const resolvedSchema = normalizeNullableSchema(document, resolveSchema(document, schema, operationId, context, refChain), operationId, context);
|
|
767
767
|
const compositionKeyword = getCompositionKeyword(resolvedSchema);
|
|
768
768
|
if (compositionKeyword !== undefined) {
|
|
769
769
|
throw new UserError(`Operation ${JSON.stringify(operationId)} uses unsupported ${context}. JSON Schema composition keyword ${JSON.stringify(compositionKeyword)} is not supported in v1.`);
|
|
@@ -780,6 +780,28 @@ function resolveSchema(document, schema, operationId, context, refChain = []) {
|
|
|
780
780
|
}
|
|
781
781
|
return schema;
|
|
782
782
|
}
|
|
783
|
+
function normalizeNullableSchema(document, schema, operationId, context) {
|
|
784
|
+
const typeNormalizedSchema = normalizeNullableTypeArray(schema);
|
|
785
|
+
if (getCompositionKeyword(typeNormalizedSchema) !== "anyOf") {
|
|
786
|
+
return typeNormalizedSchema;
|
|
787
|
+
}
|
|
788
|
+
return (resolveNullableAnyOfSchema(document, typeNormalizedSchema, operationId, context) ??
|
|
789
|
+
typeNormalizedSchema);
|
|
790
|
+
}
|
|
791
|
+
function normalizeNullableTypeArray(schema) {
|
|
792
|
+
if (!Array.isArray(schema.type)) {
|
|
793
|
+
return schema;
|
|
794
|
+
}
|
|
795
|
+
const nonNullTypes = schema.type.filter((type) => type !== "null");
|
|
796
|
+
if (nonNullTypes.length === schema.type.length) {
|
|
797
|
+
return schema;
|
|
798
|
+
}
|
|
799
|
+
return {
|
|
800
|
+
...schema,
|
|
801
|
+
type: nonNullTypes.length === 1 ? nonNullTypes[0] : nonNullTypes,
|
|
802
|
+
nullable: true
|
|
803
|
+
};
|
|
804
|
+
}
|
|
783
805
|
function getCompositionKeyword(schema) {
|
|
784
806
|
for (const keyword of ["allOf", "anyOf", "oneOf"]) {
|
|
785
807
|
if (schema[keyword] !== undefined) {
|
|
@@ -793,7 +815,7 @@ function resolveNullableAnyOfSchema(document, schema, operationId, context) {
|
|
|
793
815
|
if (variants === undefined || variants.length !== 2) {
|
|
794
816
|
return undefined;
|
|
795
817
|
}
|
|
796
|
-
const resolvedVariants = variants.map((variant, index) => resolveSchema(document, variant, operationId, `${context} anyOf variant ${index}`));
|
|
818
|
+
const resolvedVariants = variants.map((variant, index) => normalizeNullableSchema(document, resolveSchema(document, variant, operationId, `${context} anyOf variant ${index}`), operationId, `${context} anyOf variant ${index}`));
|
|
797
819
|
const nullVariantIndex = resolvedVariants.findIndex(isExplicitNullSchema);
|
|
798
820
|
if (nullVariantIndex === -1) {
|
|
799
821
|
return undefined;
|
|
@@ -802,8 +824,14 @@ function resolveNullableAnyOfSchema(document, schema, operationId, context) {
|
|
|
802
824
|
if (nonNullVariant === undefined || getCompositionKeyword(nonNullVariant) !== undefined) {
|
|
803
825
|
return undefined;
|
|
804
826
|
}
|
|
827
|
+
const { anyOf: _anyOf, nullable: _nullable, ...wrapperSchema } = schema;
|
|
828
|
+
void _anyOf;
|
|
829
|
+
void _nullable;
|
|
805
830
|
return {
|
|
831
|
+
...wrapperSchema,
|
|
806
832
|
...nonNullVariant,
|
|
833
|
+
description: nonNullVariant.description ?? schema.description,
|
|
834
|
+
default: nonNullVariant.default ?? schema.default,
|
|
807
835
|
nullable: true
|
|
808
836
|
};
|
|
809
837
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft-openapi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"auth-store": "^0.0.1",
|
|
31
31
|
"chalk": "^5.6.2",
|
|
32
32
|
"console-table-printer": "^2.15.0",
|
|
33
|
-
"toolcraft": "^0.0.
|
|
33
|
+
"toolcraft": "^0.0.14",
|
|
34
34
|
"yaml": "^2.8.2"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|