@goast/core 0.2.1 → 0.3.0

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.
Files changed (47) hide show
  1. package/README.md +65 -11
  2. package/cjs/lib/codegen/config.js +5 -1
  3. package/cjs/lib/codegen/generator.js +28 -35
  4. package/cjs/lib/codegen/internal-utils.js +1 -2
  5. package/cjs/lib/collect/collector.js +1 -2
  6. package/cjs/lib/collect/helpers.js +2 -3
  7. package/cjs/lib/internal-utils.js +1 -2
  8. package/cjs/lib/parse/deref-proxy.js +1 -2
  9. package/cjs/lib/parse/parser.js +114 -126
  10. package/cjs/lib/transform/helpers.js +10 -10
  11. package/cjs/lib/transform/transform-document.js +5 -3
  12. package/cjs/lib/transform/transform-endpoint.js +35 -10
  13. package/cjs/lib/transform/transform-schema.js +5 -3
  14. package/cjs/lib/transform/transformer.js +1 -2
  15. package/cjs/lib/utils/array.utils.js +1 -2
  16. package/cjs/lib/utils/class.utils.js +3 -4
  17. package/cjs/lib/utils/common.utils.js +12 -13
  18. package/cjs/lib/utils/condition.js +1 -2
  19. package/cjs/lib/utils/endpoint.utils.js +1 -2
  20. package/cjs/lib/utils/error.utils.js +1 -2
  21. package/cjs/lib/utils/file-system.utils.js +21 -26
  22. package/cjs/lib/utils/generator.utils.js +1 -2
  23. package/cjs/lib/utils/object.utils.js +1 -2
  24. package/cjs/lib/utils/schema.utils.js +67 -5
  25. package/cjs/lib/utils/source-builder.js +5 -3
  26. package/cjs/lib/utils/string-builder/options.js +3 -0
  27. package/cjs/lib/utils/string-builder/string-builder.js +1 -1
  28. package/cjs/lib/utils/string-builder/utils.js +5 -6
  29. package/cjs/lib/utils/string.utils.js +27 -28
  30. package/cjs/lib/utils/type.utils.js +2 -3
  31. package/esm/lib/codegen/config.js +5 -1
  32. package/esm/lib/codegen/generator.js +28 -35
  33. package/esm/lib/parse/parser.js +114 -127
  34. package/esm/lib/transform/transform-document.js +4 -1
  35. package/esm/lib/transform/transform-endpoint.js +34 -8
  36. package/esm/lib/transform/transform-schema.js +4 -1
  37. package/esm/lib/utils/file-system.utils.js +19 -24
  38. package/esm/lib/utils/schema.utils.js +65 -2
  39. package/esm/lib/utils/source-builder.js +6 -4
  40. package/esm/lib/utils/string-builder/options.js +3 -0
  41. package/esm/lib/utils/string-builder/string-builder.js +1 -1
  42. package/esm/lib/utils/string.utils.js +7 -7
  43. package/package.json +6 -5
  44. package/types/lib/codegen/config.d.ts +8 -0
  45. package/types/lib/utils/source-builder.d.ts +11 -1
  46. package/types/lib/utils/string-builder/options.d.ts +8 -2
  47. package/types/lib/utils/string.utils.types.d.ts +1 -0
