@goast/core 0.5.1 → 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.
@@ -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([...Object.keys(target), ...(!isNullish(this._ref) ? Object.keys(this._ref) : []), '$ref', '$src']));
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
  }
@@ -13,7 +13,6 @@ export declare class OpenApiParser {
13
13
  private loadDocument;
14
14
  private getDocumentContent;
15
15
  private isUrl;
16
- private tryParseJson;
17
- private tryParseYaml;
16
+ private tryParseYamlOrJson;
18
17
  }
19
18
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/src/parse/parser.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAIzD,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;YAsDX,gBAAgB;YAuBhB,YAAY;YA4CZ,kBAAkB;IAYhC,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;CAOrB"}
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"}
@@ -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, '/', doc.document);
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(path);
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(path, result);
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, joinPaths(path, key, index), v);
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, joinPaths(path, key), v);
85
+ result[key] = await this.dereference(file, [...path, key], v);
84
86
  }
85
87
  }
86
- if (typeof v === 'string' && path.endsWith('/discriminator/mapping')) {
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 !== null && refPath !== void 0 ? refPath : '/', value);
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 extname = path.extname(fileOrUrl).toLowerCase();
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
- tryParseJson(json) {
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 YAML.parse(yaml);
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
- }
@@ -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;AACjH,OAAO,EAAoC,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEzG,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,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
+ {"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":"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"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goast/core",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "A tool designed to transform OpenAPI specifications into various forms with flexibility and extensibility at its core.",
5
5
  "author": {
6
6
  "name": "Marc Schmidt (MaSch0212)",
@@ -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([...Object.keys(target), ...(!(0, common_utils_js_1.isNullish)(this._ref) ? Object.keys(this._ref) : []), '$ref', '$src']));
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
  }
@@ -13,7 +13,6 @@ export declare class OpenApiParser {
13
13
  private loadDocument;
14
14
  private getDocumentContent;
15
15
  private isUrl;
16
- private tryParseJson;
17
- private tryParseYaml;
16
+ private tryParseYamlOrJson;
18
17
  }
19
18
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/src/parse/parser.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAIzD,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;YAsDX,gBAAgB;YAuBhB,YAAY;YA4CZ,kBAAkB;IAYhC,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;CAOrB"}
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, '/', doc.document);
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(path);
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(path, result);
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, joinPaths(path, key, index), v);
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, joinPaths(path, key), v);
89
+ result[key] = await this.dereference(file, [...path, key], v);
88
90
  }
89
91
  }
90
- if (typeof v === 'string' && path.endsWith('/discriminator/mapping')) {
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 !== null && refPath !== void 0 ? refPath : '/', value);
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 extname = node_path_1.default.extname(fileOrUrl).toLowerCase();
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
- tryParseJson(json) {
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 YAML.parse(yaml);
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;AACjH,OAAO,EAAoC,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEzG,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,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
+ {"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":"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"}
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;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1G,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5D,wBAAgB,mBAAmB,CACjC,CAAC,SAAS;IACR,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,EACD,GAAG,EAAE,yBAAyB,EAAE,MAAM,EAAE,CAAC,GAAG,aAAa,CA2B1D;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE;IACN,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CAC5B,EACD,EAAE,EAAE,MAAM,GACT;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAqExC;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,sBAAsB,CAMzB;AAED,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,sBAAsB,EACrC,MAAM,EAAE;IACN,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GACA,sBAAsB,CAKxB;AAED,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACpD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;CAC5D,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAS7F;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC,GAAG,MAAM,CAGT;AAED,wBAAgB,6BAA6B,CAAC,qBAAqB,EACjE,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE;IACN,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;CAC9C,EACD,eAAe,EAAE,CACf,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,OAAO,CAAC,qBAAqB,EAAE,SAAS,GAAG,OAAO,CAAC,KACxD,SAAS,GACb,OAAO,GAAG,SAAS,GAAG,SAAS,CAIjC;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EACnD,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EACzE,eAAe,EAAE,CAAC,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,WAAW,KAAK,SAAS,GACtF,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAWhC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IAE7C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAKxC;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,UAE3E"}
@@ -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([...Object.keys(target), ...(!isNullish(this._ref) ? Object.keys(this._ref) : []), '$ref', '$src']),
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
  }
@@ -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, '/', doc.document);
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>>(file: string, path: string, value: T): Promise<Deref<T>> {
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(path);
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(path, result as Deref<OpenApiObject<string>>);
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, joinPaths(path, key, index), v);
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
- joinPaths(path, key),
100
+ [...path, key],
95
101
  v as Record<string, unknown>,
96
102
  );
97
103
  }
98
104
  }
99
- if (typeof v === 'string' && path.endsWith('/discriminator/mapping')) {
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 ?? '/', value as T);
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 extname = path.extname(fileOrUrl).toLowerCase();
138
-
139
- let parsedDocument: unknown;
140
- if (extname === '.json') {
141
- parsedDocument = this.tryParseJson(documentContent);
142
- } else if (extname === '.yaml' || extname === '.yml') {
143
- parsedDocument = this.tryParseYaml(documentContent);
144
- } else {
145
- parsedDocument = this.tryParseJson(documentContent);
146
- if (parsedDocument !== undefined) {
147
- parsedDocument = this.tryParseYaml(documentContent);
148
- }
149
- }
150
-
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 tryParseJson(json: string): unknown {
191
- try {
192
- return JSON.parse(json);
193
- } catch {
194
- return undefined;
195
- }
196
- }
197
-
198
- private tryParseYaml(yaml: string): unknown {
184
+ private tryParseYamlOrJson(yamlOrJson: string): unknown {
199
185
  try {
200
- return YAML.parse(yaml);
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
- }
@@ -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
+ }