typed-openapi 1.5.0 → 1.5.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/dist/chunk-KAEXXJ7X.js +21 -0
- package/dist/{chunk-RGFFCU3R.js → chunk-O7DZWQK4.js} +7 -4
- package/dist/{chunk-N6BWPZUB.js → chunk-OVT6OLBK.js} +102 -26
- package/dist/cli.js +3 -2
- package/dist/index.d.ts +6 -229
- package/dist/index.js +2 -1
- package/dist/node.export.d.ts +8 -5
- package/dist/node.export.js +4 -6
- package/dist/pretty.export.d.ts +5 -0
- package/dist/pretty.export.js +6 -0
- package/dist/types-DLE5RaXi.d.ts +242 -0
- package/package.json +3 -2
- package/src/generate-client-files.ts +8 -2
- package/src/generator.ts +2 -0
- package/src/map-openapi-endpoints.ts +15 -6
- package/src/node.export.ts +0 -1
- package/src/pretty.export.ts +1 -0
- package/src/ref-resolver.ts +12 -2
- package/src/sanitize-name.ts +79 -0
- package/src/types.ts +14 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/format.ts
|
|
2
|
+
import prettier from "prettier";
|
|
3
|
+
import parserTypescript from "prettier/parser-typescript";
|
|
4
|
+
function maybePretty(input, options) {
|
|
5
|
+
try {
|
|
6
|
+
return prettier.format(input, {
|
|
7
|
+
parser: "typescript",
|
|
8
|
+
plugins: [parserTypescript],
|
|
9
|
+
...options
|
|
10
|
+
});
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.warn("Failed to format code");
|
|
13
|
+
console.warn(err);
|
|
14
|
+
return input;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
var prettify = (str, options) => maybePretty(str, { printWidth: 120, trailingComma: "all", ...options });
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
prettify
|
|
21
|
+
};
|
|
@@ -2,9 +2,11 @@ import {
|
|
|
2
2
|
allowedRuntimes,
|
|
3
3
|
generateFile,
|
|
4
4
|
generateTanstackQueryFile,
|
|
5
|
-
mapOpenApiEndpoints
|
|
5
|
+
mapOpenApiEndpoints
|
|
6
|
+
} from "./chunk-OVT6OLBK.js";
|
|
7
|
+
import {
|
|
6
8
|
prettify
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KAEXXJ7X.js";
|
|
8
10
|
|
|
9
11
|
// src/generate-client-files.ts
|
|
10
12
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
@@ -28,13 +30,14 @@ var optionsSchema = type({
|
|
|
28
30
|
});
|
|
29
31
|
async function generateClientFiles(input, options) {
|
|
30
32
|
const openApiDoc = await SwaggerParser.bundle(input);
|
|
31
|
-
const ctx = mapOpenApiEndpoints(openApiDoc);
|
|
33
|
+
const ctx = mapOpenApiEndpoints(openApiDoc, options);
|
|
32
34
|
console.log(`Found ${ctx.endpointList.length} endpoints`);
|
|
33
35
|
const content = await prettify(
|
|
34
36
|
generateFile({
|
|
35
37
|
...ctx,
|
|
36
38
|
runtime: options.runtime,
|
|
37
|
-
schemasOnly: options.schemasOnly
|
|
39
|
+
schemasOnly: options.schemasOnly,
|
|
40
|
+
nameTransform: options.nameTransform
|
|
38
41
|
})
|
|
39
42
|
);
|
|
40
43
|
const outputPath = join(
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
prettify
|
|
3
|
+
} from "./chunk-KAEXXJ7X.js";
|
|
4
|
+
|
|
1
5
|
// src/asserts.ts
|
|
2
6
|
var isPrimitiveType = (type2) => primitiveTypeList.includes(type2);
|
|
3
7
|
var primitiveTypeList = ["string", "number", "integer", "boolean", "null"];
|
|
@@ -603,10 +607,90 @@ function topologicalSort(graph) {
|
|
|
603
607
|
return sorted;
|
|
604
608
|
}
|
|
605
609
|
|
|
610
|
+
// src/sanitize-name.ts
|
|
611
|
+
var reservedWords = /* @__PURE__ */ new Set([
|
|
612
|
+
// TS keywords and built-ins
|
|
613
|
+
"import",
|
|
614
|
+
"package",
|
|
615
|
+
"namespace",
|
|
616
|
+
"Record",
|
|
617
|
+
"Partial",
|
|
618
|
+
"Required",
|
|
619
|
+
"Readonly",
|
|
620
|
+
"Pick",
|
|
621
|
+
"Omit",
|
|
622
|
+
"String",
|
|
623
|
+
"Number",
|
|
624
|
+
"Boolean",
|
|
625
|
+
"Object",
|
|
626
|
+
"Array",
|
|
627
|
+
"Function",
|
|
628
|
+
"any",
|
|
629
|
+
"unknown",
|
|
630
|
+
"never",
|
|
631
|
+
"void",
|
|
632
|
+
"extends",
|
|
633
|
+
"super",
|
|
634
|
+
"class",
|
|
635
|
+
"interface",
|
|
636
|
+
"type",
|
|
637
|
+
"enum",
|
|
638
|
+
"const",
|
|
639
|
+
"let",
|
|
640
|
+
"var",
|
|
641
|
+
"if",
|
|
642
|
+
"else",
|
|
643
|
+
"for",
|
|
644
|
+
"while",
|
|
645
|
+
"do",
|
|
646
|
+
"switch",
|
|
647
|
+
"case",
|
|
648
|
+
"default",
|
|
649
|
+
"break",
|
|
650
|
+
"continue",
|
|
651
|
+
"return",
|
|
652
|
+
"try",
|
|
653
|
+
"catch",
|
|
654
|
+
"finally",
|
|
655
|
+
"throw",
|
|
656
|
+
"new",
|
|
657
|
+
"delete",
|
|
658
|
+
"in",
|
|
659
|
+
"instanceof",
|
|
660
|
+
"typeof",
|
|
661
|
+
"void",
|
|
662
|
+
"with",
|
|
663
|
+
"yield",
|
|
664
|
+
"await",
|
|
665
|
+
"static",
|
|
666
|
+
"public",
|
|
667
|
+
"private",
|
|
668
|
+
"protected",
|
|
669
|
+
"abstract",
|
|
670
|
+
"as",
|
|
671
|
+
"asserts",
|
|
672
|
+
"from",
|
|
673
|
+
"get",
|
|
674
|
+
"set",
|
|
675
|
+
"module",
|
|
676
|
+
"require",
|
|
677
|
+
"keyof",
|
|
678
|
+
"readonly",
|
|
679
|
+
"global",
|
|
680
|
+
"symbol",
|
|
681
|
+
"bigint"
|
|
682
|
+
]);
|
|
683
|
+
function sanitizeName(name, type2) {
|
|
684
|
+
let n = name.replace(/[\W/]+/g, "_");
|
|
685
|
+
if (/^\d/.test(n)) n = "_" + n;
|
|
686
|
+
if (reservedWords.has(n)) n = (type2 === "schema" ? "Schema_" : "Endpoint_") + n;
|
|
687
|
+
return n;
|
|
688
|
+
}
|
|
689
|
+
|
|
606
690
|
// src/ref-resolver.ts
|
|
607
691
|
var autocorrectRef = (ref) => ref[1] === "/" ? ref : "#/" + ref.slice(1);
|
|
608
692
|
var componentsWithSchemas = ["schemas", "responses", "parameters", "requestBodies", "headers"];
|
|
609
|
-
var createRefResolver = (doc, factory2) => {
|
|
693
|
+
var createRefResolver = (doc, factory2, nameTransform) => {
|
|
610
694
|
const nameByRef = /* @__PURE__ */ new Map();
|
|
611
695
|
const refByName = /* @__PURE__ */ new Map();
|
|
612
696
|
const byRef = /* @__PURE__ */ new Map();
|
|
@@ -619,7 +703,11 @@ var createRefResolver = (doc, factory2) => {
|
|
|
619
703
|
const normalizedPath = path.replace("#/", "").replace("#", "").replaceAll("/", ".");
|
|
620
704
|
const map = get(doc, normalizedPath) ?? {};
|
|
621
705
|
const name = split[split.length - 1];
|
|
622
|
-
|
|
706
|
+
let normalized = normalizeString(name);
|
|
707
|
+
if (nameTransform?.transformSchemaName) {
|
|
708
|
+
normalized = nameTransform.transformSchemaName(normalized);
|
|
709
|
+
}
|
|
710
|
+
normalized = sanitizeName(normalized, "schema");
|
|
623
711
|
nameByRef.set(correctRef, normalized);
|
|
624
712
|
refByName.set(normalized, correctRef);
|
|
625
713
|
const infos = { ref: correctRef, name, normalized, kind: normalizedPath.split(".")[1] };
|
|
@@ -768,7 +856,7 @@ var tsFactory = createFactory({
|
|
|
768
856
|
import { capitalize as capitalize3, pick } from "pastable/server";
|
|
769
857
|
import { match as match2, P } from "ts-pattern";
|
|
770
858
|
var factory = tsFactory;
|
|
771
|
-
var mapOpenApiEndpoints = (doc) => {
|
|
859
|
+
var mapOpenApiEndpoints = (doc, options) => {
|
|
772
860
|
const refs = createRefResolver(doc, factory);
|
|
773
861
|
const ctx = { refs, factory };
|
|
774
862
|
const endpointList = [];
|
|
@@ -776,6 +864,10 @@ var mapOpenApiEndpoints = (doc) => {
|
|
|
776
864
|
const pathItem = pick(pathItemObj, ["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
777
865
|
Object.entries(pathItem).forEach(([method, operation]) => {
|
|
778
866
|
if (operation.deprecated) return;
|
|
867
|
+
let alias = getAlias({ path, method, operation });
|
|
868
|
+
if (options?.nameTransform?.transformEndpointName) {
|
|
869
|
+
alias = options.nameTransform.transformEndpointName({ alias, path, method, operation });
|
|
870
|
+
}
|
|
779
871
|
const endpoint = {
|
|
780
872
|
operation,
|
|
781
873
|
method,
|
|
@@ -783,7 +875,7 @@ var mapOpenApiEndpoints = (doc) => {
|
|
|
783
875
|
requestFormat: "json",
|
|
784
876
|
response: openApiSchemaToTs({ schema: {}, ctx }),
|
|
785
877
|
meta: {
|
|
786
|
-
alias
|
|
878
|
+
alias,
|
|
787
879
|
areParametersRequired: false,
|
|
788
880
|
hasParameters: false
|
|
789
881
|
}
|
|
@@ -827,7 +919,7 @@ var mapOpenApiEndpoints = (doc) => {
|
|
|
827
919
|
const matchingMediaType = Object.keys(content2).find(isAllowedParamMediaTypes);
|
|
828
920
|
if (matchingMediaType && content2[matchingMediaType]) {
|
|
829
921
|
params.body = openApiSchemaToTs({
|
|
830
|
-
schema: content2[matchingMediaType]?.schema ?? {}
|
|
922
|
+
schema: content2[matchingMediaType]?.schema ?? {},
|
|
831
923
|
ctx
|
|
832
924
|
});
|
|
833
925
|
}
|
|
@@ -866,7 +958,7 @@ var mapOpenApiEndpoints = (doc) => {
|
|
|
866
958
|
const matchingMediaType = Object.keys(content).find(isResponseMediaType);
|
|
867
959
|
if (matchingMediaType && content[matchingMediaType]) {
|
|
868
960
|
endpoint.response = openApiSchemaToTs({
|
|
869
|
-
schema: content[matchingMediaType]?.schema ?? {}
|
|
961
|
+
schema: content[matchingMediaType]?.schema ?? {},
|
|
870
962
|
ctx
|
|
871
963
|
});
|
|
872
964
|
}
|
|
@@ -895,25 +987,10 @@ var allowedParamMediaTypes = [
|
|
|
895
987
|
];
|
|
896
988
|
var isAllowedParamMediaTypes = (mediaType) => mediaType.includes("application/") && mediaType.includes("json") || allowedParamMediaTypes.includes(mediaType) || mediaType.includes("text/");
|
|
897
989
|
var isResponseMediaType = (mediaType) => mediaType === "application/json";
|
|
898
|
-
var getAlias = ({ path, method, operation }) => (
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
import parserTypescript from "prettier/parser-typescript";
|
|
903
|
-
function maybePretty(input, options) {
|
|
904
|
-
try {
|
|
905
|
-
return prettier.format(input, {
|
|
906
|
-
parser: "typescript",
|
|
907
|
-
plugins: [parserTypescript],
|
|
908
|
-
...options
|
|
909
|
-
});
|
|
910
|
-
} catch (err) {
|
|
911
|
-
console.warn("Failed to format code");
|
|
912
|
-
console.warn(err);
|
|
913
|
-
return input;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
var prettify = (str, options) => maybePretty(str, { printWidth: 120, trailingComma: "all", ...options });
|
|
990
|
+
var getAlias = ({ path, method, operation }) => sanitizeName(
|
|
991
|
+
(method + "_" + capitalize3(operation.operationId ?? pathToVariableName(path))).replace(/-/g, "__"),
|
|
992
|
+
"endpoint"
|
|
993
|
+
);
|
|
917
994
|
|
|
918
995
|
// src/tanstack-query.generator.ts
|
|
919
996
|
import { capitalize as capitalize4 } from "pastable/server";
|
|
@@ -1064,6 +1141,5 @@ export {
|
|
|
1064
1141
|
createRefResolver,
|
|
1065
1142
|
tsFactory,
|
|
1066
1143
|
mapOpenApiEndpoints,
|
|
1067
|
-
prettify,
|
|
1068
1144
|
generateTanstackQueryFile
|
|
1069
1145
|
};
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateClientFiles
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O7DZWQK4.js";
|
|
4
4
|
import {
|
|
5
5
|
allowedRuntimes
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OVT6OLBK.js";
|
|
7
|
+
import "./chunk-KAEXXJ7X.js";
|
|
7
8
|
|
|
8
9
|
// src/cli.ts
|
|
9
10
|
import { cac } from "cac";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,176 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { ReferenceObject } from 'openapi3-ts/oas31';
|
|
2
|
+
import { S as StringOrBox, O as OpenapiSchemaConvertContext, L as LibSchemaObject, B as BoxFactory, m as mapOpenApiEndpoints, N as NameTransformOptions, a as OpenapiSchemaConvertArgs, b as Box, A as AnyBoxDef } from './types-DLE5RaXi.js';
|
|
3
|
+
export { q as AnyBox, j as BoxArray, f as BoxDefinition, i as BoxIntersection, o as BoxKeyword, n as BoxLiteral, p as BoxObject, k as BoxOptional, g as BoxParams, l as BoxRef, h as BoxUnion, c as Endpoint, E as EndpointParameters, F as FactoryCreator, G as GenericFactory, M as Method, R as RefInfo, e as RefResolver, W as WithSchema, d as createRefResolver } from './types-DLE5RaXi.js';
|
|
4
4
|
import * as arktype_internal_methods_string_ts from 'arktype/internal/methods/string.ts';
|
|
5
5
|
import * as Codegen from '@sinclair/typebox-codegen';
|
|
6
|
-
|
|
7
|
-
declare class Box<T extends AnyBoxDef = AnyBoxDef> {
|
|
8
|
-
definition: T;
|
|
9
|
-
type: T["type"];
|
|
10
|
-
value: T["value"];
|
|
11
|
-
params: T["params"];
|
|
12
|
-
schema: T["schema"];
|
|
13
|
-
ctx: T["ctx"];
|
|
14
|
-
constructor(definition: T);
|
|
15
|
-
toJSON(): {
|
|
16
|
-
type: T["type"];
|
|
17
|
-
value: T["value"];
|
|
18
|
-
};
|
|
19
|
-
toString(): string;
|
|
20
|
-
recompute(callback: OpenapiSchemaConvertContext["onBox"]): Box<AnyBoxDef>;
|
|
21
|
-
static fromJSON(json: string): Box<any>;
|
|
22
|
-
static isBox(box: unknown): box is Box<AnyBoxDef>;
|
|
23
|
-
static isUnion(box: Box<AnyBoxDef>): box is Box<BoxUnion>;
|
|
24
|
-
static isIntersection(box: Box<AnyBoxDef>): box is Box<BoxIntersection>;
|
|
25
|
-
static isArray(box: Box<AnyBoxDef>): box is Box<BoxArray>;
|
|
26
|
-
static isOptional(box: Box<AnyBoxDef>): box is Box<BoxOptional>;
|
|
27
|
-
static isReference(box: Box<AnyBoxDef>): box is Box<BoxRef>;
|
|
28
|
-
static isKeyword(box: Box<AnyBoxDef>): box is Box<BoxKeyword>;
|
|
29
|
-
static isObject(box: Box<AnyBoxDef>): box is Box<BoxObject>;
|
|
30
|
-
static isLiteral(box: Box<AnyBoxDef>): box is Box<BoxLiteral>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type RefInfo = {
|
|
34
|
-
/**
|
|
35
|
-
* The (potentially autocorrected) ref
|
|
36
|
-
* @example "#/components/schemas/MySchema"
|
|
37
|
-
*/
|
|
38
|
-
ref: string;
|
|
39
|
-
/**
|
|
40
|
-
* The name of the ref
|
|
41
|
-
* @example "MySchema"
|
|
42
|
-
* */
|
|
43
|
-
name: string;
|
|
44
|
-
normalized: string;
|
|
45
|
-
kind: "schemas" | "responses" | "parameters" | "requestBodies" | "headers";
|
|
46
|
-
};
|
|
47
|
-
declare const createRefResolver: (doc: OpenAPIObject, factory: GenericFactory) => {
|
|
48
|
-
get: <T = LibSchemaObject>(ref: string) => NonNullable<T>;
|
|
49
|
-
unwrap: <T extends ReferenceObject | {}>(component: T) => Exclude<T, ReferenceObject>;
|
|
50
|
-
getInfosByRef: (ref: string) => RefInfo;
|
|
51
|
-
infos: Map<string, RefInfo>;
|
|
52
|
-
/**
|
|
53
|
-
* Get the schemas in the order they should be generated, depending on their dependencies
|
|
54
|
-
* so that a schema is generated before the ones that depend on it
|
|
55
|
-
*/
|
|
56
|
-
getOrderedSchemas: () => [schema: Box<AnyBoxDef>, infos: RefInfo][];
|
|
57
|
-
directDependencies: Map<string, Set<string>>;
|
|
58
|
-
transitiveDependencies: Map<string, Set<string>>;
|
|
59
|
-
};
|
|
60
|
-
interface RefResolver extends ReturnType<typeof createRefResolver> {
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
type LibSchemaObject = SchemaObject & SchemaObject$1;
|
|
64
|
-
type BoxDefinition = {
|
|
65
|
-
type: string;
|
|
66
|
-
params: unknown;
|
|
67
|
-
value: string;
|
|
68
|
-
};
|
|
69
|
-
type BoxParams = string | BoxDefinition;
|
|
70
|
-
type WithSchema = {
|
|
71
|
-
schema: LibSchemaObject | ReferenceObject | undefined;
|
|
72
|
-
ctx: OpenapiSchemaConvertContext;
|
|
73
|
-
};
|
|
74
|
-
type BoxUnion = WithSchema & {
|
|
75
|
-
type: "union";
|
|
76
|
-
params: {
|
|
77
|
-
types: Array<BoxParams>;
|
|
78
|
-
};
|
|
79
|
-
value: string;
|
|
80
|
-
};
|
|
81
|
-
type BoxIntersection = WithSchema & {
|
|
82
|
-
type: "intersection";
|
|
83
|
-
params: {
|
|
84
|
-
types: Array<BoxParams>;
|
|
85
|
-
};
|
|
86
|
-
value: string;
|
|
87
|
-
};
|
|
88
|
-
type BoxArray = WithSchema & {
|
|
89
|
-
type: "array";
|
|
90
|
-
params: {
|
|
91
|
-
type: BoxParams;
|
|
92
|
-
};
|
|
93
|
-
value: string;
|
|
94
|
-
};
|
|
95
|
-
type BoxOptional = WithSchema & {
|
|
96
|
-
type: "optional";
|
|
97
|
-
params: {
|
|
98
|
-
type: BoxParams;
|
|
99
|
-
};
|
|
100
|
-
value: string;
|
|
101
|
-
};
|
|
102
|
-
type BoxRef = WithSchema & {
|
|
103
|
-
type: "ref";
|
|
104
|
-
params: {
|
|
105
|
-
name: string;
|
|
106
|
-
generics?: BoxParams[] | undefined;
|
|
107
|
-
};
|
|
108
|
-
value: string;
|
|
109
|
-
};
|
|
110
|
-
type BoxLiteral = WithSchema & {
|
|
111
|
-
type: "literal";
|
|
112
|
-
params: {};
|
|
113
|
-
value: string;
|
|
114
|
-
};
|
|
115
|
-
type BoxKeyword = WithSchema & {
|
|
116
|
-
type: "keyword";
|
|
117
|
-
params: {
|
|
118
|
-
name: string;
|
|
119
|
-
};
|
|
120
|
-
value: string;
|
|
121
|
-
};
|
|
122
|
-
type BoxObject = WithSchema & {
|
|
123
|
-
type: "object";
|
|
124
|
-
params: {
|
|
125
|
-
props: Record<string, BoxParams>;
|
|
126
|
-
};
|
|
127
|
-
value: string;
|
|
128
|
-
};
|
|
129
|
-
type AnyBoxDef = BoxUnion | BoxIntersection | BoxArray | BoxOptional | BoxRef | BoxLiteral | BoxKeyword | BoxObject;
|
|
130
|
-
type AnyBox = Box<AnyBoxDef>;
|
|
131
|
-
type OpenapiSchemaConvertArgs = {
|
|
132
|
-
schema: SchemaObject | ReferenceObject;
|
|
133
|
-
ctx: OpenapiSchemaConvertContext;
|
|
134
|
-
meta?: {} | undefined;
|
|
135
|
-
};
|
|
136
|
-
type FactoryCreator = (schema: SchemaObject | ReferenceObject, ctx: OpenapiSchemaConvertContext) => GenericFactory;
|
|
137
|
-
type OpenapiSchemaConvertContext = {
|
|
138
|
-
factory: FactoryCreator | GenericFactory;
|
|
139
|
-
refs: RefResolver;
|
|
140
|
-
onBox?: (box: Box<AnyBoxDef>) => Box<AnyBoxDef>;
|
|
141
|
-
};
|
|
142
|
-
type StringOrBox = string | Box<AnyBoxDef>;
|
|
143
|
-
type BoxFactory = {
|
|
144
|
-
union: (types: Array<StringOrBox>) => Box<BoxUnion>;
|
|
145
|
-
intersection: (types: Array<StringOrBox>) => Box<BoxIntersection>;
|
|
146
|
-
array: (type: StringOrBox) => Box<BoxArray>;
|
|
147
|
-
object: (props: Record<string, StringOrBox>) => Box<BoxObject>;
|
|
148
|
-
optional: (type: StringOrBox) => Box<BoxOptional>;
|
|
149
|
-
reference: (name: string, generics?: Array<StringOrBox> | undefined) => Box<BoxRef>;
|
|
150
|
-
literal: (value: StringOrBox) => Box<BoxLiteral>;
|
|
151
|
-
string: () => Box<BoxKeyword>;
|
|
152
|
-
number: () => Box<BoxKeyword>;
|
|
153
|
-
boolean: () => Box<BoxKeyword>;
|
|
154
|
-
unknown: () => Box<BoxKeyword>;
|
|
155
|
-
any: () => Box<BoxKeyword>;
|
|
156
|
-
never: () => Box<BoxKeyword>;
|
|
157
|
-
};
|
|
158
|
-
type GenericFactory = {
|
|
159
|
-
callback?: OpenapiSchemaConvertContext["onBox"];
|
|
160
|
-
union: (types: Array<StringOrBox>) => string;
|
|
161
|
-
intersection: (types: Array<StringOrBox>) => string;
|
|
162
|
-
array: (type: StringOrBox) => string;
|
|
163
|
-
object: (props: Record<string, StringOrBox>) => string;
|
|
164
|
-
optional: (type: StringOrBox) => string;
|
|
165
|
-
reference: (name: string, generics?: Array<StringOrBox> | undefined) => string;
|
|
166
|
-
literal: (value: StringOrBox) => string;
|
|
167
|
-
string: () => string;
|
|
168
|
-
number: () => string;
|
|
169
|
-
boolean: () => string;
|
|
170
|
-
unknown: () => string;
|
|
171
|
-
any: () => string;
|
|
172
|
-
never: () => string;
|
|
173
|
-
};
|
|
6
|
+
import 'openapi3-ts/oas30';
|
|
174
7
|
|
|
175
8
|
declare const unwrap: (param: StringOrBox) => string;
|
|
176
9
|
declare const createFactory: <T extends OpenapiSchemaConvertContext["factory"]>(f: T) => T;
|
|
@@ -179,66 +12,10 @@ declare const createFactory: <T extends OpenapiSchemaConvertContext["factory"]>(
|
|
|
179
12
|
*/
|
|
180
13
|
declare const createBoxFactory: (schema: LibSchemaObject | ReferenceObject, ctx: OpenapiSchemaConvertContext) => BoxFactory;
|
|
181
14
|
|
|
182
|
-
declare const mapOpenApiEndpoints: (doc: OpenAPIObject) => {
|
|
183
|
-
doc: OpenAPIObject;
|
|
184
|
-
refs: {
|
|
185
|
-
get: <T = LibSchemaObject>(ref: string) => NonNullable<T>;
|
|
186
|
-
unwrap: <T extends openapi3_ts_oas31.ReferenceObject | {}>(component: T) => Exclude<T, openapi3_ts_oas31.ReferenceObject>;
|
|
187
|
-
getInfosByRef: (ref: string) => RefInfo;
|
|
188
|
-
infos: Map<string, RefInfo>;
|
|
189
|
-
getOrderedSchemas: () => [schema: Box<AnyBoxDef>, infos: RefInfo][];
|
|
190
|
-
directDependencies: Map<string, Set<string>>;
|
|
191
|
-
transitiveDependencies: Map<string, Set<string>>;
|
|
192
|
-
};
|
|
193
|
-
endpointList: Endpoint<DefaultEndpoint>[];
|
|
194
|
-
factory: {
|
|
195
|
-
union: (types: StringOrBox[]) => string;
|
|
196
|
-
intersection: (types: StringOrBox[]) => string;
|
|
197
|
-
array: (type: StringOrBox) => string;
|
|
198
|
-
optional: (type: StringOrBox) => string;
|
|
199
|
-
reference: (name: string, typeArgs: StringOrBox[] | undefined) => string;
|
|
200
|
-
literal: (value: StringOrBox) => string;
|
|
201
|
-
string: () => "string";
|
|
202
|
-
number: () => "number";
|
|
203
|
-
boolean: () => "boolean";
|
|
204
|
-
unknown: () => "unknown";
|
|
205
|
-
any: () => "any";
|
|
206
|
-
never: () => "never";
|
|
207
|
-
object: (props: Record<string, StringOrBox>) => string;
|
|
208
|
-
};
|
|
209
|
-
};
|
|
210
|
-
type MutationMethod = "post" | "put" | "patch" | "delete";
|
|
211
|
-
type Method = "get" | "head" | "options" | MutationMethod;
|
|
212
|
-
type EndpointParameters = {
|
|
213
|
-
body?: Box<BoxRef>;
|
|
214
|
-
query?: Box<BoxRef> | Record<string, AnyBox>;
|
|
215
|
-
header?: Box<BoxRef> | Record<string, AnyBox>;
|
|
216
|
-
path?: Box<BoxRef> | Record<string, AnyBox>;
|
|
217
|
-
};
|
|
218
|
-
type RequestFormat = "json" | "form-data" | "form-url" | "binary" | "text";
|
|
219
|
-
type DefaultEndpoint = {
|
|
220
|
-
parameters?: EndpointParameters | undefined;
|
|
221
|
-
response: AnyBox;
|
|
222
|
-
responseHeaders?: Record<string, AnyBox>;
|
|
223
|
-
};
|
|
224
|
-
type Endpoint<TConfig extends DefaultEndpoint = DefaultEndpoint> = {
|
|
225
|
-
operation: OperationObject;
|
|
226
|
-
method: Method;
|
|
227
|
-
path: string;
|
|
228
|
-
parameters?: TConfig["parameters"];
|
|
229
|
-
requestFormat: RequestFormat;
|
|
230
|
-
meta: {
|
|
231
|
-
alias: string;
|
|
232
|
-
hasParameters: boolean;
|
|
233
|
-
areParametersRequired: boolean;
|
|
234
|
-
};
|
|
235
|
-
response: TConfig["response"];
|
|
236
|
-
responseHeaders?: TConfig["responseHeaders"];
|
|
237
|
-
};
|
|
238
|
-
|
|
239
15
|
type GeneratorOptions$1 = ReturnType<typeof mapOpenApiEndpoints> & {
|
|
240
16
|
runtime?: "none" | keyof typeof runtimeValidationGenerator;
|
|
241
17
|
schemasOnly?: boolean;
|
|
18
|
+
nameTransform?: NameTransformOptions | undefined;
|
|
242
19
|
};
|
|
243
20
|
declare const allowedRuntimes: arktype_internal_methods_string_ts.StringType<"none" | "arktype" | "io-ts" | "typebox" | "valibot" | "yup" | "zod", {}>;
|
|
244
21
|
type OutputRuntime = typeof allowedRuntimes.infer;
|
|
@@ -276,4 +53,4 @@ declare const tsFactory: {
|
|
|
276
53
|
object: (props: Record<string, StringOrBox>) => string;
|
|
277
54
|
};
|
|
278
55
|
|
|
279
|
-
export {
|
|
56
|
+
export { AnyBoxDef, BoxFactory, LibSchemaObject, NameTransformOptions, OpenapiSchemaConvertArgs, OpenapiSchemaConvertContext, type OutputRuntime, StringOrBox, createBoxFactory, createFactory, generateFile, generateTanstackQueryFile, mapOpenApiEndpoints, openApiSchemaToTs, tsFactory, unwrap };
|
package/dist/index.js
CHANGED
package/dist/node.export.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Options } from 'prettier';
|
|
2
1
|
import * as arktype_internal_methods_object_ts from 'arktype/internal/methods/object.ts';
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { N as NameTransformOptions } from './types-DLE5RaXi.js';
|
|
3
|
+
import 'openapi3-ts/oas31';
|
|
4
|
+
import 'openapi3-ts/oas30';
|
|
5
5
|
|
|
6
6
|
declare const optionsSchema: arktype_internal_methods_object_ts.ObjectType<{
|
|
7
7
|
runtime: "none" | "arktype" | "io-ts" | "typebox" | "valibot" | "yup" | "zod";
|
|
@@ -9,6 +9,9 @@ declare const optionsSchema: arktype_internal_methods_object_ts.ObjectType<{
|
|
|
9
9
|
schemasOnly: boolean;
|
|
10
10
|
output?: string;
|
|
11
11
|
}, {}>;
|
|
12
|
-
|
|
12
|
+
type GenerateClientFilesOptions = typeof optionsSchema.infer & {
|
|
13
|
+
nameTransform?: NameTransformOptions;
|
|
14
|
+
};
|
|
15
|
+
declare function generateClientFiles(input: string, options: GenerateClientFilesOptions): Promise<void>;
|
|
13
16
|
|
|
14
|
-
export { generateClientFiles
|
|
17
|
+
export { generateClientFiles };
|
package/dist/node.export.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateClientFiles
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
} from "./chunk-N6BWPZUB.js";
|
|
3
|
+
} from "./chunk-O7DZWQK4.js";
|
|
4
|
+
import "./chunk-OVT6OLBK.js";
|
|
5
|
+
import "./chunk-KAEXXJ7X.js";
|
|
7
6
|
export {
|
|
8
|
-
generateClientFiles
|
|
9
|
-
prettify
|
|
7
|
+
generateClientFiles
|
|
10
8
|
};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import * as openapi3_ts_oas31 from 'openapi3-ts/oas31';
|
|
2
|
+
import { OpenAPIObject, ReferenceObject, OperationObject, SchemaObject } from 'openapi3-ts/oas31';
|
|
3
|
+
import { SchemaObject as SchemaObject$1 } from 'openapi3-ts/oas30';
|
|
4
|
+
|
|
5
|
+
declare class Box<T extends AnyBoxDef = AnyBoxDef> {
|
|
6
|
+
definition: T;
|
|
7
|
+
type: T["type"];
|
|
8
|
+
value: T["value"];
|
|
9
|
+
params: T["params"];
|
|
10
|
+
schema: T["schema"];
|
|
11
|
+
ctx: T["ctx"];
|
|
12
|
+
constructor(definition: T);
|
|
13
|
+
toJSON(): {
|
|
14
|
+
type: T["type"];
|
|
15
|
+
value: T["value"];
|
|
16
|
+
};
|
|
17
|
+
toString(): string;
|
|
18
|
+
recompute(callback: OpenapiSchemaConvertContext["onBox"]): Box<AnyBoxDef>;
|
|
19
|
+
static fromJSON(json: string): Box<any>;
|
|
20
|
+
static isBox(box: unknown): box is Box<AnyBoxDef>;
|
|
21
|
+
static isUnion(box: Box<AnyBoxDef>): box is Box<BoxUnion>;
|
|
22
|
+
static isIntersection(box: Box<AnyBoxDef>): box is Box<BoxIntersection>;
|
|
23
|
+
static isArray(box: Box<AnyBoxDef>): box is Box<BoxArray>;
|
|
24
|
+
static isOptional(box: Box<AnyBoxDef>): box is Box<BoxOptional>;
|
|
25
|
+
static isReference(box: Box<AnyBoxDef>): box is Box<BoxRef>;
|
|
26
|
+
static isKeyword(box: Box<AnyBoxDef>): box is Box<BoxKeyword>;
|
|
27
|
+
static isObject(box: Box<AnyBoxDef>): box is Box<BoxObject>;
|
|
28
|
+
static isLiteral(box: Box<AnyBoxDef>): box is Box<BoxLiteral>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type RefInfo = {
|
|
32
|
+
/**
|
|
33
|
+
* The (potentially autocorrected) ref
|
|
34
|
+
* @example "#/components/schemas/MySchema"
|
|
35
|
+
*/
|
|
36
|
+
ref: string;
|
|
37
|
+
/**
|
|
38
|
+
* The name of the ref
|
|
39
|
+
* @example "MySchema"
|
|
40
|
+
* */
|
|
41
|
+
name: string;
|
|
42
|
+
normalized: string;
|
|
43
|
+
kind: "schemas" | "responses" | "parameters" | "requestBodies" | "headers";
|
|
44
|
+
};
|
|
45
|
+
declare const createRefResolver: (doc: OpenAPIObject, factory: GenericFactory, nameTransform?: NameTransformOptions) => {
|
|
46
|
+
get: <T = LibSchemaObject>(ref: string) => NonNullable<T>;
|
|
47
|
+
unwrap: <T extends ReferenceObject | {}>(component: T) => Exclude<T, ReferenceObject>;
|
|
48
|
+
getInfosByRef: (ref: string) => RefInfo;
|
|
49
|
+
infos: Map<string, RefInfo>;
|
|
50
|
+
/**
|
|
51
|
+
* Get the schemas in the order they should be generated, depending on their dependencies
|
|
52
|
+
* so that a schema is generated before the ones that depend on it
|
|
53
|
+
*/
|
|
54
|
+
getOrderedSchemas: () => [schema: Box<AnyBoxDef>, infos: RefInfo][];
|
|
55
|
+
directDependencies: Map<string, Set<string>>;
|
|
56
|
+
transitiveDependencies: Map<string, Set<string>>;
|
|
57
|
+
};
|
|
58
|
+
interface RefResolver extends ReturnType<typeof createRefResolver> {
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare const mapOpenApiEndpoints: (doc: OpenAPIObject, options?: {
|
|
62
|
+
nameTransform?: NameTransformOptions;
|
|
63
|
+
}) => {
|
|
64
|
+
doc: OpenAPIObject;
|
|
65
|
+
refs: {
|
|
66
|
+
get: <T = LibSchemaObject>(ref: string) => NonNullable<T>;
|
|
67
|
+
unwrap: <T extends openapi3_ts_oas31.ReferenceObject | {}>(component: T) => Exclude<T, openapi3_ts_oas31.ReferenceObject>;
|
|
68
|
+
getInfosByRef: (ref: string) => RefInfo;
|
|
69
|
+
infos: Map<string, RefInfo>;
|
|
70
|
+
getOrderedSchemas: () => [schema: Box<AnyBoxDef>, infos: RefInfo][];
|
|
71
|
+
directDependencies: Map<string, Set<string>>;
|
|
72
|
+
transitiveDependencies: Map<string, Set<string>>;
|
|
73
|
+
};
|
|
74
|
+
endpointList: Endpoint<DefaultEndpoint>[];
|
|
75
|
+
factory: {
|
|
76
|
+
union: (types: StringOrBox[]) => string;
|
|
77
|
+
intersection: (types: StringOrBox[]) => string;
|
|
78
|
+
array: (type: StringOrBox) => string;
|
|
79
|
+
optional: (type: StringOrBox) => string;
|
|
80
|
+
reference: (name: string, typeArgs: StringOrBox[] | undefined) => string;
|
|
81
|
+
literal: (value: StringOrBox) => string;
|
|
82
|
+
string: () => "string";
|
|
83
|
+
number: () => "number";
|
|
84
|
+
boolean: () => "boolean";
|
|
85
|
+
unknown: () => "unknown";
|
|
86
|
+
any: () => "any";
|
|
87
|
+
never: () => "never";
|
|
88
|
+
object: (props: Record<string, StringOrBox>) => string;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
type MutationMethod = "post" | "put" | "patch" | "delete";
|
|
92
|
+
type Method = "get" | "head" | "options" | MutationMethod;
|
|
93
|
+
type EndpointParameters = {
|
|
94
|
+
body?: Box<BoxRef>;
|
|
95
|
+
query?: Box<BoxRef> | Record<string, AnyBox>;
|
|
96
|
+
header?: Box<BoxRef> | Record<string, AnyBox>;
|
|
97
|
+
path?: Box<BoxRef> | Record<string, AnyBox>;
|
|
98
|
+
};
|
|
99
|
+
type RequestFormat = "json" | "form-data" | "form-url" | "binary" | "text";
|
|
100
|
+
type DefaultEndpoint = {
|
|
101
|
+
parameters?: EndpointParameters | undefined;
|
|
102
|
+
response: AnyBox;
|
|
103
|
+
responseHeaders?: Record<string, AnyBox>;
|
|
104
|
+
};
|
|
105
|
+
type Endpoint<TConfig extends DefaultEndpoint = DefaultEndpoint> = {
|
|
106
|
+
operation: OperationObject;
|
|
107
|
+
method: Method;
|
|
108
|
+
path: string;
|
|
109
|
+
parameters?: TConfig["parameters"];
|
|
110
|
+
requestFormat: RequestFormat;
|
|
111
|
+
meta: {
|
|
112
|
+
alias: string;
|
|
113
|
+
hasParameters: boolean;
|
|
114
|
+
areParametersRequired: boolean;
|
|
115
|
+
};
|
|
116
|
+
response: TConfig["response"];
|
|
117
|
+
responseHeaders?: TConfig["responseHeaders"];
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type LibSchemaObject = SchemaObject & SchemaObject$1;
|
|
121
|
+
type BoxDefinition = {
|
|
122
|
+
type: string;
|
|
123
|
+
params: unknown;
|
|
124
|
+
value: string;
|
|
125
|
+
};
|
|
126
|
+
type BoxParams = string | BoxDefinition;
|
|
127
|
+
type WithSchema = {
|
|
128
|
+
schema: LibSchemaObject | ReferenceObject | undefined;
|
|
129
|
+
ctx: OpenapiSchemaConvertContext;
|
|
130
|
+
};
|
|
131
|
+
type BoxUnion = WithSchema & {
|
|
132
|
+
type: "union";
|
|
133
|
+
params: {
|
|
134
|
+
types: Array<BoxParams>;
|
|
135
|
+
};
|
|
136
|
+
value: string;
|
|
137
|
+
};
|
|
138
|
+
type BoxIntersection = WithSchema & {
|
|
139
|
+
type: "intersection";
|
|
140
|
+
params: {
|
|
141
|
+
types: Array<BoxParams>;
|
|
142
|
+
};
|
|
143
|
+
value: string;
|
|
144
|
+
};
|
|
145
|
+
type BoxArray = WithSchema & {
|
|
146
|
+
type: "array";
|
|
147
|
+
params: {
|
|
148
|
+
type: BoxParams;
|
|
149
|
+
};
|
|
150
|
+
value: string;
|
|
151
|
+
};
|
|
152
|
+
type BoxOptional = WithSchema & {
|
|
153
|
+
type: "optional";
|
|
154
|
+
params: {
|
|
155
|
+
type: BoxParams;
|
|
156
|
+
};
|
|
157
|
+
value: string;
|
|
158
|
+
};
|
|
159
|
+
type BoxRef = WithSchema & {
|
|
160
|
+
type: "ref";
|
|
161
|
+
params: {
|
|
162
|
+
name: string;
|
|
163
|
+
generics?: BoxParams[] | undefined;
|
|
164
|
+
};
|
|
165
|
+
value: string;
|
|
166
|
+
};
|
|
167
|
+
type BoxLiteral = WithSchema & {
|
|
168
|
+
type: "literal";
|
|
169
|
+
params: {};
|
|
170
|
+
value: string;
|
|
171
|
+
};
|
|
172
|
+
type BoxKeyword = WithSchema & {
|
|
173
|
+
type: "keyword";
|
|
174
|
+
params: {
|
|
175
|
+
name: string;
|
|
176
|
+
};
|
|
177
|
+
value: string;
|
|
178
|
+
};
|
|
179
|
+
type BoxObject = WithSchema & {
|
|
180
|
+
type: "object";
|
|
181
|
+
params: {
|
|
182
|
+
props: Record<string, BoxParams>;
|
|
183
|
+
};
|
|
184
|
+
value: string;
|
|
185
|
+
};
|
|
186
|
+
type AnyBoxDef = BoxUnion | BoxIntersection | BoxArray | BoxOptional | BoxRef | BoxLiteral | BoxKeyword | BoxObject;
|
|
187
|
+
type AnyBox = Box<AnyBoxDef>;
|
|
188
|
+
type OpenapiSchemaConvertArgs = {
|
|
189
|
+
schema: SchemaObject | ReferenceObject;
|
|
190
|
+
ctx: OpenapiSchemaConvertContext;
|
|
191
|
+
meta?: {} | undefined;
|
|
192
|
+
};
|
|
193
|
+
type FactoryCreator = (schema: SchemaObject | ReferenceObject, ctx: OpenapiSchemaConvertContext) => GenericFactory;
|
|
194
|
+
type NameTransformOptions = {
|
|
195
|
+
transformSchemaName?: (name: string) => string;
|
|
196
|
+
transformEndpointName?: (endpoint: {
|
|
197
|
+
alias: string;
|
|
198
|
+
operation: OperationObject;
|
|
199
|
+
method: Method;
|
|
200
|
+
path: string;
|
|
201
|
+
}) => string;
|
|
202
|
+
};
|
|
203
|
+
type OpenapiSchemaConvertContext = {
|
|
204
|
+
factory: FactoryCreator | GenericFactory;
|
|
205
|
+
refs: RefResolver;
|
|
206
|
+
onBox?: (box: Box<AnyBoxDef>) => Box<AnyBoxDef>;
|
|
207
|
+
nameTransform?: NameTransformOptions;
|
|
208
|
+
};
|
|
209
|
+
type StringOrBox = string | Box<AnyBoxDef>;
|
|
210
|
+
type BoxFactory = {
|
|
211
|
+
union: (types: Array<StringOrBox>) => Box<BoxUnion>;
|
|
212
|
+
intersection: (types: Array<StringOrBox>) => Box<BoxIntersection>;
|
|
213
|
+
array: (type: StringOrBox) => Box<BoxArray>;
|
|
214
|
+
object: (props: Record<string, StringOrBox>) => Box<BoxObject>;
|
|
215
|
+
optional: (type: StringOrBox) => Box<BoxOptional>;
|
|
216
|
+
reference: (name: string, generics?: Array<StringOrBox> | undefined) => Box<BoxRef>;
|
|
217
|
+
literal: (value: StringOrBox) => Box<BoxLiteral>;
|
|
218
|
+
string: () => Box<BoxKeyword>;
|
|
219
|
+
number: () => Box<BoxKeyword>;
|
|
220
|
+
boolean: () => Box<BoxKeyword>;
|
|
221
|
+
unknown: () => Box<BoxKeyword>;
|
|
222
|
+
any: () => Box<BoxKeyword>;
|
|
223
|
+
never: () => Box<BoxKeyword>;
|
|
224
|
+
};
|
|
225
|
+
type GenericFactory = {
|
|
226
|
+
callback?: OpenapiSchemaConvertContext["onBox"];
|
|
227
|
+
union: (types: Array<StringOrBox>) => string;
|
|
228
|
+
intersection: (types: Array<StringOrBox>) => string;
|
|
229
|
+
array: (type: StringOrBox) => string;
|
|
230
|
+
object: (props: Record<string, StringOrBox>) => string;
|
|
231
|
+
optional: (type: StringOrBox) => string;
|
|
232
|
+
reference: (name: string, generics?: Array<StringOrBox> | undefined) => string;
|
|
233
|
+
literal: (value: StringOrBox) => string;
|
|
234
|
+
string: () => string;
|
|
235
|
+
number: () => string;
|
|
236
|
+
boolean: () => string;
|
|
237
|
+
unknown: () => string;
|
|
238
|
+
any: () => string;
|
|
239
|
+
never: () => string;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export { type AnyBoxDef as A, type BoxFactory as B, type EndpointParameters as E, type FactoryCreator as F, type GenericFactory as G, type LibSchemaObject as L, type Method as M, type NameTransformOptions as N, type OpenapiSchemaConvertContext as O, type RefInfo as R, type StringOrBox as S, type WithSchema as W, type OpenapiSchemaConvertArgs as a, Box as b, type Endpoint as c, createRefResolver as d, type RefResolver as e, type BoxDefinition as f, type BoxParams as g, type BoxUnion as h, type BoxIntersection as i, type BoxArray as j, type BoxOptional as k, type BoxRef as l, mapOpenApiEndpoints as m, type BoxLiteral as n, type BoxKeyword as o, type BoxObject as p, type AnyBox as q };
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typed-openapi",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./dist/index.js",
|
|
9
|
-
"./node": "./dist/node.export.js"
|
|
9
|
+
"./node": "./dist/node.export.js",
|
|
10
|
+
"./pretty": "./dist/pretty.export.js"
|
|
10
11
|
},
|
|
11
12
|
"bin": {
|
|
12
13
|
"typed-openapi": "bin.js"
|
|
@@ -7,6 +7,7 @@ import { allowedRuntimes, generateFile } from "./generator.ts";
|
|
|
7
7
|
import { mapOpenApiEndpoints } from "./map-openapi-endpoints.ts";
|
|
8
8
|
import { generateTanstackQueryFile } from "./tanstack-query.generator.ts";
|
|
9
9
|
import { prettify } from "./format.ts";
|
|
10
|
+
import type { NameTransformOptions } from "./types.ts";
|
|
10
11
|
|
|
11
12
|
const cwd = process.cwd();
|
|
12
13
|
const now = new Date();
|
|
@@ -26,10 +27,14 @@ export const optionsSchema = type({
|
|
|
26
27
|
schemasOnly: "boolean",
|
|
27
28
|
});
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
type GenerateClientFilesOptions = typeof optionsSchema.infer & {
|
|
31
|
+
nameTransform?: NameTransformOptions;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export async function generateClientFiles(input: string, options: GenerateClientFilesOptions) {
|
|
30
35
|
const openApiDoc = (await SwaggerParser.bundle(input)) as OpenAPIObject;
|
|
31
36
|
|
|
32
|
-
const ctx = mapOpenApiEndpoints(openApiDoc);
|
|
37
|
+
const ctx = mapOpenApiEndpoints(openApiDoc, options);
|
|
33
38
|
console.log(`Found ${ctx.endpointList.length} endpoints`);
|
|
34
39
|
|
|
35
40
|
const content = await prettify(
|
|
@@ -37,6 +42,7 @@ export async function generateClientFiles(input: string, options: typeof options
|
|
|
37
42
|
...ctx,
|
|
38
43
|
runtime: options.runtime,
|
|
39
44
|
schemasOnly: options.schemasOnly,
|
|
45
|
+
nameTransform: options.nameTransform,
|
|
40
46
|
}),
|
|
41
47
|
);
|
|
42
48
|
const outputPath = join(
|
package/src/generator.ts
CHANGED
|
@@ -6,10 +6,12 @@ import * as Codegen from "@sinclair/typebox-codegen";
|
|
|
6
6
|
import { match } from "ts-pattern";
|
|
7
7
|
import { type } from "arktype";
|
|
8
8
|
import { wrapWithQuotesIfNeeded } from "./string-utils.ts";
|
|
9
|
+
import type { NameTransformOptions } from "./types.ts";
|
|
9
10
|
|
|
10
11
|
type GeneratorOptions = ReturnType<typeof mapOpenApiEndpoints> & {
|
|
11
12
|
runtime?: "none" | keyof typeof runtimeValidationGenerator;
|
|
12
13
|
schemasOnly?: boolean;
|
|
14
|
+
nameTransform?: NameTransformOptions | undefined;
|
|
13
15
|
};
|
|
14
16
|
type GeneratorContext = Required<GeneratorOptions>;
|
|
15
17
|
|
|
@@ -8,11 +8,13 @@ import { createRefResolver } from "./ref-resolver.ts";
|
|
|
8
8
|
import { tsFactory } from "./ts-factory.ts";
|
|
9
9
|
import { AnyBox, BoxRef, OpenapiSchemaConvertContext } from "./types.ts";
|
|
10
10
|
import { pathToVariableName } from "./string-utils.ts";
|
|
11
|
+
import { NameTransformOptions } from "./types.ts";
|
|
11
12
|
import { match, P } from "ts-pattern";
|
|
13
|
+
import { sanitizeName } from "./sanitize-name.ts";
|
|
12
14
|
|
|
13
15
|
const factory = tsFactory;
|
|
14
16
|
|
|
15
|
-
export const mapOpenApiEndpoints = (doc: OpenAPIObject) => {
|
|
17
|
+
export const mapOpenApiEndpoints = (doc: OpenAPIObject, options?: { nameTransform?: NameTransformOptions }) => {
|
|
16
18
|
const refs = createRefResolver(doc, factory);
|
|
17
19
|
const ctx: OpenapiSchemaConvertContext = { refs, factory };
|
|
18
20
|
const endpointList = [] as Array<Endpoint>;
|
|
@@ -22,6 +24,10 @@ export const mapOpenApiEndpoints = (doc: OpenAPIObject) => {
|
|
|
22
24
|
Object.entries(pathItem).forEach(([method, operation]) => {
|
|
23
25
|
if (operation.deprecated) return;
|
|
24
26
|
|
|
27
|
+
let alias = getAlias({ path, method, operation } as Endpoint);
|
|
28
|
+
if (options?.nameTransform?.transformEndpointName) {
|
|
29
|
+
alias = options.nameTransform.transformEndpointName({ alias, path, method: method as Method, operation });
|
|
30
|
+
}
|
|
25
31
|
const endpoint = {
|
|
26
32
|
operation,
|
|
27
33
|
method: method as Method,
|
|
@@ -29,7 +35,7 @@ export const mapOpenApiEndpoints = (doc: OpenAPIObject) => {
|
|
|
29
35
|
requestFormat: "json",
|
|
30
36
|
response: openApiSchemaToTs({ schema: {}, ctx }),
|
|
31
37
|
meta: {
|
|
32
|
-
alias
|
|
38
|
+
alias,
|
|
33
39
|
areParametersRequired: false,
|
|
34
40
|
hasParameters: false,
|
|
35
41
|
},
|
|
@@ -84,7 +90,7 @@ export const mapOpenApiEndpoints = (doc: OpenAPIObject) => {
|
|
|
84
90
|
|
|
85
91
|
if (matchingMediaType && content[matchingMediaType]) {
|
|
86
92
|
params.body = openApiSchemaToTs({
|
|
87
|
-
schema: content[matchingMediaType]?.schema ?? {}
|
|
93
|
+
schema: content[matchingMediaType]?.schema ?? {},
|
|
88
94
|
ctx,
|
|
89
95
|
});
|
|
90
96
|
}
|
|
@@ -139,7 +145,7 @@ export const mapOpenApiEndpoints = (doc: OpenAPIObject) => {
|
|
|
139
145
|
const matchingMediaType = Object.keys(content).find(isResponseMediaType);
|
|
140
146
|
if (matchingMediaType && content[matchingMediaType]) {
|
|
141
147
|
endpoint.response = openApiSchemaToTs({
|
|
142
|
-
schema: content[matchingMediaType]?.schema ?? {}
|
|
148
|
+
schema: content[matchingMediaType]?.schema ?? {},
|
|
143
149
|
ctx,
|
|
144
150
|
});
|
|
145
151
|
}
|
|
@@ -180,10 +186,13 @@ const isAllowedParamMediaTypes = (
|
|
|
180
186
|
|
|
181
187
|
const isResponseMediaType = (mediaType: string) => mediaType === "application/json";
|
|
182
188
|
const getAlias = ({ path, method, operation }: Endpoint) =>
|
|
183
|
-
(
|
|
189
|
+
sanitizeName(
|
|
190
|
+
(method + "_" + capitalize(operation.operationId ?? pathToVariableName(path))).replace(/-/g, "__"),
|
|
191
|
+
"endpoint",
|
|
192
|
+
);
|
|
184
193
|
|
|
185
194
|
type MutationMethod = "post" | "put" | "patch" | "delete";
|
|
186
|
-
type Method = "get" | "head" | "options" | MutationMethod;
|
|
195
|
+
export type Method = "get" | "head" | "options" | MutationMethod;
|
|
187
196
|
|
|
188
197
|
export type EndpointParameters = {
|
|
189
198
|
body?: Box<BoxRef>;
|
package/src/node.export.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { prettify } from "./format.ts";
|
package/src/ref-resolver.ts
CHANGED
|
@@ -5,8 +5,10 @@ import { Box } from "./box.ts";
|
|
|
5
5
|
import { isReferenceObject } from "./is-reference-object.ts";
|
|
6
6
|
import { openApiSchemaToTs } from "./openapi-schema-to-ts.ts";
|
|
7
7
|
import { normalizeString } from "./string-utils.ts";
|
|
8
|
+
import { NameTransformOptions } from "./types.ts";
|
|
8
9
|
import { AnyBoxDef, GenericFactory, type LibSchemaObject } from "./types.ts";
|
|
9
10
|
import { topologicalSort } from "./topological-sort.ts";
|
|
11
|
+
import { sanitizeName } from "./sanitize-name.ts";
|
|
10
12
|
|
|
11
13
|
const autocorrectRef = (ref: string) => (ref[1] === "/" ? ref : "#/" + ref.slice(1));
|
|
12
14
|
const componentsWithSchemas = ["schemas", "responses", "parameters", "requestBodies", "headers"];
|
|
@@ -26,7 +28,11 @@ export type RefInfo = {
|
|
|
26
28
|
kind: "schemas" | "responses" | "parameters" | "requestBodies" | "headers";
|
|
27
29
|
};
|
|
28
30
|
|
|
29
|
-
export const createRefResolver = (
|
|
31
|
+
export const createRefResolver = (
|
|
32
|
+
doc: OpenAPIObject,
|
|
33
|
+
factory: GenericFactory,
|
|
34
|
+
nameTransform?: NameTransformOptions,
|
|
35
|
+
) => {
|
|
30
36
|
// both used for debugging purpose
|
|
31
37
|
const nameByRef = new Map<string, string>();
|
|
32
38
|
const refByName = new Map<string, string>();
|
|
@@ -48,7 +54,11 @@ export const createRefResolver = (doc: OpenAPIObject, factory: GenericFactory) =
|
|
|
48
54
|
|
|
49
55
|
// "#/components/schemas/Something.jsonld" -> "Something.jsonld"
|
|
50
56
|
const name = split[split.length - 1]!;
|
|
51
|
-
|
|
57
|
+
let normalized = normalizeString(name);
|
|
58
|
+
if (nameTransform?.transformSchemaName) {
|
|
59
|
+
normalized = nameTransform.transformSchemaName(normalized);
|
|
60
|
+
}
|
|
61
|
+
normalized = sanitizeName(normalized, "schema");
|
|
52
62
|
|
|
53
63
|
nameByRef.set(correctRef, normalized);
|
|
54
64
|
refByName.set(normalized, correctRef);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const reservedWords = new Set([
|
|
2
|
+
// TS keywords and built-ins
|
|
3
|
+
"import",
|
|
4
|
+
"package",
|
|
5
|
+
"namespace",
|
|
6
|
+
"Record",
|
|
7
|
+
"Partial",
|
|
8
|
+
"Required",
|
|
9
|
+
"Readonly",
|
|
10
|
+
"Pick",
|
|
11
|
+
"Omit",
|
|
12
|
+
"String",
|
|
13
|
+
"Number",
|
|
14
|
+
"Boolean",
|
|
15
|
+
"Object",
|
|
16
|
+
"Array",
|
|
17
|
+
"Function",
|
|
18
|
+
"any",
|
|
19
|
+
"unknown",
|
|
20
|
+
"never",
|
|
21
|
+
"void",
|
|
22
|
+
"extends",
|
|
23
|
+
"super",
|
|
24
|
+
"class",
|
|
25
|
+
"interface",
|
|
26
|
+
"type",
|
|
27
|
+
"enum",
|
|
28
|
+
"const",
|
|
29
|
+
"let",
|
|
30
|
+
"var",
|
|
31
|
+
"if",
|
|
32
|
+
"else",
|
|
33
|
+
"for",
|
|
34
|
+
"while",
|
|
35
|
+
"do",
|
|
36
|
+
"switch",
|
|
37
|
+
"case",
|
|
38
|
+
"default",
|
|
39
|
+
"break",
|
|
40
|
+
"continue",
|
|
41
|
+
"return",
|
|
42
|
+
"try",
|
|
43
|
+
"catch",
|
|
44
|
+
"finally",
|
|
45
|
+
"throw",
|
|
46
|
+
"new",
|
|
47
|
+
"delete",
|
|
48
|
+
"in",
|
|
49
|
+
"instanceof",
|
|
50
|
+
"typeof",
|
|
51
|
+
"void",
|
|
52
|
+
"with",
|
|
53
|
+
"yield",
|
|
54
|
+
"await",
|
|
55
|
+
"static",
|
|
56
|
+
"public",
|
|
57
|
+
"private",
|
|
58
|
+
"protected",
|
|
59
|
+
"abstract",
|
|
60
|
+
"as",
|
|
61
|
+
"asserts",
|
|
62
|
+
"from",
|
|
63
|
+
"get",
|
|
64
|
+
"set",
|
|
65
|
+
"module",
|
|
66
|
+
"require",
|
|
67
|
+
"keyof",
|
|
68
|
+
"readonly",
|
|
69
|
+
"global",
|
|
70
|
+
"symbol",
|
|
71
|
+
"bigint",
|
|
72
|
+
]);
|
|
73
|
+
|
|
74
|
+
export function sanitizeName(name: string, type: "schema" | "endpoint") {
|
|
75
|
+
let n = name.replace(/[\W/]+/g, "_");
|
|
76
|
+
if (/^\d/.test(n)) n = "_" + n;
|
|
77
|
+
if (reservedWords.has(n)) n = (type === "schema" ? "Schema_" : "Endpoint_") + n;
|
|
78
|
+
return n;
|
|
79
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { ReferenceObject, SchemaObject } from "openapi3-ts/oas31";
|
|
1
|
+
import type { OperationObject, ReferenceObject, SchemaObject } from "openapi3-ts/oas31";
|
|
2
2
|
import type { SchemaObject as SchemaObject3 } from "openapi3-ts/oas30";
|
|
3
3
|
|
|
4
4
|
import type { RefResolver } from "./ref-resolver.ts";
|
|
5
5
|
import { Box } from "./box.ts";
|
|
6
|
+
import type { Method } from "./map-openapi-endpoints.ts";
|
|
6
7
|
|
|
7
8
|
export type LibSchemaObject = SchemaObject & SchemaObject3;
|
|
8
9
|
|
|
@@ -94,10 +95,22 @@ export type FactoryCreator = (
|
|
|
94
95
|
schema: SchemaObject | ReferenceObject,
|
|
95
96
|
ctx: OpenapiSchemaConvertContext,
|
|
96
97
|
) => GenericFactory;
|
|
98
|
+
|
|
99
|
+
export type NameTransformOptions = {
|
|
100
|
+
transformSchemaName?: (name: string) => string;
|
|
101
|
+
transformEndpointName?: (endpoint: {
|
|
102
|
+
alias: string;
|
|
103
|
+
operation: OperationObject;
|
|
104
|
+
method: Method;
|
|
105
|
+
path: string;
|
|
106
|
+
}) => string;
|
|
107
|
+
};
|
|
108
|
+
|
|
97
109
|
export type OpenapiSchemaConvertContext = {
|
|
98
110
|
factory: FactoryCreator | GenericFactory;
|
|
99
111
|
refs: RefResolver;
|
|
100
112
|
onBox?: (box: Box<AnyBoxDef>) => Box<AnyBoxDef>;
|
|
113
|
+
nameTransform?: NameTransformOptions;
|
|
101
114
|
};
|
|
102
115
|
|
|
103
116
|
export type StringOrBox = string | Box<AnyBoxDef>;
|