@@ -1,6 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.removeStr = exports.trim = exports.trimStart = exports.trimEnd = exports.trimIndent = exports.spliceString = exports.escapeRegExp = exports.toCustomCase = exports.toSnakeCase = exports.toKebabCase = exports.toPascalCase = exports.toCamelCase = exports.toCasing = exports.wordToCasing = exports.getWords = exports.uncapitalize = exports.capitalize = exports.uppercase = exports.lowercase = exports.adjustCasing = void 0;
3
+ exports.adjustCasing = adjustCasing;
4
+ exports.lowercase = lowercase;
5
+ exports.uppercase = uppercase;
6
+ exports.capitalize = capitalize;
7
+ exports.uncapitalize = uncapitalize;
8
+ exports.getWords = getWords;
9
+ exports.wordToCasing = wordToCasing;
10
+ exports.toCasing = toCasing;
11
+ exports.toCamelCase = toCamelCase;
12
+ exports.toPascalCase = toPascalCase;
13
+ exports.toKebabCase = toKebabCase;
14
+ exports.toSnakeCase = toSnakeCase;
15
+ exports.toCustomCase = toCustomCase;
16
+ exports.escapeRegExp = escapeRegExp;
17
+ exports.spliceString = spliceString;
18
+ exports.trimIndent = trimIndent;
19
+ exports.trimEnd = trimEnd;
20
+ exports.trimStart = trimStart;
21
+ exports.trim = trim;
22
+ exports.removeStr = removeStr;
4
23
  const common_utils_1 = require("./common.utils");
5
24
  function adjustCasing(a, b) {
6
25
  if (typeof a === 'string') {
@@ -8,33 +27,28 @@ function adjustCasing(a, b) {
8
27
  return b;
9
28
  }
10
29
  else {
11
- return Object.assign({ casing: a }, b);
30
+ return { casing: a, ...b };
12
31
  }
13
32
  }
14
33
  else if (typeof b === 'string') {
15
- return Object.assign(Object.assign({}, a), { casing: b });
34
+ return { ...a, casing: b };
16
35
  }
17
36
  else {
18
- return Object.assign(Object.assign({}, a), b);
37
+ return { ...a, ...b };
19
38
  }
20
39
  }
21
- exports.adjustCasing = adjustCasing;
22
40
  function lowercase(str) {
23
41
  return str.toLowerCase();
24
42
  }
25
- exports.lowercase = lowercase;
26
43
  function uppercase(str) {
27
44
  return str.toUpperCase();
28
45
  }
29
- exports.uppercase = uppercase;
30
46
  function capitalize(str) {
31
47
  return (str.charAt(0).toUpperCase() + str.slice(1));
32
48
  }
33
- exports.capitalize = capitalize;
34
49
  function uncapitalize(str) {
35
50
  return (str.charAt(0).toLowerCase() + str.slice(1));
36
51
  }
37
- exports.uncapitalize = uncapitalize;
38
52
  /**
39
53
  * Gets the words from a string. Words are separated by capital letters. Leading numbers are removed. Non-alphanumerical characters are removed and interpreted as word seperators. Multiple uppercase letters are interpreted as one word.
40
54
  * @param str The string to get the words from.
@@ -56,7 +70,6 @@ function getWords(str) {
56
70
  // Split into words
57
71
  return (_a = str.match(/[A-Z]{2,}(?=[A-Z0-9-]|$)|[a-zA-Z][a-z]*|[0-9]+/g)) !== null && _a !== void 0 ? _a : [];
58
72
  }
59
- exports.getWords = getWords;
60
73
  /**
61
74
  * Converts a word to a given casing.
62
75
  * @param str The word to convert.
@@ -102,7 +115,6 @@ function wordToCasing(str, casing) {
102
115
  .join('');
103
116
  }
104
117
  }
105
- exports.wordToCasing = wordToCasing;
106
118
  function toCasing(str, casing) {
107
119
  let options;
108
120
  let casingType;
@@ -128,7 +140,6 @@ function toCasing(str, casing) {
128
140
  return wordToCasing(getWords(str).join(''), casingType);
129
141
  }
130
142
  }
131
- exports.toCasing = toCasing;
132
143
  function addPrefixAndSuffix(str, { prefix, suffix }) {
133
144
  if (prefix) {
134
145
  str = prefix + str;
@@ -151,7 +162,7 @@ function addPrefixAndSuffix(str, { prefix, suffix }) {
151
162
  * toCamelCase('Foo bAR', { suffix: 'bar' }) // => 'fooBarbar'
152
163
  */
