@goast/core 0.2.2 → 0.3.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/README.md +65 -11
- package/cjs/lib/codegen/config.js +5 -1
- package/cjs/lib/codegen/generator.js +28 -35
- package/cjs/lib/codegen/internal-utils.js +1 -2
- package/cjs/lib/collect/collector.js +1 -2
- package/cjs/lib/collect/helpers.js +2 -3
- package/cjs/lib/internal-utils.js +1 -2
- package/cjs/lib/parse/deref-proxy.js +1 -2
- package/cjs/lib/parse/parser.js +114 -126
- package/cjs/lib/transform/helpers.js +10 -10
- package/cjs/lib/transform/transform-document.js +5 -3
- package/cjs/lib/transform/transform-endpoint.js +35 -10
- package/cjs/lib/transform/transform-schema.js +5 -3
- package/cjs/lib/transform/transformer.js +1 -2
- package/cjs/lib/utils/array.utils.js +1 -2
- package/cjs/lib/utils/class.utils.js +3 -4
- package/cjs/lib/utils/common.utils.js +12 -13
- package/cjs/lib/utils/condition.js +1 -2
- package/cjs/lib/utils/endpoint.utils.js +1 -2
- package/cjs/lib/utils/error.utils.js +1 -2
- package/cjs/lib/utils/file-system.utils.js +21 -26
- package/cjs/lib/utils/generator.utils.js +1 -2
- package/cjs/lib/utils/object.utils.js +1 -2
- package/cjs/lib/utils/schema.utils.js +12 -4
- package/cjs/lib/utils/source-builder.js +5 -3
- package/cjs/lib/utils/string-builder/options.js +3 -0
- package/cjs/lib/utils/string-builder/string-builder.js +1 -1
- package/cjs/lib/utils/string-builder/utils.js +5 -6
- package/cjs/lib/utils/string.utils.js +27 -28
- package/cjs/lib/utils/type.utils.js +2 -3
- package/esm/lib/codegen/config.js +5 -1
- package/esm/lib/codegen/generator.js +28 -35
- package/esm/lib/parse/parser.js +114 -127
- package/esm/lib/transform/transform-document.js +4 -1
- package/esm/lib/transform/transform-endpoint.js +34 -8
- package/esm/lib/transform/transform-schema.js +4 -1
- package/esm/lib/utils/file-system.utils.js +19 -24
- package/esm/lib/utils/schema.utils.js +10 -1
- package/esm/lib/utils/source-builder.js +6 -4
- package/esm/lib/utils/string-builder/options.js +3 -0
- package/esm/lib/utils/string-builder/string-builder.js +1 -1
- package/esm/lib/utils/string.utils.js +7 -7
- package/package.json +16 -5
- package/types/lib/codegen/config.d.ts +8 -0
- package/types/lib/utils/source-builder.d.ts +11 -1
- package/types/lib/utils/string-builder/options.d.ts +8 -2
- package/types/lib/utils/string.utils.types.d.ts +1 -0
|
@@ -5,7 +5,10 @@ export function transformEndpoint(context, endpointInfo) {
|
|
|
5
5
|
var _a, _b, _c, _d;
|
|
6
6
|
const apiPath = transformApiPath(context, endpointInfo.path, endpointInfo.pathItem);
|
|
7
7
|
const endpoint = {
|
|
8
|
-
$src:
|
|
8
|
+
$src: {
|
|
9
|
+
...endpointInfo.operation.$src,
|
|
10
|
+
component: endpointInfo.operation,
|
|
11
|
+
},
|
|
9
12
|
$ref: undefined,
|
|
10
13
|
id: context.idGenerator.generateId('endpoint'),
|
|
11
14
|
name: determineEndpointName(endpointInfo),
|
|
@@ -54,7 +57,10 @@ function transformApiPath(context, path, pathItem, isReference = false) {
|
|
|
54
57
|
return existing;
|
|
55
58
|
const ref = pathItem.$ref ? transformApiPath(context, path, pathItem.$ref, true) : undefined;
|
|
56
59
|
const apiPath = {
|
|
57
|
-
$src:
|
|
60
|
+
$src: {
|
|
61
|
+
...pathItem.$src,
|
|
62
|
+
component: pathItem,
|
|
63
|
+
},
|
|
58
64
|
$ref: ref,
|
|
59
65
|
id: context.idGenerator.generateId('path'),
|
|
60
66
|
summary: pathItem.summary,
|
|
@@ -85,7 +91,10 @@ function transformParameter(context, parameter) {
|
|
|
85
91
|
const ref = parameter.$ref ? transformParameter(context, parameter.$ref) : undefined;
|
|
86
92
|
const id = context.idGenerator.generateId('parameter');
|
|
87
93
|
const p = {
|
|
88
|
-
$src:
|
|
94
|
+
$src: {
|
|
95
|
+
...parameter.$src,
|
|
96
|
+
component: parameter,
|
|
97
|
+
},
|
|
89
98
|
$ref: ref,
|
|
90
99
|
id: id,
|
|
91
100
|
name: (_a = parameter.name) !== null && _a !== void 0 ? _a : id,
|
|
@@ -110,7 +119,10 @@ function transformRequestBody(context, requestBody) {
|
|
|
110
119
|
return existing;
|
|
111
120
|
const ref = requestBody.$ref ? transformRequestBody(context, requestBody.$ref) : undefined;
|
|
112
121
|
const rb = {
|
|
113
|
-
$src:
|
|
122
|
+
$src: {
|
|
123
|
+
...requestBody.$src,
|
|
124
|
+
component: requestBody,
|
|
125
|
+
},
|
|
114
126
|
$ref: ref,
|
|
115
127
|
id: context.idGenerator.generateId('requestBody'),
|
|
116
128
|
description: requestBody.description,
|
|
@@ -138,7 +150,10 @@ function transformResponse(context, response, status) {
|
|
|
138
150
|
return existing;
|
|
139
151
|
const ref = response.$ref ? transformResponse(context, response.$ref, status) : undefined;
|
|
140
152
|
const r = {
|
|
141
|
-
$src:
|
|
153
|
+
$src: {
|
|
154
|
+
...response.$src,
|
|
155
|
+
component: response,
|
|
156
|
+
},
|
|
142
157
|
$ref: ref,
|
|
143
158
|
id: context.idGenerator.generateId('response'),
|
|
144
159
|
statusCode: Number(status) || undefined,
|
|
@@ -167,7 +182,10 @@ function transformMediaType(context, mediaType, media) {
|
|
|
167
182
|
return existing;
|
|
168
183
|
const ref = mediaType.$ref ? transformMediaType(context, mediaType.$ref, media) : undefined;
|
|
169
184
|
const mt = {
|
|
170
|
-
$src:
|
|
185
|
+
$src: {
|
|
186
|
+
...mediaType.$src,
|
|
187
|
+
component: mediaType,
|
|
188
|
+
},
|
|
171
189
|
$ref: ref,
|
|
172
190
|
id: context.idGenerator.generateId('content'),
|
|
173
191
|
type: media,
|
|
@@ -214,7 +232,11 @@ function transformHeader(context, header, name) {
|
|
|
214
232
|
const id = context.idGenerator.generateId('header');
|
|
215
233
|
if (isSchema(header)) {
|
|
216
234
|
h = {
|
|
217
|
-
$src:
|
|
235
|
+
$src: {
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
237
|
+
...header.$src,
|
|
238
|
+
component: header,
|
|
239
|
+
},
|
|
218
240
|
$ref: ref,
|
|
219
241
|
id,
|
|
220
242
|
name,
|
|
@@ -230,7 +252,11 @@ function transformHeader(context, header, name) {
|
|
|
230
252
|
}
|
|
231
253
|
else {
|
|
232
254
|
h = {
|
|
233
|
-
$src:
|
|
255
|
+
$src: {
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
257
|
+
...header.$src,
|
|
258
|
+
component: header,
|
|
259
|
+
},
|
|
234
260
|
$ref: ref,
|
|
235
261
|
id,
|
|
236
262
|
name,
|
|
@@ -36,7 +36,10 @@ export function transformSchema(context, schema) {
|
|
|
36
36
|
const id = context.idGenerator.generateId('schema');
|
|
37
37
|
const nameInfo = determineSchemaName(schema, id);
|
|
38
38
|
const incompleteSchema = {
|
|
39
|
-
$src:
|
|
39
|
+
$src: {
|
|
40
|
+
...schema.$src,
|
|
41
|
+
component: schema,
|
|
42
|
+
},
|
|
40
43
|
$ref: undefined,
|
|
41
44
|
id,
|
|
42
45
|
name: nameInfo.name,
|
|
@@ -1,36 +1,31 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
1
|
import { resolve } from 'path';
|
|
3
2
|
import { lstat, readdir } from 'fs-extra';
|
|
4
3
|
export const defaultDirectoryScanOptions = {
|
|
5
4
|
recursive: false,
|
|
6
5
|
maxDepth: 5,
|
|
7
6
|
};
|
|
8
|
-
export function getFiles(dir, options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return files;
|
|
14
|
-
});
|
|
7
|
+
export async function getFiles(dir, options) {
|
|
8
|
+
const opts = { ...defaultDirectoryScanOptions, ...options };
|
|
9
|
+
const files = [];
|
|
10
|
+
await getFilesImpl(dir, opts, files, 0);
|
|
11
|
+
return files;
|
|
15
12
|
}
|
|
16
|
-
function getFilesImpl(dir, options, files, currentDepth) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
if (options.
|
|
24
|
-
|
|
25
|
-
getFilesImpl(filePath, options, files, currentDepth + 1);
|
|
26
|
-
}
|
|
13
|
+
async function getFilesImpl(dir, options, files, currentDepth) {
|
|
14
|
+
const dirFiles = await readdir(dir);
|
|
15
|
+
for (const file of dirFiles) {
|
|
16
|
+
const filePath = resolve(dir, file);
|
|
17
|
+
const stat = await lstat(filePath);
|
|
18
|
+
if (stat.isDirectory()) {
|
|
19
|
+
if (options.recursive) {
|
|
20
|
+
if (options.maxDepth && options.maxDepth > currentDepth) {
|
|
21
|
+
getFilesImpl(filePath, options, files, currentDepth + 1);
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (!options.filter || options.filter(file)) {
|
|
27
|
+
files.push(filePath);
|
|
33
28
|
}
|
|
34
29
|
}
|
|
35
|
-
}
|
|
30
|
+
}
|
|
36
31
|
}
|
|
@@ -14,7 +14,16 @@ export function resolveAnyOfAndAllOf(schema, ignoreNonObjectParts) {
|
|
|
14
14
|
if (properties.size === 0 && initialAdditionalProperties === additionalProperties) {
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
|
-
return
|
|
17
|
+
return {
|
|
18
|
+
...schema,
|
|
19
|
+
kind: 'object',
|
|
20
|
+
type: 'object',
|
|
21
|
+
anyOf: [],
|
|
22
|
+
allOf: [],
|
|
23
|
+
properties: properties,
|
|
24
|
+
required: required,
|
|
25
|
+
additionalProperties,
|
|
26
|
+
};
|
|
18
27
|
}
|
|
19
28
|
function collectSubSchemaProperties(subSchemas, properties, required, optional) {
|
|
20
29
|
for (const subSchema of subSchemas) {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { EOL } from 'os';
|
|
2
1
|
import { isNullish } from './common.utils';
|
|
3
2
|
import { evalCondition } from './condition';
|
|
4
|
-
import { StringBuilder } from './string-builder';
|
|
3
|
+
import { defaultStringBuilderOptions, StringBuilder, } from './string-builder';
|
|
5
4
|
import { removeStr, trimEnd } from './string.utils';
|
|
5
|
+
/**
|
|
6
|
+
* Default options for the `SourceBuilder` class.
|
|
7
|
+
*/
|
|
6
8
|
export const defaultSourceBuilderOptions = {
|
|
9
|
+
...defaultStringBuilderOptions,
|
|
7
10
|
indent: { type: 'spaces', count: 2 },
|
|
8
|
-
newLine: EOL,
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* Represents an in-memory source file.
|
|
@@ -27,7 +29,7 @@ export class SourceBuilder extends StringBuilder {
|
|
|
27
29
|
this._isLastLineEmpty = true;
|
|
28
30
|
this._isCurrentLineEmpty = true;
|
|
29
31
|
this._linePrefixNodes = [];
|
|
30
|
-
this.__options =
|
|
32
|
+
this.__options = { ...defaultSourceBuilderOptions, ...options };
|
|
31
33
|
this._indentString = this.__options.indent.type === 'tabs' ? '\t' : ' '.repeat(this.__options.indent.count);
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
@@ -17,7 +17,7 @@ export class StringBuilder {
|
|
|
17
17
|
*/
|
|
18
18
|
constructor(options) {
|
|
19
19
|
this.str = '';
|
|
20
|
-
this._options =
|
|
20
|
+
this._options = { ...defaultStringBuilderOptions, ...options };
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Creates a new StringBuilder instance and appends the specified string to it.
|
|
@@ -5,14 +5,14 @@ export function adjustCasing(a, b) {
|
|
|
5
5
|
return b;
|
|
6
6
|
}
|
|
7
7
|
else {
|
|
8
|
-
return
|
|
8
|
+
return { casing: a, ...b };
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
else if (typeof b === 'string') {
|
|
12
|
-
return
|
|
12
|
+
return { ...a, casing: b };
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
|
-
return
|
|
15
|
+
return { ...a, ...b };
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
export function lowercase(str) {
|
|
@@ -140,7 +140,7 @@ function addPrefixAndSuffix(str, { prefix, suffix }) {
|
|
|
140
140
|
* toCamelCase('Foo bAR', { suffix: 'bar' }) // => 'fooBarbar'
|
|
141
141
|
*/
|
|
142
142
|
export function toCamelCase(str, options) {
|
|
143
|
-
const opts =
|
|
143
|
+
const opts = { keepOriginalCase: false, ...options };
|
|
144
144
|
const words = getWords(str);
|
|
145
145
|
const camelCase = words
|
|
146
146
|
.map((word, index) => index === 0
|
|
@@ -162,7 +162,7 @@ export function toCamelCase(str, options) {
|
|
|
162
162
|
* toPascalCase('foo bAR', { suffix: 'bar' }) // => 'FooBarbar'
|
|
163
163
|
*/
|
|
164
164
|
export function toPascalCase(str, options) {
|
|
165
|
-
const opts =
|
|
165
|
+
const opts = { keepOriginalCase: false, ...options };
|
|
166
166
|
const words = getWords(str);
|
|
167
167
|
const pascalCase = words
|
|
168
168
|
.map((word) => wordToCasing(word, opts.keepOriginalCase ? 'first-upper' : 'first-upper-then-lower'))
|
|
@@ -183,7 +183,7 @@ export function toPascalCase(str, options) {
|
|
|
183
183
|
* toKebabCase('Foo bAR', { suffix: 'bar' }) // => 'foo-barbar'
|
|
184
184
|
*/
|
|
185
185
|
export function toKebabCase(str, options) {
|
|
186
|
-
const opts =
|
|
186
|
+
const opts = { wordCasing: 'all-lower', ...options };
|
|
187
187
|
const words = getWords(str);
|
|
188
188
|
const kebabCase = words
|
|
189
189
|
.map((word, index) => { var _a; return index === 0 ? wordToCasing(word, (_a = opts.firstWordCasing) !== null && _a !== void 0 ? _a : opts.wordCasing) : wordToCasing(word, opts.wordCasing); })
|
|
@@ -204,7 +204,7 @@ export function toKebabCase(str, options) {
|
|
|
204
204
|
* toSnakeCase('Foo bAR', { suffix: 'bar' }) // => 'FOO_BARbar'
|
|
205
205
|
*/
|
|
206
206
|
export function toSnakeCase(str, options) {
|
|
207
|
-
const opts =
|
|
207
|
+
const opts = { wordCasing: 'all-upper', ...options };
|
|
208
208
|
const words = getWords(str);
|
|
209
209
|
const snakeCase = words
|
|
210
210
|
.map((word, index) => { var _a; return index === 0 ? wordToCasing(word, (_a = opts.firstWordCasing) !== null && _a !== void 0 ? _a : opts.wordCasing) : wordToCasing(word, opts.wordCasing); })
|
package/package.json
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goast/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"repository": "https://github.com/MaSch0212/goast.git",
|
|
5
|
+
"description": "A tool designed to transform OpenAPI specifications into various forms with flexibility and extensibility at its core.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"goast",
|
|
8
|
+
"openapi",
|
|
9
|
+
"swagger",
|
|
10
|
+
"api",
|
|
11
|
+
"generator",
|
|
12
|
+
"transformer",
|
|
13
|
+
"schema"
|
|
14
|
+
],
|
|
5
15
|
"author": {
|
|
6
16
|
"name": "Marc Schmidt (MaSch0212)",
|
|
7
17
|
"url": "https://github.com/MaSch0212"
|
|
@@ -10,10 +20,11 @@
|
|
|
10
20
|
"type": "module",
|
|
11
21
|
"dependencies": {
|
|
12
22
|
"fs-extra": "^11.2.0",
|
|
13
|
-
"node-fetch": "^
|
|
14
|
-
"yaml": "^2.4.
|
|
15
|
-
"tslib": "2.6.
|
|
23
|
+
"node-fetch": "^3.3.2",
|
|
24
|
+
"yaml": "^2.4.5",
|
|
25
|
+
"tslib": "2.6.3"
|
|
16
26
|
},
|
|
27
|
+
"packageManager": "pnpm@9.5.0",
|
|
17
28
|
"module": "./esm/index.js",
|
|
18
29
|
"main": "./cjs/index.js",
|
|
19
30
|
"types": "./types/index.d.ts",
|
|
@@ -30,4 +41,4 @@
|
|
|
30
41
|
},
|
|
31
42
|
"./package.json": "./package.json"
|
|
32
43
|
}
|
|
33
|
-
}
|
|
44
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { SourceBuilderOptions } from '../utils/source-builder';
|
|
2
2
|
export type OpenApiGeneratorConfig = SourceBuilderOptions & {
|
|
3
|
+
/**
|
|
4
|
+
* The directory where the generated files should be saved.
|
|
5
|
+
* @default 'generated'
|
|
6
|
+
*/
|
|
3
7
|
outputDir: string;
|
|
8
|
+
/**
|
|
9
|
+
* Whether to clear the output directory before generating the files.
|
|
10
|
+
* @default true
|
|
11
|
+
*/
|
|
4
12
|
clearOutputDir: boolean;
|
|
5
13
|
};
|
|
6
14
|
export declare const defaultOpenApiGeneratorConfig: OpenApiGeneratorConfig;
|
|
@@ -8,9 +8,19 @@ export type IndentOptions = {
|
|
|
8
8
|
readonly type: 'spaces';
|
|
9
9
|
readonly count: number;
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Options for the `SourceBuilder` class.
|
|
13
|
+
*/
|
|
11
14
|
export type SourceBuilderOptions = StringBuilderOptions & {
|
|
15
|
+
/**
|
|
16
|
+
* The type of indentation to use.
|
|
17
|
+
* @default { type: 'spaces', count: 2 }
|
|
18
|
+
*/
|
|
12
19
|
indent: IndentOptions;
|
|
13
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Default options for the `SourceBuilder` class.
|
|
23
|
+
*/
|
|
14
24
|
export declare const defaultSourceBuilderOptions: SourceBuilderOptions;
|
|
15
25
|
type KnownParatheses = '()' | '[]' | '{}' | '<>';
|
|
16
26
|
export type Paratheses<TBuilder extends StringBuilder> = KnownParatheses | Omit<string, KnownParatheses> | [open: Nullable<AppendValue<TBuilder>>, close: Nullable<AppendValue<TBuilder>>];
|
|
@@ -216,6 +226,6 @@ export declare class SourceBuilder<TAdditionalAppends = never> extends StringBui
|
|
|
216
226
|
}
|
|
217
227
|
declare function _builderTemplate<T extends SourceBuilder>(template: readonly string[] | ArrayLike<string>, ...substitutions: AppendValue<T>[]): BuilderFn<T>;
|
|
218
228
|
export declare const builderTemplate: typeof _builderTemplate & {
|
|
219
|
-
indent: <T extends SourceBuilder
|
|
229
|
+
indent: <T extends SourceBuilder>(template: readonly string[] | ArrayLike<string>, ...substitutions: AppendValue<T>[]) => BuilderFn<T>;
|
|
220
230
|
};
|
|
221
231
|
export {};
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Options for the StringBuilder class.
|
|
3
|
-
* @default newLine = os.EOL
|
|
2
|
+
* Options for the `StringBuilder` class.
|
|
4
3
|
*/
|
|
5
4
|
export type StringBuilderOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* The string to use for new lines.
|
|
7
|
+
* @default os.EOL
|
|
8
|
+
*/
|
|
6
9
|
readonly newLine: string;
|
|
7
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Default options for the `StringBuilder` class.
|
|
13
|
+
*/
|
|
8
14
|
export declare const defaultStringBuilderOptions: StringBuilderOptions;
|
|
@@ -33,6 +33,7 @@ export type StringCasing = WordCasing | 'camel' | 'pascal' | 'kebab' | 'snake' |
|
|
|
33
33
|
export type StringCasingWithOptions<T extends StringCasing = StringCasing> = {
|
|
34
34
|
casing: T;
|
|
35
35
|
} & CaseOptions<T>;
|
|
36
|
+
export type ExtendedStringCasing = StringCasing | StringCasingWithOptions;
|
|
36
37
|
export type CaseOptions<T extends StringCasing> = T extends 'camel' ? Partial<CamelCaseOptions> : T extends 'pascal' ? Partial<PascalCaseOptions> : T extends 'kebab' ? Partial<KebabCaseOptions> : T extends 'snake' ? Partial<SnakeCaseOptions> : T extends 'custom' ? CustomCaseOptions : never;
|
|
37
38
|
export type BaseCaseOptions = {
|
|
38
39
|
/**
|