@goast/core 0.5.0-beta.5 → 0.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/LICENSE +21 -21
- package/esm/src/transform/helpers.d.ts.map +1 -1
- package/esm/src/transform/helpers.js +0 -1
- package/esm/src/utils/api-data.utils.d.ts +2 -2
- package/esm/src/utils/api-data.utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/script/src/transform/helpers.d.ts.map +1 -1
- package/script/src/transform/helpers.js +0 -1
- package/script/src/utils/api-data.utils.d.ts +2 -2
- package/script/src/utils/api-data.utils.d.ts.map +1 -1
- package/src/_dnt.shims.ts +69 -0
- package/src/mod.ts +35 -0
- package/src/src/ast/node.ts +46 -0
- package/src/src/codegen/config.ts +41 -0
- package/src/src/codegen/endpoints-generator.ts +72 -0
- package/src/src/codegen/generator.ts +192 -0
- package/src/src/codegen/internal-utils.ts +6 -0
- package/src/src/codegen/schemas-generator.ts +87 -0
- package/src/src/codegen/services-generator.ts +77 -0
- package/src/src/codegen/types.ts +37 -0
- package/src/src/collect/collector.ts +142 -0
- package/src/src/collect/helpers.ts +36 -0
- package/src/src/collect/types.ts +21 -0
- package/src/src/internal-utils.ts +5 -0
- package/src/src/parse/deref-proxy.ts +64 -0
- package/src/src/parse/openapi-types.ts +949 -0
- package/src/src/parse/parser.ts +226 -0
- package/src/src/parse/types.ts +27 -0
- package/src/src/transform/api-types.ts +245 -0
- package/src/src/transform/helpers.ts +216 -0
- package/src/src/transform/transform-document.ts +35 -0
- package/src/src/transform/transform-endpoint.ts +331 -0
- package/src/src/transform/transform-schema.ts +217 -0
- package/src/src/transform/transformer.ts +53 -0
- package/src/src/transform/types.ts +52 -0
- package/src/src/utils/action-provider.ts +58 -0
- package/src/src/utils/api-data.utils.ts +48 -0
- package/src/src/utils/array.utils.ts +7 -0
- package/src/src/utils/asset-manager.ts +51 -0
- package/src/src/utils/class.utils.ts +40 -0
- package/src/src/utils/common.utils.ts +86 -0
- package/src/src/utils/condition.ts +7 -0
- package/src/src/utils/endpoint.utils.ts +10 -0
- package/src/src/utils/error.utils.ts +3 -0
- package/src/src/utils/factory.ts +42 -0
- package/src/src/utils/file-system.utils.ts +61 -0
- package/src/src/utils/generator.utils.ts +6 -0
- package/src/src/utils/object.utils.ts +32 -0
- package/src/src/utils/schema.utils.ts +148 -0
- package/src/src/utils/source-builder.ts +597 -0
- package/src/src/utils/string-builder/options.ts +19 -0
- package/src/src/utils/string-builder/string-builder.ts +165 -0
- package/src/src/utils/string-builder/utils.ts +69 -0
- package/src/src/utils/string.utils.ts +369 -0
- package/src/src/utils/string.utils.types.ts +179 -0
- package/src/src/utils/type.utils.ts +93 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { cwd } from 'node:process';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import * as YAML from 'yaml';
|
|
8
|
+
|
|
9
|
+
import { collectOpenApi } from '../collect/collector.js';
|
|
10
|
+
import type { ApiData } from '../transform/api-types.js';
|
|
11
|
+
import { transformOpenApi } from '../transform/transformer.js';
|
|
12
|
+
import { isNullish } from '../utils/common.utils.js';
|
|
13
|
+
import { createDerefProxy } from './deref-proxy.js';
|
|
14
|
+
import type { OpenApiDocument, OpenApiObject, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
15
|
+
import { defaultOpenApiParserOptions, type Deref, type OpenApiParserOptions } from './types.js';
|
|
16
|
+
|
|
17
|
+
type LoadedDocument = {
|
|
18
|
+
file: string;
|
|
19
|
+
document: OpenApiDocument;
|
|
20
|
+
dereferencedDocument: Deref<OpenApiDocument>;
|
|
21
|
+
dereferencedComponents: Map<string, Deref<OpenApiObject<string>>>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export class OpenApiParser {
|
|
25
|
+
private readonly _loadedDocuments = new Map<string, LoadedDocument>();
|
|
26
|
+
private readonly _config: OpenApiParserOptions;
|
|
27
|
+
|
|
28
|
+
constructor(config?: Partial<OpenApiParserOptions>) {
|
|
29
|
+
this._config = { ...defaultOpenApiParserOptions, ...config };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public async parseApisAndTransform(...fileNames: (string | string[])[]): Promise<ApiData> {
|
|
33
|
+
const flatFileNames = ([] as string[]).concat(...fileNames);
|
|
34
|
+
const apis = await Promise.all(flatFileNames.map((fileName) => this.parseApi(fileName)));
|
|
35
|
+
|
|
36
|
+
const transformed = this.transformApis(apis);
|
|
37
|
+
|
|
38
|
+
return transformed;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public async parseApi(fileName: string): Promise<Deref<OpenApiDocument>> {
|
|
42
|
+
const absoluteFilePath = this.isUrl(fileName) ? fileName : path.resolve(cwd(), fileName);
|
|
43
|
+
const doc = await this.loadDocument(absoluteFilePath);
|
|
44
|
+
return await this.dereference(absoluteFilePath, '/', doc.document);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public transformApis(apis: Deref<OpenApiDocument>[]): ApiData {
|
|
48
|
+
const collectedData = collectOpenApi(apis);
|
|
49
|
+
const transformedData = transformOpenApi(collectedData, this._config);
|
|
50
|
+
return transformedData;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private async dereference<T extends OpenApiObject<string>>(file: string, path: string, value: T): Promise<Deref<T>> {
|
|
54
|
+
let existingDocument = this._loadedDocuments.get(file);
|
|
55
|
+
if (existingDocument) {
|
|
56
|
+
const existingComponent = existingDocument.dereferencedComponents.get(path);
|
|
57
|
+
if (existingComponent) {
|
|
58
|
+
return existingComponent as Deref<T>;
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
existingDocument = await this.loadDocument(file);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const result = createDerefProxy(value, {
|
|
65
|
+
file,
|
|
66
|
+
path,
|
|
67
|
+
document: existingDocument.dereferencedDocument,
|
|
68
|
+
originalComponent: value,
|
|
69
|
+
});
|
|
70
|
+
existingDocument.dereferencedComponents.set(path, result as Deref<OpenApiObject<string>>);
|
|
71
|
+
|
|
72
|
+
if (value.$ref) {
|
|
73
|
+
// deno-lint-ignore no-explicit-any
|
|
74
|
+
result.$ref = await this.resolveReference<T>(file, value as OpenApiReference) as any;
|
|
75
|
+
}
|
|
76
|
+
for (const key of Object.keys(value) as (keyof T)[]) {
|
|
77
|
+
if (key === '$ref') continue;
|
|
78
|
+
const v = value[key];
|
|
79
|
+
if (isNullish(v)) continue;
|
|
80
|
+
if (typeof v === 'object') {
|
|
81
|
+
if (Array.isArray(v)) {
|
|
82
|
+
(result as Record<keyof T, unknown>)[key] = await Promise.all(
|
|
83
|
+
v.map(async (v, index) => {
|
|
84
|
+
if (v && typeof v === 'object') {
|
|
85
|
+
return await this.dereference(file, joinPaths(path, key, index), v);
|
|
86
|
+
} else {
|
|
87
|
+
return v;
|
|
88
|
+
}
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
(result as Record<keyof T, unknown>)[key] = await this.dereference(
|
|
93
|
+
file,
|
|
94
|
+
joinPaths(path, key),
|
|
95
|
+
v as Record<string, unknown>,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (typeof v === 'string' && path.endsWith('/discriminator/mapping')) {
|
|
100
|
+
(result as Record<keyof T, unknown>)[key] = await this.resolveReference<OpenApiSchema>(file, { $ref: v });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private async resolveReference<T extends OpenApiObject<string>>(
|
|
108
|
+
file: string,
|
|
109
|
+
ref: OpenApiReference,
|
|
110
|
+
): Promise<Deref<T> | undefined> {
|
|
111
|
+
const [refFile, refPath] = ref.$ref.split('#');
|
|
112
|
+
|
|
113
|
+
let absoluteRefFile: string = refFile;
|
|
114
|
+
if (!/\S/.test(refFile)) {
|
|
115
|
+
absoluteRefFile = file;
|
|
116
|
+
} else if (!this.isUrl(refFile)) {
|
|
117
|
+
absoluteRefFile = path.resolve(path.dirname(file), refFile);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const doc = await this.loadDocument(absoluteRefFile);
|
|
121
|
+
|
|
122
|
+
const value = refPath ? getDeepProperty(doc.document, refPath.replace(/[/]/g, '.')) : doc.document;
|
|
123
|
+
if (value && typeof value === 'object') {
|
|
124
|
+
return this.dereference(absoluteRefFile, refPath ?? '/', value as T);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private async loadDocument(fileOrUrl: string): Promise<LoadedDocument> {
|
|
131
|
+
const existingDocument = this._loadedDocuments.get(fileOrUrl);
|
|
132
|
+
if (existingDocument) {
|
|
133
|
+
return existingDocument;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const documentContent = await this.getDocumentContent(fileOrUrl);
|
|
137
|
+
const extname = path.extname(fileOrUrl).toLowerCase();
|
|
138
|
+
|
|
139
|
+
let parsedDocument: unknown;
|
|
140
|
+
if (extname === '.json') {
|
|
141
|
+
parsedDocument = this.tryParseJson(documentContent);
|
|
142
|
+
} else if (extname === '.yaml' || extname === '.yml') {
|
|
143
|
+
parsedDocument = this.tryParseYaml(documentContent);
|
|
144
|
+
} else {
|
|
145
|
+
parsedDocument = this.tryParseJson(documentContent);
|
|
146
|
+
if (parsedDocument !== undefined) {
|
|
147
|
+
parsedDocument = this.tryParseYaml(documentContent);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (parsedDocument === undefined) {
|
|
152
|
+
throw new Error(`Unable to parse ${fileOrUrl}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const doc = (parsedDocument ?? {}) as OpenApiDocument;
|
|
156
|
+
const deref = createDerefProxy(doc, {
|
|
157
|
+
file: fileOrUrl,
|
|
158
|
+
path: '',
|
|
159
|
+
originalComponent: doc,
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
161
|
+
document: undefined!,
|
|
162
|
+
});
|
|
163
|
+
deref.$src.document = deref;
|
|
164
|
+
const loadedDocument = {
|
|
165
|
+
file: fileOrUrl,
|
|
166
|
+
document: doc,
|
|
167
|
+
dereferencedDocument: deref,
|
|
168
|
+
dereferencedComponents: new Map(),
|
|
169
|
+
};
|
|
170
|
+
this._loadedDocuments.set(fileOrUrl, loadedDocument);
|
|
171
|
+
return loadedDocument;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private async getDocumentContent(fileOrUrl: string): Promise<string> {
|
|
175
|
+
if (this.isUrl(fileOrUrl)) {
|
|
176
|
+
const res = await dntShim.fetch(fileOrUrl);
|
|
177
|
+
if (!res.ok) {
|
|
178
|
+
throw new Error(`Unable to download ${fileOrUrl}: ${res.statusText}`);
|
|
179
|
+
}
|
|
180
|
+
return await res.text();
|
|
181
|
+
} else {
|
|
182
|
+
return (await fs.readFile(fileOrUrl)).toString();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private isUrl(fileOrUrl: string): boolean {
|
|
187
|
+
return /^https?:\/\//i.test(fileOrUrl);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private tryParseJson(json: string): unknown {
|
|
191
|
+
try {
|
|
192
|
+
return JSON.parse(json);
|
|
193
|
+
} catch {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private tryParseYaml(yaml: string): unknown {
|
|
199
|
+
try {
|
|
200
|
+
return YAML.parse(yaml);
|
|
201
|
+
} catch {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function getDeepProperty(value: Record<string, unknown>, path: string): unknown {
|
|
208
|
+
const parts = path.split('.');
|
|
209
|
+
let result: unknown = value;
|
|
210
|
+
for (const part of parts) {
|
|
211
|
+
if (!/\S/.test(part)) continue;
|
|
212
|
+
if (typeof result === 'object') {
|
|
213
|
+
result = (result as Record<string, unknown>)[part];
|
|
214
|
+
} else {
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function joinPaths(...paths: unknown[]): string {
|
|
223
|
+
return paths
|
|
224
|
+
.map((p) => String(p).replace(/\/$/, ''))
|
|
225
|
+
.join('/');
|
|
226
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
2
|
+
import { defaultOpenApiTransformerOptions, type OpenApiTransformerOptions } from '../transform/types.js';
|
|
3
|
+
|
|
4
|
+
export type DerefSource<T> = {
|
|
5
|
+
file: string;
|
|
6
|
+
path: string;
|
|
7
|
+
document: Deref<OpenApiDocument>;
|
|
8
|
+
originalComponent: T;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type _DerefDiscriminator = Omit<OpenApiDiscriminator, 'mapping'> & {
|
|
12
|
+
mapping?: Record<string, Deref<OpenApiSchema>>;
|
|
13
|
+
};
|
|
14
|
+
type _Deref<T extends object> = T extends OpenApiDiscriminator ? _DerefDiscriminator
|
|
15
|
+
:
|
|
16
|
+
& {
|
|
17
|
+
[K in keyof T as K extends keyof OpenApiReference ? never : K]: Deref<T[K]>;
|
|
18
|
+
}
|
|
19
|
+
& {
|
|
20
|
+
$src: DerefSource<T>;
|
|
21
|
+
$ref?: Deref<T>;
|
|
22
|
+
};
|
|
23
|
+
export type Deref<T> = T extends object ? (T extends (infer A)[] ? Deref<A>[] : _Deref<T>) : T;
|
|
24
|
+
|
|
25
|
+
export type OpenApiParserOptions = OpenApiTransformerOptions;
|
|
26
|
+
|
|
27
|
+
export const defaultOpenApiParserOptions = { ...defaultOpenApiTransformerOptions };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
KnownOpenApiParameterTarget,
|
|
3
|
+
OpenApiDocument,
|
|
4
|
+
OpenApiHeader,
|
|
5
|
+
OpenApiHttpMethod,
|
|
6
|
+
OpenApiMediaType,
|
|
7
|
+
OpenApiOperation,
|
|
8
|
+
OpenApiParameter,
|
|
9
|
+
OpenApiPathItem,
|
|
10
|
+
OpenApiRequestBody,
|
|
11
|
+
OpenApiResponse,
|
|
12
|
+
OpenApiSchema,
|
|
13
|
+
OpenApiTag,
|
|
14
|
+
} from '../parse/openapi-types.js';
|
|
15
|
+
import type { Deref, DerefSource } from '../parse/types.js';
|
|
16
|
+
import type { OptionalProperties } from '../utils/type.utils.js';
|
|
17
|
+
|
|
18
|
+
export type ApiData = {
|
|
19
|
+
documents: Deref<OpenApiDocument>[];
|
|
20
|
+
services: ApiService[];
|
|
21
|
+
endpoints: ApiEndpoint[];
|
|
22
|
+
schemas: ApiSchema[];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type ApiComponentSource<T> = DerefSource<T> & {
|
|
26
|
+
component: Deref<T>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type Transformed<T> = T extends OpenApiTag ? ApiService
|
|
30
|
+
: T extends OpenApiPathItem ? ApiPath
|
|
31
|
+
: T extends OpenApiParameter ? ApiParameter
|
|
32
|
+
: T extends OpenApiRequestBody ? ApiRequestBody
|
|
33
|
+
: T extends OpenApiResponse ? ApiResponse
|
|
34
|
+
: T extends OpenApiMediaType ? ApiContent
|
|
35
|
+
: T extends OpenApiHeader ? ApiHeader
|
|
36
|
+
: T extends OpenApiSchema ? ApiSchema
|
|
37
|
+
: undefined;
|
|
38
|
+
|
|
39
|
+
export type ApiComponent<T> = {
|
|
40
|
+
id: string;
|
|
41
|
+
$src: ApiComponentSource<T>;
|
|
42
|
+
$ref: Transformed<T> | undefined;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type ApiMethod = OpenApiHttpMethod;
|
|
46
|
+
export type ApiParameterTarget = KnownOpenApiParameterTarget;
|
|
47
|
+
|
|
48
|
+
export type ApiServiceComponent = OptionalProperties<ApiComponent<OpenApiTag>, '$src'>;
|
|
49
|
+
export type ApiService = ApiServiceComponent & {
|
|
50
|
+
name: string;
|
|
51
|
+
description: string | undefined;
|
|
52
|
+
endpoints: ApiEndpoint[];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type ApiPathComponent = ApiComponent<OpenApiPathItem>;
|
|
56
|
+
export type ApiPath = ApiPathComponent & {
|
|
57
|
+
summary: string | undefined;
|
|
58
|
+
description: string | undefined;
|
|
59
|
+
path: string;
|
|
60
|
+
parameters: ApiParameter[];
|
|
61
|
+
} & { [K in ApiMethod]: ApiEndpoint | undefined };
|
|
62
|
+
|
|
63
|
+
export type ApiEndpointComponent = ApiComponent<OpenApiOperation>;
|
|
64
|
+
export type ApiEndpoint = ApiEndpointComponent & {
|
|
65
|
+
name: string;
|
|
66
|
+
path: string;
|
|
67
|
+
pathInfo: ApiPath;
|
|
68
|
+
method: ApiMethod;
|
|
69
|
+
summary: string | undefined;
|
|
70
|
+
description: string | undefined;
|
|
71
|
+
parameters: ApiParameter[];
|
|
72
|
+
deprecated: boolean;
|
|
73
|
+
requestBody: ApiRequestBody | undefined;
|
|
74
|
+
responses: ApiResponse[];
|
|
75
|
+
tags: string[];
|
|
76
|
+
custom: Record<string, unknown>;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type ApiParameterComponent = ApiComponent<OpenApiParameter>;
|
|
80
|
+
export type ApiParameter = ApiParameterComponent & {
|
|
81
|
+
name: string;
|
|
82
|
+
target: ApiParameterTarget;
|
|
83
|
+
description: string | undefined;
|
|
84
|
+
required: boolean;
|
|
85
|
+
deprecated: boolean;
|
|
86
|
+
allowEmptyValue: boolean | undefined;
|
|
87
|
+
style: string | undefined;
|
|
88
|
+
explode: boolean | undefined;
|
|
89
|
+
allowReserved: boolean | undefined;
|
|
90
|
+
schema: ApiSchema | undefined;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export type ApiRequestBodyComponent = ApiComponent<OpenApiRequestBody>;
|
|
94
|
+
export type ApiRequestBody = ApiRequestBodyComponent & {
|
|
95
|
+
description: string | undefined;
|
|
96
|
+
content: ApiContent[];
|
|
97
|
+
required: boolean;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type ApiContentComponent = ApiComponent<OpenApiMediaType>;
|
|
101
|
+
export type ApiContent = ApiContentComponent & {
|
|
102
|
+
type: string;
|
|
103
|
+
schema: ApiSchema | undefined;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type ApiExampleComponent = ApiComponent<OpenApiResponse>;
|
|
107
|
+
export type ApiResponse = ApiExampleComponent & {
|
|
108
|
+
statusCode: number | undefined;
|
|
109
|
+
description: string | undefined;
|
|
110
|
+
headers: ApiHeader[];
|
|
111
|
+
contentOptions: ApiContent[];
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export type ApiHeaderComponent = Omit<ApiComponent<OpenApiHeader> | ApiComponent<OpenApiSchema>, '$ref'> & {
|
|
115
|
+
$ref: ApiHeader | undefined;
|
|
116
|
+
};
|
|
117
|
+
export type ApiHeader = ApiHeaderComponent & Omit<ApiParameter, 'target'>;
|
|
118
|
+
|
|
119
|
+
export type ApiSchemaType = 'string' | 'number' | 'integer' | 'array' | 'boolean' | 'null' | 'object' | string;
|
|
120
|
+
export type ApiSchemaKind =
|
|
121
|
+
| 'oneOf'
|
|
122
|
+
| 'multi-type'
|
|
123
|
+
| 'string'
|
|
124
|
+
| 'number'
|
|
125
|
+
| 'integer'
|
|
126
|
+
| 'array'
|
|
127
|
+
| 'boolean'
|
|
128
|
+
| 'null'
|
|
129
|
+
| 'object'
|
|
130
|
+
| 'combined'
|
|
131
|
+
| 'unknown';
|
|
132
|
+
export type ApiSchemaAccessibility = 'all' | 'readOnly' | 'writeOnly' | 'none';
|
|
133
|
+
export type ApiSchemaProperty = {
|
|
134
|
+
name: string;
|
|
135
|
+
schema: ApiSchema;
|
|
136
|
+
};
|
|
137
|
+
export type ApiSchemaDiscriminator = {
|
|
138
|
+
propertyName: string;
|
|
139
|
+
mapping: Record<string, ApiSchema>;
|
|
140
|
+
};
|
|
141
|
+
export type ApiSchemaComponent = ApiComponent<OpenApiSchema>;
|
|
142
|
+
export type ApiSchemaBase = ApiSchemaComponent & {
|
|
143
|
+
name: string;
|
|
144
|
+
isNameGenerated: boolean;
|
|
145
|
+
description: string | undefined;
|
|
146
|
+
deprecated: boolean;
|
|
147
|
+
accessibility: ApiSchemaAccessibility;
|
|
148
|
+
enum: unknown[] | undefined;
|
|
149
|
+
const: unknown | undefined;
|
|
150
|
+
default: unknown | undefined;
|
|
151
|
+
example: unknown | undefined;
|
|
152
|
+
nullable: boolean;
|
|
153
|
+
required: Set<string>;
|
|
154
|
+
custom: Record<string, unknown>;
|
|
155
|
+
not: ApiSchema | undefined;
|
|
156
|
+
discriminator: ApiSchemaDiscriminator | undefined;
|
|
157
|
+
inheritedSchemas: (ApiSchema & { discriminator: NonNullable<ApiSchema['discriminator']> })[];
|
|
158
|
+
};
|
|
159
|
+
export type ApiSchema<T extends ApiSchemaKind = ApiSchemaKind> = ApiSchemaBase & ApiSchemaExtensions<T>;
|
|
160
|
+
type AdditionalCombinedSchemaProperties = {
|
|
161
|
+
allOf: ApiSchema[];
|
|
162
|
+
anyOf: ApiSchema[];
|
|
163
|
+
};
|
|
164
|
+
type AdditionalArraySchemaProperties = {
|
|
165
|
+
items: ApiSchema | undefined;
|
|
166
|
+
minItems: number | undefined;
|
|
167
|
+
maxItems: number | undefined;
|
|
168
|
+
};
|
|
169
|
+
type AdditionalObjectSchemaProperties = {
|
|
170
|
+
properties: Map<string, ApiSchemaProperty>;
|
|
171
|
+
additionalProperties: boolean | undefined | ApiSchema;
|
|
172
|
+
} & AdditionalCombinedSchemaProperties;
|
|
173
|
+
type AdditionalNumberSchemaProperties = {
|
|
174
|
+
minimum: number | undefined;
|
|
175
|
+
maximum: number | undefined;
|
|
176
|
+
};
|
|
177
|
+
type AdditionalStringSchemaProperties = {
|
|
178
|
+
pattern: string | undefined;
|
|
179
|
+
minLength: number | undefined;
|
|
180
|
+
maxLength: number | undefined;
|
|
181
|
+
};
|
|
182
|
+
type AdditionalPrimitiveSchemaProperties = {
|
|
183
|
+
format: string | undefined;
|
|
184
|
+
};
|
|
185
|
+
export type ApiSchemaExtensions<T extends ApiSchemaKind> = T extends 'oneOf' ? { kind: 'oneOf'; oneOf: ApiSchema[] }
|
|
186
|
+
: T extends 'multi-type' ?
|
|
187
|
+
& {
|
|
188
|
+
kind: 'multi-type';
|
|
189
|
+
type: ApiSchemaType[];
|
|
190
|
+
}
|
|
191
|
+
& AdditionalArraySchemaProperties
|
|
192
|
+
& AdditionalObjectSchemaProperties
|
|
193
|
+
& AdditionalNumberSchemaProperties
|
|
194
|
+
& AdditionalStringSchemaProperties
|
|
195
|
+
& AdditionalPrimitiveSchemaProperties
|
|
196
|
+
: T extends 'string'
|
|
197
|
+
? { kind: 'string'; type: 'string' } & AdditionalStringSchemaProperties & AdditionalPrimitiveSchemaProperties
|
|
198
|
+
: T extends 'boolean' ? { kind: 'boolean'; type: 'boolean' } & AdditionalPrimitiveSchemaProperties
|
|
199
|
+
: T extends 'null' ? { kind: 'null'; type: 'null' }
|
|
200
|
+
: T extends 'number' | 'integer'
|
|
201
|
+
? { kind: 'number' | 'integer'; type: T } & AdditionalNumberSchemaProperties & AdditionalPrimitiveSchemaProperties
|
|
202
|
+
: T extends 'array' ? {
|
|
203
|
+
kind: 'array';
|
|
204
|
+
type: 'array';
|
|
205
|
+
} & AdditionalArraySchemaProperties
|
|
206
|
+
: T extends 'object' ? {
|
|
207
|
+
kind: 'object';
|
|
208
|
+
type: 'object';
|
|
209
|
+
} & AdditionalObjectSchemaProperties
|
|
210
|
+
: T extends 'combined' ? {
|
|
211
|
+
kind: 'combined';
|
|
212
|
+
} & AdditionalCombinedSchemaProperties
|
|
213
|
+
: { kind: 'unknown' };
|
|
214
|
+
export type CombinedLikeApiSchema = ApiSchemaBase & {
|
|
215
|
+
kind: 'combined' | 'object' | 'multi-type';
|
|
216
|
+
type?: 'object' | string[];
|
|
217
|
+
} & AdditionalCombinedSchemaProperties;
|
|
218
|
+
export type NumberLikeApiSchema =
|
|
219
|
+
& ApiSchemaBase
|
|
220
|
+
& {
|
|
221
|
+
kind: 'number' | 'integer' | 'multi-type';
|
|
222
|
+
type: 'number' | 'integer' | string[];
|
|
223
|
+
}
|
|
224
|
+
& AdditionalNumberSchemaProperties
|
|
225
|
+
& AdditionalPrimitiveSchemaProperties;
|
|
226
|
+
export type ArrayLikeApiSchema = ApiSchemaBase & {
|
|
227
|
+
kind: 'array' | 'multi-type';
|
|
228
|
+
type: 'array' | string[];
|
|
229
|
+
} & AdditionalArraySchemaProperties;
|
|
230
|
+
export type ObjectLikeApiSchema = ApiSchemaBase & {
|
|
231
|
+
kind: 'object' | 'multi-type';
|
|
232
|
+
type: 'object' | string[];
|
|
233
|
+
} & AdditionalObjectSchemaProperties;
|
|
234
|
+
export type StringLikeApiSchema =
|
|
235
|
+
& ApiSchemaBase
|
|
236
|
+
& {
|
|
237
|
+
kind: 'string' | 'multi-type';
|
|
238
|
+
type: 'string' | string[];
|
|
239
|
+
}
|
|
240
|
+
& AdditionalStringSchemaProperties
|
|
241
|
+
& AdditionalPrimitiveSchemaProperties;
|
|
242
|
+
export type PrimitiveLikeApiSchema = ApiSchemaBase & {
|
|
243
|
+
kind: 'string' | 'number' | 'integer' | 'boolean' | 'null' | 'multi-type';
|
|
244
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'null' | string[];
|
|
245
|
+
} & AdditionalPrimitiveSchemaProperties;
|