153
164
  function toCamelCase(str, options) {
154
- const opts = Object.assign({ keepOriginalCase: false }, options);
165
+ const opts = { keepOriginalCase: false, ...options };
155
166
  const words = getWords(str);
156
167
  const camelCase = words
157
168
  .map((word, index) => index === 0
@@ -160,7 +171,6 @@ function toCamelCase(str, options) {
160
171
  .join('');
161
172
  return addPrefixAndSuffix(camelCase, opts);
162
173
  }
163
- exports.toCamelCase = toCamelCase;
164
174
  /**
165
175
  * Converts a string to pascal case.
166
176
  * @param str The string to convert.
@@ -174,14 +184,13 @@ exports.toCamelCase = toCamelCase;
174
184
  * toPascalCase('foo bAR', { suffix: 'bar' }) // => 'FooBarbar'
175
185
  */
176
186
  function toPascalCase(str, options) {
177
- const opts = Object.assign({ keepOriginalCase: false }, options);
187
+ const opts = { keepOriginalCase: false, ...options };
178
188
  const words = getWords(str);
179
189
  const pascalCase = words
180
190
  .map((word) => wordToCasing(word, opts.keepOriginalCase ? 'first-upper' : 'first-upper-then-lower'))
181
191
  .join('');
182
192
  return addPrefixAndSuffix(pascalCase, opts);
183
193
  }
184
- exports.toPascalCase = toPascalCase;
185
194
  /**
186
195
  * Converts a string to kebab case.
187
196
  * @param str The string to convert.
@@ -196,14 +205,13 @@ exports.toPascalCase = toPascalCase;
196
205
  * toKebabCase('Foo bAR', { suffix: 'bar' }) // => 'foo-barbar'
197
206
  */
198
207
  function toKebabCase(str, options) {
199
- const opts = Object.assign({ wordCasing: 'all-lower' }, options);
208
+ const opts = { wordCasing: 'all-lower', ...options };
200
209
  const words = getWords(str);
201
210
  const kebabCase = words
202
211
  .map((word, index) => { var _a; return index === 0 ? wordToCasing(word, (_a = opts.firstWordCasing) !== null && _a !== void 0 ? _a : opts.wordCasing) : wordToCasing(word, opts.wordCasing); })
203
212
  .join('-');
204
213
  return addPrefixAndSuffix(kebabCase, opts);
205
214
  }
206
- exports.toKebabCase = toKebabCase;
207
215
  /**
208
216
  * Converts a string to snake case.
209
217
  * @param str The string to convert.
@@ -218,14 +226,13 @@ exports.toKebabCase = toKebabCase;
218
226
  * toSnakeCase('Foo bAR', { suffix: 'bar' }) // => 'FOO_BARbar'
219
227
  */
220
228
  function toSnakeCase(str, options) {
221
- const opts = Object.assign({ wordCasing: 'all-upper' }, options);
229
+ const opts = { wordCasing: 'all-upper', ...options };
222
230
  const words = getWords(str);
223
231
  const snakeCase = words
224
232
  .map((word, index) => { var _a; return index === 0 ? wordToCasing(word, (_a = opts.firstWordCasing) !== null && _a !== void 0 ? _a : opts.wordCasing) : wordToCasing(word, opts.wordCasing); })
225
233
  .join('_');
226
234
  return addPrefixAndSuffix(snakeCase, opts);
227
235
  }
228
- exports.toSnakeCase = toSnakeCase;
229
236
  /**
230
237
  * Converts a string to a custom case.
231
238
  * @param str The string to convert.
@@ -253,7 +260,6 @@ function toCustomCase(str, options) {
253
260
  const customCase = words.map(wordMapFn).join((_a = options.wordSeparator) !== null && _a !== void 0 ? _a : '');
254
261
  return addPrefixAndSuffix(customCase, options);
255
262
  }
256
- exports.toCustomCase = toCustomCase;
257
263
  /**
258
264
  * Escapes a string to be used in a regular expression.
259
265
  * @param str The string to escape.
@@ -261,7 +267,6 @@ exports.toCustomCase = toCustomCase;
261
267
  function escapeRegExp(str) {
262
268
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
263
269
  }
264
- exports.escapeRegExp = escapeRegExp;
265
270
  /**
266
271
  * Removes characters from a string and, if necessary, inserts new characters in their place, returning the spliced string.
267
272
  * @param str The string to splice.
@@ -273,7 +278,6 @@ exports.escapeRegExp = escapeRegExp;
273
278
  function spliceString(str, start, deleteCount, insert) {
274
279
  return str.slice(0, start) + insert + str.slice(start + deleteCount);
275
280
  }
276
- exports.spliceString = spliceString;
277
281
  /**
278
282
  * Removes leading indentation based on the last line. Also removes the first line if it is empty.
279
283
  * @param str The string to trim.
@@ -285,7 +289,6 @@ function trimIndent(str) {
285
289
  return str;
286
290
  return str.replace(/^\r?\n/, '').replace(new RegExp(`^ {0,${indent.length}}`, 'gm'), '');
287
291
  }
288
- exports.trimIndent = trimIndent;
289
292
  function isNonLineBreakWhitespaceChar(char) {
290
293
  return (char === ' ' ||
291
294
  char === '\t' ||
@@ -319,7 +322,6 @@ function trimEnd(str, includeNewLine = true) {
319
322
  ;
320
323
  return str.substring(0, i);
321
324
  }
322
- exports.trimEnd = trimEnd;
323
325
  function trimStart(str, includeNewLine = true) {
324
326
  if (includeNewLine)
325
327
  return str.trimStart();
@@ -328,7 +330,6 @@ function trimStart(str, includeNewLine = true) {
328
330
  ;
329
331
  return str.substring(i);
330
332
  }
331
- exports.trimStart = trimStart;
332
333
  function trim(str, includeNewLine = true) {
333
334
  if (includeNewLine)
334
335
  return str.trim();
@@ -340,7 +341,6 @@ function trim(str, includeNewLine = true) {
340
341
  ;
341
342
  return str.substring(s, e);
342
343
  }
343
- exports.trim = trim;
344
344
  function removeStr(str, rem) {
345
345
  let i = str.indexOf(rem);
346
346
  if (i === -1)
@@ -354,4 +354,3 @@ function removeStr(str, rem) {
354
354
  }
355
355
  return result + str.substring(s);
356
356
  }
357
- exports.removeStr = removeStr;
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.suggestionsAsString = exports.stringUnionToArray = void 0;
3
+ exports.stringUnionToArray = stringUnionToArray;
4
+ exports.suggestionsAsString = suggestionsAsString;
4
5
  function stringUnionToArray() {
5
6
  return (...elements) => elements;
6
7
  }
7
- exports.stringUnionToArray = stringUnionToArray;
8
8
  function suggestionsAsString(value) {
9
9
  return value;
10
10
  }
11
- exports.suggestionsAsString = suggestionsAsString;
@@ -1,2 +1,6 @@
1
1
  import { defaultSourceBuilderOptions } from '../utils/source-builder';
2
- export const defaultOpenApiGeneratorConfig = Object.assign(Object.assign({}, defaultSourceBuilderOptions), { outputDir: 'generated', clearOutputDir: true });
2
+ export const defaultOpenApiGeneratorConfig = {
3
+ ...defaultSourceBuilderOptions,
4
+ outputDir: 'generated',
5
+ clearOutputDir: true,
6
+ };
@@ -1,4 +1,3 @@
1
- import { __awaiter } from "tslib";
2
1
  import { resolve } from 'path';
3
2
  import { emptyDir, ensureDir } from 'fs-extra';
4
3
  import { defaultOpenApiGeneratorConfig } from './config';
@@ -24,46 +23,40 @@ class _OpenApiGenerator {
24
23
  useValue(value, config) {
25
24
  return this.use(ActionProvider.fromValue(value, 'generate'), config);
26
25
  }
27
- generate(data) {
28
- return __awaiter(this, void 0, void 0, function* () {
29
- const absOutputPath = resolve(this._config.outputDir);
30
- if (this._config.clearOutputDir) {
31
- yield emptyDir(absOutputPath);
32
- }
33
- else {
34
- yield ensureDir(absOutputPath);
35
- }
36
- let input = {};
37
- for (const generator of this._providers) {
38
- const context = {
39
- data,
40
- input,
41
- config: this._config,
42
- };
43
- const result = generator.provider.run(context, generator.config);
44
- if (result) {
45
- input = mergeDeep(input, result);
46
- }
26
+ async generate(data) {
27
+ const absOutputPath = resolve(this._config.outputDir);
28
+ if (this._config.clearOutputDir) {
29
+ await emptyDir(absOutputPath);
30
+ }
31
+ else {
32
+ await ensureDir(absOutputPath);
33
+ }
34
+ let input = {};
35
+ for (const generator of this._providers) {
36
+ const context = {
37
+ data,
38
+ input,
39
+ config: this._config,
40
+ };
41
+ const result = generator.provider.run(context, generator.config);
42
+ if (result) {
43
+ input = mergeDeep(input, result);
47
44
  }
48
- return input;
49
- });
45
+ }
46
+ return input;
50
47
  }
51
- parseAndGenerate(...fileNames) {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- const data = yield this._parser.parseApisAndTransform(...fileNames);
54
- return yield this.generate(data);
55
- });
48
+ async parseAndGenerate(...fileNames) {
49
+ const data = await this._parser.parseApisAndTransform(...fileNames);
50
+ return await this.generate(data);
56
51
  }
57
- parseAndGenerateFromDir(dir, options) {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- const filter = (file) => { var _a, _b; return (file.endsWith('.yml') || file.endsWith('.yaml') || file.endsWith('.json')) && ((_b = (_a = options === null || options === void 0 ? void 0 : options.filter) === null || _a === void 0 ? void 0 : _a.call(options, file)) !== null && _b !== void 0 ? _b : true); };
60
- return this.parseAndGenerate(...(yield getFiles(dir, Object.assign(Object.assign({}, options), { filter }))));
61
- });
52
+ async parseAndGenerateFromDir(dir, options) {
53
+ const filter = (file) => { var _a, _b; return (file.endsWith('.yml') || file.endsWith('.yaml') || file.endsWith('.json')) && ((_b = (_a = options === null || options === void 0 ? void 0 : options.filter) === null || _a === void 0 ? void 0 : _a.call(options, file)) !== null && _b !== void 0 ? _b : true); };
54
+ return this.parseAndGenerate(...(await getFiles(dir, { ...options, filter })));
62
55
  }
63
56
  }
64
57
  export class OpenApiGenerator extends _OpenApiGenerator {
65
58
  constructor(config) {
66
- super(Object.assign(Object.assign({}, defaultOpenApiGeneratorConfig), config), [], new OpenApiParser());
59
+ super({ ...defaultOpenApiGeneratorConfig, ...config }, [], new OpenApiParser());
67
60
  }
68
61
  }
69
62
  function mergeDeep(target, ...sources) {
@@ -96,7 +89,7 @@ export class OpenApiGenerationProviderBase {
96
89
  return this.onGenerate(ctx);
97
90
  }
98
91
  getProviderContext(context, config, defaultConfig) {
99
- const c = Object.assign(Object.assign(Object.assign({}, context.config), defaultConfig), config);
92
+ const c = { ...context.config, ...defaultConfig, ...config };
100
93
  return Object.assign(context, {
101
94
  config: c,
102
95
  });
@@ -1,4 +1,3 @@
1
- import { __awaiter } from "tslib";
2
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
2
  import path from 'path';
4
3
  import { cwd } from 'process';
@@ -13,150 +12,138 @@ export class OpenApiParser {
13
12
  constructor() {
14
13
  this._loadedDocuments = new Map();
15
14
  }
16
- parseApisAndTransform(...fileNames) {
17
- return __awaiter(this, void 0, void 0, function* () {
18
- const flatFileNames = [].concat(...fileNames);
19
- const apis = yield Promise.all(flatFileNames.map((fileName) => this.parseApi(fileName)));
20
- const transformed = this.transformApis(apis);
21
- return transformed;
22
- });
15
+ async parseApisAndTransform(...fileNames) {
16
+ const flatFileNames = [].concat(...fileNames);
17
+ const apis = await Promise.all(flatFileNames.map((fileName) => this.parseApi(fileName)));
18
+ const transformed = this.transformApis(apis);
19
+ return transformed;
23
20
  }
24
- parseApi(fileName) {
25
- return __awaiter(this, void 0, void 0, function* () {
26
- const absoluteFilePath = this.isUrl(fileName) ? fileName : path.resolve(cwd(), fileName);
27
- const doc = yield this.loadDocument(absoluteFilePath);
28
- return yield this.dereference(absoluteFilePath, '', doc.document);
29
- });
21
+ async parseApi(fileName) {
22
+ const absoluteFilePath = this.isUrl(fileName) ? fileName : path.resolve(cwd(), fileName);
23
+ const doc = await this.loadDocument(absoluteFilePath);
24
+ return await this.dereference(absoluteFilePath, '', doc.document);
30
25
  }
31
26
  transformApis(apis) {
32
27
  const collectedData = collectOpenApi(apis);
33
28
  const transformedData = transformOpenApi(collectedData);
34
29
  return transformedData;
35
30
  }
36
- dereference(file, path, value) {
37
- return __awaiter(this, void 0, void 0, function* () {
38
- let existingDocument = this._loadedDocuments.get(file);
39
- if (existingDocument) {
40
- const existingComponent = existingDocument.dereferencedComponents.get(path);
41
- if (existingComponent) {
42
- return existingComponent;
43
- }
44
- }
45
- else {
46
- existingDocument = yield this.loadDocument(file);
47
- }
48
- const result = createDerefProxy(value, {
49
- file,
50
- path,
51
- document: existingDocument.dereferencedDocument,
52
- originalComponent: value,
53
- });
54
- existingDocument.dereferencedComponents.set(path, result);
55
- if (value.$ref) {
56
- result.$ref = (yield this.resolveReference(file, value));
31
+ async dereference(file, path, value) {
32
+ let existingDocument = this._loadedDocuments.get(file);
33
+ if (existingDocument) {
34
+ const existingComponent = existingDocument.dereferencedComponents.get(path);
35
+ if (existingComponent) {
36
+ return existingComponent;
57
37
  }
58
- for (const key of Object.keys(value)) {
59
- if (key === '$ref')
60
- continue;
61
- const v = value[key];
62
- if (isNullish(v))
63
- continue;
64
- if (typeof v === 'object') {
65
- if (Array.isArray(v)) {
66
- result[key] = yield Promise.all(v.map((v, index) => __awaiter(this, void 0, void 0, function* () {
67
- if (v && typeof v === 'object') {
68
- return yield this.dereference(file, `${path}/${String(key)}/${index}`, v);
69
- }
70
- else {
71
- return v;
72
- }
73
- })));
74
- }
75
- else {
76
- result[key] = yield this.dereference(file, `${path}/${String(key)}`, v);
77
- }
38
+ }
39
+ else {
40
+ existingDocument = await this.loadDocument(file);
41
+ }
42
+ const result = createDerefProxy(value, {
43
+ file,
44
+ path,
45
+ document: existingDocument.dereferencedDocument,
46
+ originalComponent: value,
47
+ });
48
+ existingDocument.dereferencedComponents.set(path, result);
49
+ if (value.$ref) {
50
+ result.$ref = (await this.resolveReference(file, value));
51
+ }
52
+ for (const key of Object.keys(value)) {
53
+ if (key === '$ref')
54
+ continue;
55
+ const v = value[key];
56
+ if (isNullish(v))
57
+ continue;
58
+ if (typeof v === 'object') {
59
+ if (Array.isArray(v)) {
60
+ result[key] = await Promise.all(v.map(async (v, index) => {
61
+ if (v && typeof v === 'object') {
62
+ return await this.dereference(file, `${path}/${String(key)}/${index}`, v);
63
+ }
64
+ else {
65
+ return v;
66
+ }
67
+ }));
78
68
  }
79
- if (typeof v === 'string' && path.endsWith('/discriminator/mapping')) {
80
- result[key] = yield this.resolveReference(file, { $ref: v });
69
+ else {
70
+ result[key] = await this.dereference(file, `${path}/${String(key)}`, v);
81
71
  }
82
72
  }
83
- return result;
84
- });
85
- }
86
- resolveReference(file, ref) {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- const [refFile, refPath] = ref.$ref.split('#');
89
- let absoluteRefFile = refFile;
90
- if (!/\S/.test(refFile)) {
91
- absoluteRefFile = file;
92
- }
93
- else if (!this.isUrl(refFile)) {
94
- absoluteRefFile = path.resolve(path.dirname(file), refFile);
73
+ if (typeof v === 'string' && path.endsWith('/discriminator/mapping')) {
74
+ result[key] = await this.resolveReference(file, { $ref: v });
95
75
  }
96
- const doc = yield this.loadDocument(absoluteRefFile);
97
- const value = getDeepProperty(doc.document, refPath.replace(/[/]/g, '.'));
98
- if (value && typeof value === 'object') {
99
- return this.dereference(absoluteRefFile, refPath, value);
100
- }
101
- return undefined;
102
- });
76
+ }
77
+ return result;
103
78
  }
104
- loadDocument(fileOrUrl) {
105
- return __awaiter(this, void 0, void 0, function* () {
106
- const existingDocument = this._loadedDocuments.get(fileOrUrl);
107
- if (existingDocument) {
108
- return existingDocument;
109
- }
110
- const documentContent = yield this.getDocumentContent(fileOrUrl);
111
- const extname = path.extname(fileOrUrl).toLowerCase();
112
- let parsedDocument;
113
- if (extname === '.json') {
114
- parsedDocument = this.tryParseJson(documentContent);
115
- }
116
- else if (extname === '.yaml' || extname === '.yml') {
79
+ async resolveReference(file, ref) {
80
+ const [refFile, refPath] = ref.$ref.split('#');
81
+ let absoluteRefFile = refFile;
82
+ if (!/\S/.test(refFile)) {
83
+ absoluteRefFile = file;
84
+ }
85
+ else if (!this.isUrl(refFile)) {
86
+ absoluteRefFile = path.resolve(path.dirname(file), refFile);
87
+ }
88
+ const doc = await this.loadDocument(absoluteRefFile);
89
+ const value = getDeepProperty(doc.document, refPath.replace(/[/]/g, '.'));
90
+ if (value && typeof value === 'object') {
91
+ return this.dereference(absoluteRefFile, refPath, value);
92
+ }
93
+ return undefined;
94
+ }
95
+ async loadDocument(fileOrUrl) {
96
+ const existingDocument = this._loadedDocuments.get(fileOrUrl);
97
+ if (existingDocument) {
98
+ return existingDocument;
99
+ }
100
+ const documentContent = await this.getDocumentContent(fileOrUrl);
101
+ const extname = path.extname(fileOrUrl).toLowerCase();
102
+ let parsedDocument;
103
+ if (extname === '.json') {
104
+ parsedDocument = this.tryParseJson(documentContent);
105
+ }
106
+ else if (extname === '.yaml' || extname === '.yml') {
107
+ parsedDocument = this.tryParseYaml(documentContent);
108
+ }
109
+ else {
110
+ parsedDocument = this.tryParseJson(documentContent);
111
+ if (parsedDocument !== undefined) {
117
112
  parsedDocument = this.tryParseYaml(documentContent);
118
113
  }
119
- else {
120
- parsedDocument = this.tryParseJson(documentContent);
121
- if (parsedDocument !== undefined) {
122
- parsedDocument = this.tryParseYaml(documentContent);
123
- }
124
- }
125
- if (parsedDocument === undefined) {
126
- throw new Error(`Unable to parse ${fileOrUrl}`);
127
- }
128
- const doc = (parsedDocument !== null && parsedDocument !== void 0 ? parsedDocument : {});
129
- const deref = createDerefProxy(doc, {
130
- file: fileOrUrl,
131
- path: '',
132
- originalComponent: doc,
133
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
134
- document: undefined,
135
- });
136
- deref.$src.document = deref;
137
- const loadedDocument = {
138
- file: fileOrUrl,
139
- document: doc,
140
- dereferencedDocument: deref,
141
- dereferencedComponents: new Map(),
142
- };
143
- this._loadedDocuments.set(fileOrUrl, loadedDocument);
144
- return loadedDocument;
114
+ }
115
+ if (parsedDocument === undefined) {
116
+ throw new Error(`Unable to parse ${fileOrUrl}`);
117
+ }
118
+ const doc = (parsedDocument !== null && parsedDocument !== void 0 ? parsedDocument : {});
119
+ const deref = createDerefProxy(doc, {
120
+ file: fileOrUrl,
121
+ path: '',
122
+ originalComponent: doc,
123
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
124
+ document: undefined,
145
125
  });
126
+ deref.$src.document = deref;
127
+ const loadedDocument = {
128
+ file: fileOrUrl,
129
+ document: doc,
130
+ dereferencedDocument: deref,
131
+ dereferencedComponents: new Map(),
132
+ };
133
+ this._loadedDocuments.set(fileOrUrl, loadedDocument);
134
+ return loadedDocument;
146
135
  }
147
- getDocumentContent(fileOrUrl) {
148
- return __awaiter(this, void 0, void 0, function* () {
149
- if (this.isUrl(fileOrUrl)) {
150
- const res = yield nodeFetch(fileOrUrl);
151
- if (!res.ok) {
152
- throw new Error(`Unable to download ${fileOrUrl}: ${res.statusText}`);
153
- }
154
- return yield res.text();
136
+ async getDocumentContent(fileOrUrl) {
137
+ if (this.isUrl(fileOrUrl)) {
138
+ const res = await nodeFetch(fileOrUrl);
139
+ if (!res.ok) {
140
+ throw new Error(`Unable to download ${fileOrUrl}: ${res.statusText}`);
155
141
  }
156
- else {
157
- return (yield fs.readFile(fileOrUrl)).toString();
158
- }
159
- });
142
+ return await res.text();
143
+ }
144
+ else {
145
+ return (await fs.readFile(fileOrUrl)).toString();
146
+ }
160
147
  }
161
148
  isUrl(fileOrUrl) {
162
149
  return /^https?:\/\//i.test(fileOrUrl);
@@ -14,7 +14,10 @@ function transformTag(context, tag, isReference = false) {
14
14
  const ref = tag.$ref ? transformTag(context, tag.$ref, true) : undefined;
15
15
  const id = context.idGenerator.generateId('service');
16
16
  const service = {
17
- $src: Object.assign(Object.assign({}, tag.$src), { component: tag }),
17
+ $src: {
18
+ ...tag.$src,
19
+ component: tag,
20
+ },
18
21
  $ref: ref,
19
22
  id,
20
23
  name: (_a = tag.name) !== null && _a !== void 0 ? _a : id,