@goast/core 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/src/parse/deref-proxy.js +7 -1
- package/esm/src/parse/parser.d.ts +1 -2
- package/esm/src/parse/parser.d.ts.map +1 -1
- package/esm/src/parse/parser.js +15 -38
- package/esm/src/parse/types.d.ts +5 -1
- package/esm/src/parse/types.d.ts.map +1 -1
- package/esm/src/transform/helpers.d.ts.map +1 -1
- package/esm/src/transform/helpers.js +2 -1
- package/esm/src/utils/yaml-info.d.ts +13 -0
- package/esm/src/utils/yaml-info.d.ts.map +1 -0
- package/esm/src/utils/yaml-info.js +31 -0
- package/package.json +1 -1
- package/script/src/parse/deref-proxy.js +7 -1
- package/script/src/parse/parser.d.ts +1 -2
- package/script/src/parse/parser.d.ts.map +1 -1
- package/script/src/parse/parser.js +15 -38
- package/script/src/parse/types.d.ts +5 -1
- package/script/src/parse/types.d.ts.map +1 -1
- package/script/src/transform/helpers.d.ts.map +1 -1
- package/script/src/transform/helpers.js +2 -1
- package/script/src/utils/yaml-info.d.ts +13 -0
- package/script/src/utils/yaml-info.d.ts.map +1 -0
- package/script/src/utils/yaml-info.js +38 -0
- package/src/src/parse/deref-proxy.ts +7 -1
- package/src/src/parse/parser.ts +20 -40
- package/src/src/parse/types.ts +2 -1
- package/src/src/transform/helpers.ts +2 -1
- package/src/src/utils/yaml-info.ts +48 -0
|
@@ -57,6 +57,12 @@ class DerefProxyHandler {
|
|
|
57
57
|
return prop in target || (!isNullish(this._ref) && prop in this._ref);
|
|
58
58
|
}
|
|
59
59
|
ownKeys(target) {
|
|
60
|
-
return Array.from(new Set([
|
|
60
|
+
return Array.from(new Set([
|
|
61
|
+
...Object.getOwnPropertyNames(target),
|
|
62
|
+
...Object.getOwnPropertySymbols(target),
|
|
63
|
+
...(!isNullish(this._ref) ? Object.keys(this._ref) : []),
|
|
64
|
+
'$ref',
|
|
65
|
+
'$src',
|
|
66
|
+
]));
|
|
61
67
|
}
|
|
62
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/src/parse/parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/src/parse/parser.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,KAAK,EAAE,eAAe,EAAkD,MAAM,oBAAoB,CAAC;AAC1G,OAAO,EAA+B,KAAK,KAAK,EAAE,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAShG,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqC;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;gBAEnC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAIrC,qBAAqB,CAAC,GAAG,SAAS,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAS5E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAMjE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,OAAO;YAM/C,WAAW;YA4DX,gBAAgB;YAuBhB,YAAY;YAgCZ,kBAAkB;IAYhC,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,kBAAkB;CAO3B"}
|
package/esm/src/parse/parser.js
CHANGED
|
@@ -2,10 +2,10 @@ import * as dntShim from "../../_dnt.shims.js";
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { cwd } from 'node:process';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
|
-
import * as YAML from 'yaml';
|
|
6
5
|
import { collectOpenApi } from '../collect/collector.js';
|
|
7
6
|
import { transformOpenApi } from '../transform/transformer.js';
|
|
8
7
|
import { isNullish } from '../utils/common.utils.js';
|
|
8
|
+
import { getLineInfo, parseYamlWithInfo } from '../utils/yaml-info.js';
|
|
9
9
|
import { createDerefProxy } from './deref-proxy.js';
|
|
10
10
|
import { defaultOpenApiParserOptions } from './types.js';
|
|
11
11
|
export class OpenApiParser {
|
|
@@ -33,7 +33,7 @@ export class OpenApiParser {
|
|
|
33
33
|
async parseApi(fileName) {
|
|
34
34
|
const absoluteFilePath = this.isUrl(fileName) ? fileName : path.resolve(cwd(), fileName);
|
|
35
35
|
const doc = await this.loadDocument(absoluteFilePath);
|
|
36
|
-
return await this.dereference(absoluteFilePath,
|
|
36
|
+
return await this.dereference(absoluteFilePath, [], doc.document);
|
|
37
37
|
}
|
|
38
38
|
transformApis(apis) {
|
|
39
39
|
const collectedData = collectOpenApi(apis);
|
|
@@ -41,9 +41,10 @@ export class OpenApiParser {
|
|
|
41
41
|
return transformedData;
|
|
42
42
|
}
|
|
43
43
|
async dereference(file, path, value) {
|
|
44
|
+
const openApiPath = `/${path.join('/')}`;
|
|
44
45
|
let existingDocument = this._loadedDocuments.get(file);
|
|
45
46
|
if (existingDocument) {
|
|
46
|
-
const existingComponent = existingDocument.dereferencedComponents.get(
|
|
47
|
+
const existingComponent = existingDocument.dereferencedComponents.get(openApiPath);
|
|
47
48
|
if (existingComponent) {
|
|
48
49
|
return existingComponent;
|
|
49
50
|
}
|
|
@@ -53,11 +54,12 @@ export class OpenApiParser {
|
|
|
53
54
|
}
|
|
54
55
|
const result = createDerefProxy(value, {
|
|
55
56
|
file,
|
|
56
|
-
path,
|
|
57
|
+
pos: getLineInfo(existingDocument.document, path),
|
|
58
|
+
path: openApiPath,
|
|
57
59
|
document: existingDocument.dereferencedDocument,
|
|
58
60
|
originalComponent: value,
|
|
59
61
|
});
|
|
60
|
-
existingDocument.dereferencedComponents.set(
|
|
62
|
+
existingDocument.dereferencedComponents.set(openApiPath, result);
|
|
61
63
|
if (value.$ref) {
|
|
62
64
|
// deno-lint-ignore no-explicit-any
|
|
63
65
|
result.$ref = await this.resolveReference(file, value);
|
|
@@ -72,7 +74,7 @@ export class OpenApiParser {
|
|
|
72
74
|
if (Array.isArray(v)) {
|
|
73
75
|
result[key] = await Promise.all(v.map(async (v, index) => {
|
|
74
76
|
if (v && typeof v === 'object') {
|
|
75
|
-
return await this.dereference(file,
|
|
77
|
+
return await this.dereference(file, [...path, key, index], v);
|
|
76
78
|
}
|
|
77
79
|
else {
|
|
78
80
|
return v;
|
|
@@ -80,10 +82,10 @@ export class OpenApiParser {
|
|
|
80
82
|
}));
|
|
81
83
|
}
|
|
82
84
|
else {
|
|
83
|
-
result[key] = await this.dereference(file,
|
|
85
|
+
result[key] = await this.dereference(file, [...path, key], v);
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
|
-
if (typeof v === 'string' &&
|
|
88
|
+
if (typeof v === 'string' && openApiPath.endsWith('/discriminator/mapping')) {
|
|
87
89
|
result[key] = await this.resolveReference(file, { $ref: v });
|
|
88
90
|
}
|
|
89
91
|
}
|
|
@@ -101,7 +103,7 @@ export class OpenApiParser {
|
|
|
101
103
|
const doc = await this.loadDocument(absoluteRefFile);
|
|
102
104
|
const value = refPath ? getDeepProperty(doc.document, refPath.replace(/[/]/g, '.')) : doc.document;
|
|
103
105
|
if (value && typeof value === 'object') {
|
|
104
|
-
return this.dereference(absoluteRefFile, refPath
|
|
106
|
+
return this.dereference(absoluteRefFile, refPath.split('/').filter(Boolean), value);
|
|
105
107
|
}
|
|
106
108
|
return undefined;
|
|
107
109
|
}
|
|
@@ -111,26 +113,14 @@ export class OpenApiParser {
|
|
|
111
113
|
return existingDocument;
|
|
112
114
|
}
|
|
113
115
|
const documentContent = await this.getDocumentContent(fileOrUrl);
|
|
114
|
-
const
|
|
115
|
-
let parsedDocument;
|
|
116
|
-
if (extname === '.json') {
|
|
117
|
-
parsedDocument = this.tryParseJson(documentContent);
|
|
118
|
-
}
|
|
119
|
-
else if (extname === '.yaml' || extname === '.yml') {
|
|
120
|
-
parsedDocument = this.tryParseYaml(documentContent);
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
parsedDocument = this.tryParseJson(documentContent);
|
|
124
|
-
if (parsedDocument !== undefined) {
|
|
125
|
-
parsedDocument = this.tryParseYaml(documentContent);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
116
|
+
const parsedDocument = this.tryParseYamlOrJson(documentContent);
|
|
128
117
|
if (parsedDocument === undefined) {
|
|
129
118
|
throw new Error(`Unable to parse ${fileOrUrl}`);
|
|
130
119
|
}
|
|
131
120
|
const doc = (parsedDocument !== null && parsedDocument !== void 0 ? parsedDocument : {});
|
|
132
121
|
const deref = createDerefProxy(doc, {
|
|
133
122
|
file: fileOrUrl,
|
|
123
|
+
pos: { line: 0, col: 0 },
|
|
134
124
|
path: '',
|
|
135
125
|
originalComponent: doc,
|
|
136
126
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -161,17 +151,9 @@ export class OpenApiParser {
|
|
|
161
151
|
isUrl(fileOrUrl) {
|
|
162
152
|
return /^https?:\/\//i.test(fileOrUrl);
|
|
163
153
|
}
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
return JSON.parse(json);
|
|
167
|
-
}
|
|
168
|
-
catch (_a) {
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
tryParseYaml(yaml) {
|
|
154
|
+
tryParseYamlOrJson(yamlOrJson) {
|
|
173
155
|
try {
|
|
174
|
-
return
|
|
156
|
+
return parseYamlWithInfo(yamlOrJson);
|
|
175
157
|
}
|
|
176
158
|
catch (_a) {
|
|
177
159
|
return undefined;
|
|
@@ -193,8 +175,3 @@ function getDeepProperty(value, path) {
|
|
|
193
175
|
}
|
|
194
176
|
return result;
|
|
195
177
|
}
|
|
196
|
-
function joinPaths(...paths) {
|
|
197
|
-
return paths
|
|
198
|
-
.map((p) => String(p).replace(/\/$/, ''))
|
|
199
|
-
.join('/');
|
|
200
|
-
}
|
package/esm/src/parse/types.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
2
1
|
import { type OpenApiTransformerOptions } from '../transform/types.js';
|
|
2
|
+
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
3
3
|
export type DerefSource<T> = {
|
|
4
4
|
file: string;
|
|
5
|
+
pos: {
|
|
6
|
+
line: number;
|
|
7
|
+
col: number;
|
|
8
|
+
};
|
|
5
9
|
path: string;
|
|
6
10
|
document: Deref<OpenApiDocument>;
|
|
7
11
|
originalComponent: T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/parse/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/parse/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACzG,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACjC,iBAAiB,EAAE,CAAC,CAAC;CACtB,CAAC;AAEF,KAAK,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;CAChD,CAAC;AACF,KAAK,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,oBAAoB,GAAG,mBAAmB,GAE9E;KACC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,gBAAgB,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5E,GACC;IACA,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CACjB,CAAC;AACN,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAE/F,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE7D,eAAO,MAAM,2BAA2B;;CAA0C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/src/transform/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/src/transform/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { parse as parsePath } from 'node:path';
|
|
|
2
2
|
import { isOpenApiObjectProperty } from '../internal-utils.js';
|
|
3
3
|
import { isNullish } from '../utils/common.utils.js';
|
|
4
4
|
import { getDeepProperty } from '../utils/object.utils.js';
|
|
5
|
+
import { getLineInfo } from '../utils/yaml-info.js';
|
|
5
6
|
export function determineSchemaKind(ctx, schema) {
|
|
6
7
|
if (schema.oneOf) {
|
|
7
8
|
return 'oneOf';
|
|
@@ -50,7 +51,6 @@ export function determineSchemaName(schema, id) {
|
|
|
50
51
|
if (responseMatch && responseMatch.groups) {
|
|
51
52
|
const { path, method, status } = responseMatch.groups;
|
|
52
53
|
const operation = (_c = (_b = (_a = schema.$src.document.paths) === null || _a === void 0 ? void 0 : _a[path]) === null || _b === void 0 ? void 0 : _b[method]) !== null && _c !== void 0 ? _c : {};
|
|
53
|
-
console.log('responseMatch', responseMatch.groups, operation);
|
|
54
54
|
return {
|
|
55
55
|
name: `${determineEndpointName({ method, path: `/${path}`, operation })}_${status}_Response`,
|
|
56
56
|
isGenerated: true,
|
|
@@ -80,6 +80,7 @@ export function determineSchemaName(schema, id) {
|
|
|
80
80
|
: undefined,
|
|
81
81
|
$src: {
|
|
82
82
|
file: schema.$src.file,
|
|
83
|
+
pos: getLineInfo(schema.$src.document, parentSchemaMatch[1].split('/').filter(Boolean)),
|
|
83
84
|
path: parentSchemaMatch[1],
|
|
84
85
|
document: schema.$src.document,
|
|
85
86
|
originalComponent: parentSchema,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as YAML from 'yaml';
|
|
2
|
+
export declare const yamlInfoSymbol: unique symbol;
|
|
3
|
+
export type YamlInfo = {
|
|
4
|
+
document: YAML.Document.Parsed;
|
|
5
|
+
lineCounter: YAML.LineCounter;
|
|
6
|
+
};
|
|
7
|
+
export declare function getYamlInfo(obj: unknown): YamlInfo;
|
|
8
|
+
export declare function getLineInfo(obj: unknown, path: unknown[]): {
|
|
9
|
+
line: number;
|
|
10
|
+
col: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function parseYamlWithInfo(yamlString: string): unknown;
|
|
13
|
+
//# sourceMappingURL=yaml-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-info.d.ts","sourceRoot":"","sources":["../../../src/src/utils/yaml-info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,eAAO,MAAM,cAAc,eAAqB,CAAC;AAMjD,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC/B,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC;CAC/B,CAAC;AAEF,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAMlD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAiBxF;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAO7D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as YAML from 'yaml';
|
|
2
|
+
export const yamlInfoSymbol = Symbol('yamlInfo');
|
|
3
|
+
export function getYamlInfo(obj) {
|
|
4
|
+
const yamlInfo = obj[yamlInfoSymbol];
|
|
5
|
+
if (!yamlInfo) {
|
|
6
|
+
throw new Error('No YAML info found on object');
|
|
7
|
+
}
|
|
8
|
+
return yamlInfo;
|
|
9
|
+
}
|
|
10
|
+
export function getLineInfo(obj, path) {
|
|
11
|
+
var _a;
|
|
12
|
+
const yamlInfo = getYamlInfo(obj);
|
|
13
|
+
const node = (_a = yamlInfo.document.getIn(path, true)) !== null && _a !== void 0 ? _a : yamlInfo.document.getIn(path.map((v) => {
|
|
14
|
+
const num = Number(v);
|
|
15
|
+
return isNaN(num) ? v : num;
|
|
16
|
+
}), true);
|
|
17
|
+
if (!node || typeof node !== 'object' || !('range' in node) || !Array.isArray(node.range) ||
|
|
18
|
+
typeof node.range[0] !== 'number') {
|
|
19
|
+
console.warn(`Unable to get line info for path ${path.join('/')}`);
|
|
20
|
+
return { line: 0, col: 0 };
|
|
21
|
+
}
|
|
22
|
+
return yamlInfo.lineCounter.linePos(node.range[0]);
|
|
23
|
+
}
|
|
24
|
+
export function parseYamlWithInfo(yamlString) {
|
|
25
|
+
const lineCounter = new YAML.LineCounter();
|
|
26
|
+
const document = YAML.parseDocument(yamlString, { lineCounter });
|
|
27
|
+
return Object.defineProperty(document.toJS(), yamlInfoSymbol, {
|
|
28
|
+
value: { document, lineCounter },
|
|
29
|
+
enumerable: false,
|
|
30
|
+
});
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -60,6 +60,12 @@ class DerefProxyHandler {
|
|
|
60
60
|
return prop in target || (!(0, common_utils_js_1.isNullish)(this._ref) && prop in this._ref);
|
|
61
61
|
}
|
|
62
62
|
ownKeys(target) {
|
|
63
|
-
return Array.from(new Set([
|
|
63
|
+
return Array.from(new Set([
|
|
64
|
+
...Object.getOwnPropertyNames(target),
|
|
65
|
+
...Object.getOwnPropertySymbols(target),
|
|
66
|
+
...(!(0, common_utils_js_1.isNullish)(this._ref) ? Object.keys(this._ref) : []),
|
|
67
|
+
'$ref',
|
|
68
|
+
'$src',
|
|
69
|
+
]));
|
|
64
70
|
}
|
|
65
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/src/parse/parser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/src/parse/parser.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,KAAK,EAAE,eAAe,EAAkD,MAAM,oBAAoB,CAAC;AAC1G,OAAO,EAA+B,KAAK,KAAK,EAAE,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAShG,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqC;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;gBAEnC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAIrC,qBAAqB,CAAC,GAAG,SAAS,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAS5E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAMjE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,OAAO;YAM/C,WAAW;YA4DX,gBAAgB;YAuBhB,YAAY;YAgCZ,kBAAkB;IAYhC,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,kBAAkB;CAO3B"}
|
|
@@ -6,10 +6,10 @@ const dntShim = tslib_1.__importStar(require("../../_dnt.shims.js"));
|
|
|
6
6
|
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
7
7
|
const node_process_1 = require("node:process");
|
|
8
8
|
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
9
|
-
const YAML = tslib_1.__importStar(require("yaml"));
|
|
10
9
|
const collector_js_1 = require("../collect/collector.js");
|
|
11
10
|
const transformer_js_1 = require("../transform/transformer.js");
|
|
12
11
|
const common_utils_js_1 = require("../utils/common.utils.js");
|
|
12
|
+
const yaml_info_js_1 = require("../utils/yaml-info.js");
|
|
13
13
|
const deref_proxy_js_1 = require("./deref-proxy.js");
|
|
14
14
|
const types_js_1 = require("./types.js");
|
|
15
15
|
class OpenApiParser {
|
|
@@ -37,7 +37,7 @@ class OpenApiParser {
|
|
|
37
37
|
async parseApi(fileName) {
|
|
38
38
|
const absoluteFilePath = this.isUrl(fileName) ? fileName : node_path_1.default.resolve((0, node_process_1.cwd)(), fileName);
|
|
39
39
|
const doc = await this.loadDocument(absoluteFilePath);
|
|
40
|
-
return await this.dereference(absoluteFilePath,
|
|
40
|
+
return await this.dereference(absoluteFilePath, [], doc.document);
|
|
41
41
|
}
|
|
42
42
|
transformApis(apis) {
|
|
43
43
|
const collectedData = (0, collector_js_1.collectOpenApi)(apis);
|
|
@@ -45,9 +45,10 @@ class OpenApiParser {
|
|
|
45
45
|
return transformedData;
|
|
46
46
|
}
|
|
47
47
|
async dereference(file, path, value) {
|
|
48
|
+
const openApiPath = `/${path.join('/')}`;
|
|
48
49
|
let existingDocument = this._loadedDocuments.get(file);
|
|
49
50
|
if (existingDocument) {
|
|
50
|
-
const existingComponent = existingDocument.dereferencedComponents.get(
|
|
51
|
+
const existingComponent = existingDocument.dereferencedComponents.get(openApiPath);
|
|
51
52
|
if (existingComponent) {
|
|
52
53
|
return existingComponent;
|
|
53
54
|
}
|
|
@@ -57,11 +58,12 @@ class OpenApiParser {
|
|
|
57
58
|
}
|
|
58
59
|
const result = (0, deref_proxy_js_1.createDerefProxy)(value, {
|
|
59
60
|
file,
|
|
60
|
-
path,
|
|
61
|
+
pos: (0, yaml_info_js_1.getLineInfo)(existingDocument.document, path),
|
|
62
|
+
path: openApiPath,
|
|
61
63
|
document: existingDocument.dereferencedDocument,
|
|
62
64
|
originalComponent: value,
|
|
63
65
|
});
|
|
64
|
-
existingDocument.dereferencedComponents.set(
|
|
66
|
+
existingDocument.dereferencedComponents.set(openApiPath, result);
|
|
65
67
|
if (value.$ref) {
|
|
66
68
|
// deno-lint-ignore no-explicit-any
|
|
67
69
|
result.$ref = await this.resolveReference(file, value);
|
|
@@ -76,7 +78,7 @@ class OpenApiParser {
|
|
|
76
78
|
if (Array.isArray(v)) {
|
|
77
79
|
result[key] = await Promise.all(v.map(async (v, index) => {
|
|
78
80
|
if (v && typeof v === 'object') {
|
|
79
|
-
return await this.dereference(file,
|
|
81
|
+
return await this.dereference(file, [...path, key, index], v);
|
|
80
82
|
}
|
|
81
83
|
else {
|
|
82
84
|
return v;
|
|
@@ -84,10 +86,10 @@ class OpenApiParser {
|
|
|
84
86
|
}));
|
|
85
87
|
}
|
|
86
88
|
else {
|
|
87
|
-
result[key] = await this.dereference(file,
|
|
89
|
+
result[key] = await this.dereference(file, [...path, key], v);
|
|
88
90
|
}
|
|
89
91
|
}
|
|
90
|
-
if (typeof v === 'string' &&
|
|
92
|
+
if (typeof v === 'string' && openApiPath.endsWith('/discriminator/mapping')) {
|
|
91
93
|
result[key] = await this.resolveReference(file, { $ref: v });
|
|
92
94
|
}
|
|
93
95
|
}
|
|
@@ -105,7 +107,7 @@ class OpenApiParser {
|
|
|
105
107
|
const doc = await this.loadDocument(absoluteRefFile);
|
|
106
108
|
const value = refPath ? getDeepProperty(doc.document, refPath.replace(/[/]/g, '.')) : doc.document;
|
|
107
109
|
if (value && typeof value === 'object') {
|
|
108
|
-
return this.dereference(absoluteRefFile, refPath
|
|
110
|
+
return this.dereference(absoluteRefFile, refPath.split('/').filter(Boolean), value);
|
|
109
111
|
}
|
|
110
112
|
return undefined;
|
|
111
113
|
}
|
|
@@ -115,26 +117,14 @@ class OpenApiParser {
|
|
|
115
117
|
return existingDocument;
|
|
116
118
|
}
|
|
117
119
|
const documentContent = await this.getDocumentContent(fileOrUrl);
|
|
118
|
-
const
|
|
119
|
-
let parsedDocument;
|
|
120
|
-
if (extname === '.json') {
|
|
121
|
-
parsedDocument = this.tryParseJson(documentContent);
|
|
122
|
-
}
|
|
123
|
-
else if (extname === '.yaml' || extname === '.yml') {
|
|
124
|
-
parsedDocument = this.tryParseYaml(documentContent);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
parsedDocument = this.tryParseJson(documentContent);
|
|
128
|
-
if (parsedDocument !== undefined) {
|
|
129
|
-
parsedDocument = this.tryParseYaml(documentContent);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
120
|
+
const parsedDocument = this.tryParseYamlOrJson(documentContent);
|
|
132
121
|
if (parsedDocument === undefined) {
|
|
133
122
|
throw new Error(`Unable to parse ${fileOrUrl}`);
|
|
134
123
|
}
|
|
135
124
|
const doc = (parsedDocument !== null && parsedDocument !== void 0 ? parsedDocument : {});
|
|
136
125
|
const deref = (0, deref_proxy_js_1.createDerefProxy)(doc, {
|
|
137
126
|
file: fileOrUrl,
|
|
127
|
+
pos: { line: 0, col: 0 },
|
|
138
128
|
path: '',
|
|
139
129
|
originalComponent: doc,
|
|
140
130
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -165,17 +155,9 @@ class OpenApiParser {
|
|
|
165
155
|
isUrl(fileOrUrl) {
|
|
166
156
|
return /^https?:\/\//i.test(fileOrUrl);
|
|
167
157
|
}
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
return JSON.parse(json);
|
|
171
|
-
}
|
|
172
|
-
catch (_a) {
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
tryParseYaml(yaml) {
|
|
158
|
+
tryParseYamlOrJson(yamlOrJson) {
|
|
177
159
|
try {
|
|
178
|
-
return
|
|
160
|
+
return (0, yaml_info_js_1.parseYamlWithInfo)(yamlOrJson);
|
|
179
161
|
}
|
|
180
162
|
catch (_a) {
|
|
181
163
|
return undefined;
|
|
@@ -198,8 +180,3 @@ function getDeepProperty(value, path) {
|
|
|
198
180
|
}
|
|
199
181
|
return result;
|
|
200
182
|
}
|
|
201
|
-
function joinPaths(...paths) {
|
|
202
|
-
return paths
|
|
203
|
-
.map((p) => String(p).replace(/\/$/, ''))
|
|
204
|
-
.join('/');
|
|
205
|
-
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
2
1
|
import { type OpenApiTransformerOptions } from '../transform/types.js';
|
|
2
|
+
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
3
3
|
export type DerefSource<T> = {
|
|
4
4
|
file: string;
|
|
5
|
+
pos: {
|
|
6
|
+
line: number;
|
|
7
|
+
col: number;
|
|
8
|
+
};
|
|
5
9
|
path: string;
|
|
6
10
|
document: Deref<OpenApiDocument>;
|
|
7
11
|
originalComponent: T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/parse/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/parse/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACzG,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACjC,iBAAiB,EAAE,CAAC,CAAC;CACtB,CAAC;AAEF,KAAK,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;CAChD,CAAC;AACF,KAAK,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,oBAAoB,GAAG,mBAAmB,GAE9E;KACC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,gBAAgB,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5E,GACC;IACA,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CACjB,CAAC;AACN,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAE/F,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE7D,eAAO,MAAM,2BAA2B;;CAA0C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/src/transform/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/src/transform/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ const node_path_1 = require("node:path");
|
|
|
14
14
|
const internal_utils_js_1 = require("../internal-utils.js");
|
|
15
15
|
const common_utils_js_1 = require("../utils/common.utils.js");
|
|
16
16
|
const object_utils_js_1 = require("../utils/object.utils.js");
|
|
17
|
+
const yaml_info_js_1 = require("../utils/yaml-info.js");
|
|
17
18
|
function determineSchemaKind(ctx, schema) {
|
|
18
19
|
if (schema.oneOf) {
|
|
19
20
|
return 'oneOf';
|
|
@@ -62,7 +63,6 @@ function determineSchemaName(schema, id) {
|
|
|
62
63
|
if (responseMatch && responseMatch.groups) {
|
|
63
64
|
const { path, method, status } = responseMatch.groups;
|
|
64
65
|
const operation = (_c = (_b = (_a = schema.$src.document.paths) === null || _a === void 0 ? void 0 : _a[path]) === null || _b === void 0 ? void 0 : _b[method]) !== null && _c !== void 0 ? _c : {};
|
|
65
|
-
console.log('responseMatch', responseMatch.groups, operation);
|
|
66
66
|
return {
|
|
67
67
|
name: `${determineEndpointName({ method, path: `/${path}`, operation })}_${status}_Response`,
|
|
68
68
|
isGenerated: true,
|
|
@@ -92,6 +92,7 @@ function determineSchemaName(schema, id) {
|
|
|
92
92
|
: undefined,
|
|
93
93
|
$src: {
|
|
94
94
|
file: schema.$src.file,
|
|
95
|
+
pos: (0, yaml_info_js_1.getLineInfo)(schema.$src.document, parentSchemaMatch[1].split('/').filter(Boolean)),
|
|
95
96
|
path: parentSchemaMatch[1],
|
|
96
97
|
document: schema.$src.document,
|
|
97
98
|
originalComponent: parentSchema,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as YAML from 'yaml';
|
|
2
|
+
export declare const yamlInfoSymbol: unique symbol;
|
|
3
|
+
export type YamlInfo = {
|
|
4
|
+
document: YAML.Document.Parsed;
|
|
5
|
+
lineCounter: YAML.LineCounter;
|
|
6
|
+
};
|
|
7
|
+
export declare function getYamlInfo(obj: unknown): YamlInfo;
|
|
8
|
+
export declare function getLineInfo(obj: unknown, path: unknown[]): {
|
|
9
|
+
line: number;
|
|
10
|
+
col: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function parseYamlWithInfo(yamlString: string): unknown;
|
|
13
|
+
//# sourceMappingURL=yaml-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml-info.d.ts","sourceRoot":"","sources":["../../../src/src/utils/yaml-info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,eAAO,MAAM,cAAc,eAAqB,CAAC;AAMjD,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC/B,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC;CAC/B,CAAC;AAEF,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAMlD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAiBxF;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAO7D"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.yamlInfoSymbol = void 0;
|
|
4
|
+
exports.getYamlInfo = getYamlInfo;
|
|
5
|
+
exports.getLineInfo = getLineInfo;
|
|
6
|
+
exports.parseYamlWithInfo = parseYamlWithInfo;
|
|
7
|
+
const tslib_1 = require("tslib");
|
|
8
|
+
const YAML = tslib_1.__importStar(require("yaml"));
|
|
9
|
+
exports.yamlInfoSymbol = Symbol('yamlInfo');
|
|
10
|
+
function getYamlInfo(obj) {
|
|
11
|
+
const yamlInfo = obj[exports.yamlInfoSymbol];
|
|
12
|
+
if (!yamlInfo) {
|
|
13
|
+
throw new Error('No YAML info found on object');
|
|
14
|
+
}
|
|
15
|
+
return yamlInfo;
|
|
16
|
+
}
|
|
17
|
+
function getLineInfo(obj, path) {
|
|
18
|
+
var _a;
|
|
19
|
+
const yamlInfo = getYamlInfo(obj);
|
|
20
|
+
const node = (_a = yamlInfo.document.getIn(path, true)) !== null && _a !== void 0 ? _a : yamlInfo.document.getIn(path.map((v) => {
|
|
21
|
+
const num = Number(v);
|
|
22
|
+
return isNaN(num) ? v : num;
|
|
23
|
+
}), true);
|
|
24
|
+
if (!node || typeof node !== 'object' || !('range' in node) || !Array.isArray(node.range) ||
|
|
25
|
+
typeof node.range[0] !== 'number') {
|
|
26
|
+
console.warn(`Unable to get line info for path ${path.join('/')}`);
|
|
27
|
+
return { line: 0, col: 0 };
|
|
28
|
+
}
|
|
29
|
+
return yamlInfo.lineCounter.linePos(node.range[0]);
|
|
30
|
+
}
|
|
31
|
+
function parseYamlWithInfo(yamlString) {
|
|
32
|
+
const lineCounter = new YAML.LineCounter();
|
|
33
|
+
const document = YAML.parseDocument(yamlString, { lineCounter });
|
|
34
|
+
return Object.defineProperty(document.toJS(), exports.yamlInfoSymbol, {
|
|
35
|
+
value: { document, lineCounter },
|
|
36
|
+
enumerable: false,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -58,7 +58,13 @@ class DerefProxyHandler<T extends OpenApiObject<string>> implements ProxyHandler
|
|
|
58
58
|
|
|
59
59
|
public ownKeys(target: T): ArrayLike<string | symbol> {
|
|
60
60
|
return Array.from(
|
|
61
|
-
new Set([
|
|
61
|
+
new Set([
|
|
62
|
+
...Object.getOwnPropertyNames(target),
|
|
63
|
+
...Object.getOwnPropertySymbols(target),
|
|
64
|
+
...(!isNullish(this._ref) ? Object.keys(this._ref) : []),
|
|
65
|
+
'$ref',
|
|
66
|
+
'$src',
|
|
67
|
+
]),
|
|
62
68
|
);
|
|
63
69
|
}
|
|
64
70
|
}
|
package/src/src/parse/parser.ts
CHANGED
|
@@ -4,12 +4,12 @@ import { cwd } from 'node:process';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
|
-
import * as YAML from 'yaml';
|
|
8
7
|
|
|
9
8
|
import { collectOpenApi } from '../collect/collector.js';
|
|
10
9
|
import type { ApiData } from '../transform/api-types.js';
|
|
11
10
|
import { transformOpenApi } from '../transform/transformer.js';
|
|
12
11
|
import { isNullish } from '../utils/common.utils.js';
|
|
12
|
+
import { getLineInfo, parseYamlWithInfo } from '../utils/yaml-info.js';
|
|
13
13
|
import { createDerefProxy } from './deref-proxy.js';
|
|
14
14
|
import type { OpenApiDocument, OpenApiObject, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
15
15
|
import { defaultOpenApiParserOptions, type Deref, type OpenApiParserOptions } from './types.js';
|
|
@@ -41,7 +41,7 @@ export class OpenApiParser {
|
|
|
41
41
|
public async parseApi(fileName: string): Promise<Deref<OpenApiDocument>> {
|
|
42
42
|
const absoluteFilePath = this.isUrl(fileName) ? fileName : path.resolve(cwd(), fileName);
|
|
43
43
|
const doc = await this.loadDocument(absoluteFilePath);
|
|
44
|
-
return await this.dereference(absoluteFilePath,
|
|
44
|
+
return await this.dereference(absoluteFilePath, [], doc.document);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
public transformApis(apis: Deref<OpenApiDocument>[]): ApiData {
|
|
@@ -50,10 +50,15 @@ export class OpenApiParser {
|
|
|
50
50
|
return transformedData;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
private async dereference<T extends OpenApiObject<string>>(
|
|
53
|
+
private async dereference<T extends OpenApiObject<string>>(
|
|
54
|
+
file: string,
|
|
55
|
+
path: unknown[],
|
|
56
|
+
value: T,
|
|
57
|
+
): Promise<Deref<T>> {
|
|
58
|
+
const openApiPath = `/${path.join('/')}`;
|
|
54
59
|
let existingDocument = this._loadedDocuments.get(file);
|
|
55
60
|
if (existingDocument) {
|
|
56
|
-
const existingComponent = existingDocument.dereferencedComponents.get(
|
|
61
|
+
const existingComponent = existingDocument.dereferencedComponents.get(openApiPath);
|
|
57
62
|
if (existingComponent) {
|
|
58
63
|
return existingComponent as Deref<T>;
|
|
59
64
|
}
|
|
@@ -63,11 +68,12 @@ export class OpenApiParser {
|
|
|
63
68
|
|
|
64
69
|
const result = createDerefProxy(value, {
|
|
65
70
|
file,
|
|
66
|
-
path,
|
|
71
|
+
pos: getLineInfo(existingDocument.document, path),
|
|
72
|
+
path: openApiPath,
|
|
67
73
|
document: existingDocument.dereferencedDocument,
|
|
68
74
|
originalComponent: value,
|
|
69
75
|
});
|
|
70
|
-
existingDocument.dereferencedComponents.set(
|
|
76
|
+
existingDocument.dereferencedComponents.set(openApiPath, result as Deref<OpenApiObject<string>>);
|
|
71
77
|
|
|
72
78
|
if (value.$ref) {
|
|
73
79
|
// deno-lint-ignore no-explicit-any
|
|
@@ -82,7 +88,7 @@ export class OpenApiParser {
|
|
|
82
88
|
(result as Record<keyof T, unknown>)[key] = await Promise.all(
|
|
83
89
|
v.map(async (v, index) => {
|
|
84
90
|
if (v && typeof v === 'object') {
|
|
85
|
-
return await this.dereference(file,
|
|
91
|
+
return await this.dereference(file, [...path, key, index], v);
|
|
86
92
|
} else {
|
|
87
93
|
return v;
|
|
88
94
|
}
|
|
@@ -91,12 +97,12 @@ export class OpenApiParser {
|
|
|
91
97
|
} else {
|
|
92
98
|
(result as Record<keyof T, unknown>)[key] = await this.dereference(
|
|
93
99
|
file,
|
|
94
|
-
|
|
100
|
+
[...path, key],
|
|
95
101
|
v as Record<string, unknown>,
|
|
96
102
|
);
|
|
97
103
|
}
|
|
98
104
|
}
|
|
99
|
-
if (typeof v === 'string' &&
|
|
105
|
+
if (typeof v === 'string' && openApiPath.endsWith('/discriminator/mapping')) {
|
|
100
106
|
(result as Record<keyof T, unknown>)[key] = await this.resolveReference<OpenApiSchema>(file, { $ref: v });
|
|
101
107
|
}
|
|
102
108
|
}
|
|
@@ -121,7 +127,7 @@ export class OpenApiParser {
|
|
|
121
127
|
|
|
122
128
|
const value = refPath ? getDeepProperty(doc.document, refPath.replace(/[/]/g, '.')) : doc.document;
|
|
123
129
|
if (value && typeof value === 'object') {
|
|
124
|
-
return this.dereference(absoluteRefFile, refPath
|
|
130
|
+
return this.dereference(absoluteRefFile, refPath.split('/').filter(Boolean), value as T);
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
return undefined;
|
|
@@ -134,20 +140,7 @@ export class OpenApiParser {
|
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
const documentContent = await this.getDocumentContent(fileOrUrl);
|
|
137
|
-
const
|
|
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
|
-
|
|
143
|
+
const parsedDocument = this.tryParseYamlOrJson(documentContent);
|
|
151
144
|
if (parsedDocument === undefined) {
|
|
152
145
|
throw new Error(`Unable to parse ${fileOrUrl}`);
|
|
153
146
|
}
|
|
@@ -155,6 +148,7 @@ export class OpenApiParser {
|
|
|
155
148
|
const doc = (parsedDocument ?? {}) as OpenApiDocument;
|
|
156
149
|
const deref = createDerefProxy(doc, {
|
|
157
150
|
file: fileOrUrl,
|
|
151
|
+
pos: { line: 0, col: 0 },
|
|
158
152
|
path: '',
|
|
159
153
|
originalComponent: doc,
|
|
160
154
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -187,17 +181,9 @@ export class OpenApiParser {
|
|
|
187
181
|
return /^https?:\/\//i.test(fileOrUrl);
|
|
188
182
|
}
|
|
189
183
|
|
|
190
|
-
private
|
|
191
|
-
try {
|
|
192
|
-
return JSON.parse(json);
|
|
193
|
-
} catch {
|
|
194
|
-
return undefined;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
private tryParseYaml(yaml: string): unknown {
|
|
184
|
+
private tryParseYamlOrJson(yamlOrJson: string): unknown {
|
|
199
185
|
try {
|
|
200
|
-
return
|
|
186
|
+
return parseYamlWithInfo(yamlOrJson);
|
|
201
187
|
} catch {
|
|
202
188
|
return undefined;
|
|
203
189
|
}
|
|
@@ -218,9 +204,3 @@ function getDeepProperty(value: Record<string, unknown>, path: string): unknown
|
|
|
218
204
|
|
|
219
205
|
return result;
|
|
220
206
|
}
|
|
221
|
-
|
|
222
|
-
function joinPaths(...paths: unknown[]): string {
|
|
223
|
-
return paths
|
|
224
|
-
.map((p) => String(p).replace(/\/$/, ''))
|
|
225
|
-
.join('/');
|
|
226
|
-
}
|
package/src/src/parse/types.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
2
1
|
import { defaultOpenApiTransformerOptions, type OpenApiTransformerOptions } from '../transform/types.js';
|
|
2
|
+
import type { OpenApiDiscriminator, OpenApiDocument, OpenApiReference, OpenApiSchema } from './openapi-types.js';
|
|
3
3
|
|
|
4
4
|
export type DerefSource<T> = {
|
|
5
5
|
file: string;
|
|
6
|
+
pos: { line: number; col: number };
|
|
6
7
|
path: string;
|
|
7
8
|
document: Deref<OpenApiDocument>;
|
|
8
9
|
originalComponent: T;
|
|
@@ -4,6 +4,7 @@ import type { OpenApiHttpMethod, OpenApiObject } from '../parse/openapi-types.js
|
|
|
4
4
|
import type { Deref, DerefSource } from '../parse/types.js';
|
|
5
5
|
import { isNullish } from '../utils/common.utils.js';
|
|
6
6
|
import { getDeepProperty } from '../utils/object.utils.js';
|
|
7
|
+
import { getLineInfo } from '../utils/yaml-info.js';
|
|
7
8
|
import type { ApiSchema, ApiSchemaAccessibility, ApiSchemaKind, ApiSchemaProperty } from './api-types.js';
|
|
8
9
|
import type { OpenApiTransformerContext } from './types.js';
|
|
9
10
|
|
|
@@ -73,7 +74,6 @@ export function determineSchemaName(
|
|
|
73
74
|
if (responseMatch && responseMatch.groups) {
|
|
74
75
|
const { path, method, status } = responseMatch.groups;
|
|
75
76
|
const operation = schema.$src.document.paths?.[path]?.[method as OpenApiHttpMethod] ?? {};
|
|
76
|
-
console.log('responseMatch', responseMatch.groups, operation);
|
|
77
77
|
return {
|
|
78
78
|
name: `${determineEndpointName({ method, path: `/${path}`, operation })}_${status}_Response`,
|
|
79
79
|
isGenerated: true,
|
|
@@ -107,6 +107,7 @@ export function determineSchemaName(
|
|
|
107
107
|
: undefined,
|
|
108
108
|
$src: {
|
|
109
109
|
file: schema.$src.file,
|
|
110
|
+
pos: getLineInfo(schema.$src.document, parentSchemaMatch[1].split('/').filter(Boolean)),
|
|
110
111
|
path: parentSchemaMatch[1],
|
|
111
112
|
document: schema.$src.document,
|
|
112
113
|
originalComponent: parentSchema,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as YAML from 'yaml';
|
|
2
|
+
|
|
3
|
+
export const yamlInfoSymbol = Symbol('yamlInfo');
|
|
4
|
+
|
|
5
|
+
type WithYamlInfo = {
|
|
6
|
+
[yamlInfoSymbol]?: YamlInfo;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type YamlInfo = {
|
|
10
|
+
document: YAML.Document.Parsed;
|
|
11
|
+
lineCounter: YAML.LineCounter;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function getYamlInfo(obj: unknown): YamlInfo {
|
|
15
|
+
const yamlInfo = (obj as WithYamlInfo)[yamlInfoSymbol] as YamlInfo | undefined;
|
|
16
|
+
if (!yamlInfo) {
|
|
17
|
+
throw new Error('No YAML info found on object');
|
|
18
|
+
}
|
|
19
|
+
return yamlInfo;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getLineInfo(obj: unknown, path: unknown[]): { line: number; col: number } {
|
|
23
|
+
const yamlInfo = getYamlInfo(obj);
|
|
24
|
+
const node = yamlInfo.document.getIn(path, true) ?? yamlInfo.document.getIn(
|
|
25
|
+
path.map((v) => {
|
|
26
|
+
const num = Number(v);
|
|
27
|
+
return isNaN(num) ? v : num;
|
|
28
|
+
}),
|
|
29
|
+
true,
|
|
30
|
+
);
|
|
31
|
+
if (
|
|
32
|
+
!node || typeof node !== 'object' || !('range' in node) || !Array.isArray(node.range) ||
|
|
33
|
+
typeof node.range[0] !== 'number'
|
|
34
|
+
) {
|
|
35
|
+
console.warn(`Unable to get line info for path ${path.join('/')}`);
|
|
36
|
+
return { line: 0, col: 0 };
|
|
37
|
+
}
|
|
38
|
+
return yamlInfo.lineCounter.linePos(node.range[0]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function parseYamlWithInfo(yamlString: string): unknown {
|
|
42
|
+
const lineCounter = new YAML.LineCounter();
|
|
43
|
+
const document = YAML.parseDocument(yamlString, { lineCounter });
|
|
44
|
+
return Object.defineProperty(document.toJS(), yamlInfoSymbol, {
|
|
45
|
+
value: { document, lineCounter },
|
|
46
|
+
enumerable: false,
|
|
47
|
+
});
|
|
48
|
+
}
|