@goast/core 0.5.1 → 0.5.3
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 +16 -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 -0
- 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 +16 -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 -0
- 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 -0
- 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,16 +82,17 @@ 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
|
}
|
|
90
92
|
return result;
|
|
91
93
|
}
|
|
92
94
|
async resolveReference(file, ref) {
|
|
95
|
+
var _a;
|
|
93
96
|
const [refFile, refPath] = ref.$ref.split('#');
|
|
94
97
|
let absoluteRefFile = refFile;
|
|
95
98
|
if (!/\S/.test(refFile)) {
|
|
@@ -101,7 +104,7 @@ export class OpenApiParser {
|
|
|
101
104
|
const doc = await this.loadDocument(absoluteRefFile);
|
|
102
105
|
const value = refPath ? getDeepProperty(doc.document, refPath.replace(/[/]/g, '.')) : doc.document;
|
|
103
106
|
if (value && typeof value === 'object') {
|
|
104
|
-
return this.dereference(absoluteRefFile, refPath
|
|
107
|
+
return this.dereference(absoluteRefFile, (_a = refPath === null || refPath === void 0 ? void 0 : refPath.split('/').filter(Boolean)) !== null && _a !== void 0 ? _a : [], value);
|
|
105
108
|
}
|
|
106
109
|
return undefined;
|
|
107
110
|
}
|
|
@@ -111,26 +114,14 @@ export class OpenApiParser {
|
|
|
111
114
|
return existingDocument;
|
|
112
115
|
}
|
|
113
116
|
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
|
-
}
|
|
117
|
+
const parsedDocument = this.tryParseYamlOrJson(documentContent);
|
|
128
118
|
if (parsedDocument === undefined) {
|
|
129
119
|
throw new Error(`Unable to parse ${fileOrUrl}`);
|
|
130
120
|
}
|
|
131
121
|
const doc = (parsedDocument !== null && parsedDocument !== void 0 ? parsedDocument : {});
|
|
132
122
|
const deref = createDerefProxy(doc, {
|
|
133
123
|
file: fileOrUrl,
|
|
124
|
+
pos: { line: 0, col: 0 },
|
|
134
125
|
path: '',
|
|
135
126
|
originalComponent: doc,
|
|
136
127
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -161,17 +152,9 @@ export class OpenApiParser {
|
|
|
161
152
|
isUrl(fileOrUrl) {
|
|
162
153
|
return /^https?:\/\//i.test(fileOrUrl);
|
|
163
154
|
}
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
return JSON.parse(json);
|
|
167
|
-
}
|
|
168
|
-
catch (_a) {
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
tryParseYaml(yaml) {
|
|
155
|
+
tryParseYamlOrJson(yamlOrJson) {
|
|
173
156
|
try {
|
|
174
|
-
return
|
|
157
|
+
return parseYamlWithInfo(yamlOrJson);
|
|
175
158
|
}
|
|
176
159
|
catch (_a) {
|
|
177
160
|
return undefined;
|
|
@@ -193,8 +176,3 @@ function getDeepProperty(value, path) {
|
|
|
193
176
|
}
|
|
194
177
|
return result;
|
|
195
178
|
}
|
|
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';
|
|
@@ -79,6 +80,7 @@ export function determineSchemaName(schema, id) {
|
|
|
79
80
|
: undefined,
|
|
80
81
|
$src: {
|
|
81
82
|
file: schema.$src.file,
|
|
83
|
+
pos: getLineInfo(schema.$src.document, parentSchemaMatch[1].split('/').filter(Boolean)),
|
|
82
84
|
path: parentSchemaMatch[1],
|
|
83
85
|
document: schema.$src.document,
|
|
84
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,16 +86,17 @@ 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
|
}
|
|
94
96
|
return result;
|
|
95
97
|
}
|
|
96
98
|
async resolveReference(file, ref) {
|
|
99
|
+
var _a;
|
|
97
100
|
const [refFile, refPath] = ref.$ref.split('#');
|
|
98
101
|
let absoluteRefFile = refFile;
|
|
99
102
|
if (!/\S/.test(refFile)) {
|
|
@@ -105,7 +108,7 @@ class OpenApiParser {
|
|
|
105
108
|
const doc = await this.loadDocument(absoluteRefFile);
|
|
106
109
|
const value = refPath ? getDeepProperty(doc.document, refPath.replace(/[/]/g, '.')) : doc.document;
|
|
107
110
|
if (value && typeof value === 'object') {
|
|
108
|
-
return this.dereference(absoluteRefFile, refPath
|
|
111
|
+
return this.dereference(absoluteRefFile, (_a = refPath === null || refPath === void 0 ? void 0 : refPath.split('/').filter(Boolean)) !== null && _a !== void 0 ? _a : [], value);
|
|
109
112
|
}
|
|
110
113
|
return undefined;
|
|
111
114
|
}
|
|
@@ -115,26 +118,14 @@ class OpenApiParser {
|
|
|
115
118
|
return existingDocument;
|
|
116
119
|
}
|
|
117
120
|
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
|
-
}
|
|
121
|
+
const parsedDocument = this.tryParseYamlOrJson(documentContent);
|
|
132
122
|
if (parsedDocument === undefined) {
|
|
133
123
|
throw new Error(`Unable to parse ${fileOrUrl}`);
|
|
134
124
|
}
|
|
135
125
|
const doc = (parsedDocument !== null && parsedDocument !== void 0 ? parsedDocument : {});
|
|
136
126
|
const deref = (0, deref_proxy_js_1.createDerefProxy)(doc, {
|
|
137
127
|
file: fileOrUrl,
|
|
128
|
+
pos: { line: 0, col: 0 },
|
|
138
129
|
path: '',
|
|
139
130
|
originalComponent: doc,
|
|
140
131
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -165,17 +156,9 @@ class OpenApiParser {
|
|
|
165
156
|
isUrl(fileOrUrl) {
|
|
166
157
|
return /^https?:\/\//i.test(fileOrUrl);
|
|
167
158
|
}
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
return JSON.parse(json);
|
|
171
|
-
}
|
|
172
|
-
catch (_a) {
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
tryParseYaml(yaml) {
|
|
159
|
+
tryParseYamlOrJson(yamlOrJson) {
|
|
177
160
|
try {
|
|
178
|
-
return
|
|
161
|
+
return (0, yaml_info_js_1.parseYamlWithInfo)(yamlOrJson);
|
|
179
162
|
}
|
|
180
163
|
catch (_a) {
|
|
181
164
|
return undefined;
|
|
@@ -198,8 +181,3 @@ function getDeepProperty(value, path) {
|
|
|
198
181
|
}
|
|
199
182
|
return result;
|
|
200
183
|
}
|
|
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';
|
|
@@ -91,6 +92,7 @@ function determineSchemaName(schema, id) {
|
|
|
91
92
|
: undefined,
|
|
92
93
|
$src: {
|
|
93
94
|
file: schema.$src.file,
|
|
95
|
+
pos: (0, yaml_info_js_1.getLineInfo)(schema.$src.document, parentSchemaMatch[1].split('/').filter(Boolean)),
|
|
94
96
|
path: parentSchemaMatch[1],
|
|
95
97
|
document: schema.$src.document,
|
|
96
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
|
|
|
@@ -106,6 +107,7 @@ export function determineSchemaName(
|
|
|
106
107
|
: undefined,
|
|
107
108
|
$src: {
|
|
108
109
|
file: schema.$src.file,
|
|
110
|
+
pos: getLineInfo(schema.$src.document, parentSchemaMatch[1].split('/').filter(Boolean)),
|
|
109
111
|
path: parentSchemaMatch[1],
|
|
110
112
|
document: schema.$src.document,
|
|
111
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
|
+
}
|