@asyncapi/cli 4.1.1 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/assets/create-template/templates/default/package-lock.json +4 -3
- package/lib/apps/api/controllers/generate.controller.js +1 -3
- package/lib/apps/cli/commands/convert.d.ts +0 -2
- package/lib/apps/cli/commands/convert.js +9 -14
- package/lib/apps/cli/commands/format.d.ts +1 -3
- package/lib/apps/cli/commands/format.js +7 -10
- package/lib/apps/cli/commands/generate/client.js +5 -5
- package/lib/apps/cli/commands/generate/fromTemplate.d.ts +0 -25
- package/lib/apps/cli/commands/generate/fromTemplate.js +9 -17
- package/lib/apps/cli/commands/generate/models.js +3 -5
- package/lib/apps/cli/commands/optimize.js +11 -12
- package/lib/apps/cli/commands/start/preview.js +1 -1
- package/lib/apps/cli/commands/validate.js +2 -7
- package/lib/apps/cli/internal/base/BaseGeneratorCommand.js +3 -5
- package/lib/apps/cli/internal/base.d.ts +1 -1
- package/lib/apps/cli/internal/base.js +8 -7
- package/lib/apps/cli/internal/flags/generate/fromTemplate.flags.d.ts +0 -25
- package/lib/apps/cli/internal/flags/generate/fromTemplate.flags.js +1 -2
- package/lib/apps/cli/internal/globals.js +2 -1
- package/lib/domains/models/Context.js +3 -1
- package/lib/domains/models/Preview.js +9 -2
- package/lib/domains/models/SpecificationFile.d.ts +12 -0
- package/lib/domains/models/SpecificationFile.js +20 -3
- package/lib/domains/models/Studio.js +9 -2
- package/lib/domains/services/base.service.d.ts +26 -2
- package/lib/domains/services/base.service.js +23 -0
- package/lib/domains/services/convert.service.d.ts +13 -0
- package/lib/domains/services/convert.service.js +14 -3
- package/lib/domains/services/generator.service.d.ts +20 -2
- package/lib/domains/services/generator.service.js +21 -28
- package/lib/domains/services/validation.service.d.ts +16 -0
- package/lib/domains/services/validation.service.js +68 -57
- package/lib/index.d.ts +4 -0
- package/lib/index.js +7 -0
- package/lib/interfaces/index.d.ts +54 -12
- package/lib/utils/error-handler.d.ts +95 -0
- package/lib/utils/error-handler.js +134 -0
- package/lib/utils/proxy.d.ts +29 -0
- package/lib/utils/proxy.js +47 -0
- package/lib/utils/validation.d.ts +103 -0
- package/lib/utils/validation.js +159 -0
- package/oclif.manifest.json +1 -9
- package/package.json +10 -11
- package/scripts/generateTypesForGenerateCommand.js +1 -1
|
@@ -17,6 +17,8 @@ const Context_1 = require("./Context");
|
|
|
17
17
|
const specification_file_1 = require("../../errors/specification-file");
|
|
18
18
|
const context_error_1 = require("../../errors/context-error");
|
|
19
19
|
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
20
|
+
const logger_1 = require("../../utils/logger");
|
|
21
|
+
const error_handler_1 = require("../../utils/error-handler");
|
|
20
22
|
const { readFile, lstat } = fs_1.promises;
|
|
21
23
|
const allowedFileNames = [
|
|
22
24
|
'asyncapi.json',
|
|
@@ -107,6 +109,7 @@ class Specification {
|
|
|
107
109
|
response = yield fetch(targetUrl, fetchOptions);
|
|
108
110
|
}
|
|
109
111
|
catch (err) {
|
|
112
|
+
logger_1.logger.error(`Proxy connection error: ${(0, error_handler_1.getErrorMessage)(err)}`);
|
|
110
113
|
throw new Error('Proxy Connection Error: Unable to establish a connection to the proxy check hostName or PortNumber');
|
|
111
114
|
}
|
|
112
115
|
}
|
|
@@ -118,7 +121,7 @@ class Specification {
|
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
123
|
catch (error) {
|
|
121
|
-
|
|
124
|
+
logger_1.logger.error(`Error loading spec from URL: ${(0, error_handler_1.getErrorMessage)(error)}`);
|
|
122
125
|
throw new specification_file_1.ErrorLoadingSpec('url', targetUrl);
|
|
123
126
|
}
|
|
124
127
|
return new Specification((yield (response === null || response === void 0 ? void 0 : response.text())), {
|
|
@@ -272,6 +275,12 @@ function retrieveFileFormat(content) {
|
|
|
272
275
|
return undefined;
|
|
273
276
|
}
|
|
274
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Converts a JSON or YAML specification to YAML format.
|
|
280
|
+
*
|
|
281
|
+
* @param spec - The specification content as a string
|
|
282
|
+
* @returns The YAML formatted string, or undefined if conversion fails
|
|
283
|
+
*/
|
|
275
284
|
function convertToYaml(spec) {
|
|
276
285
|
try {
|
|
277
286
|
// JS object -> YAML string
|
|
@@ -279,9 +288,16 @@ function convertToYaml(spec) {
|
|
|
279
288
|
return js_yaml_1.default.dump(jsonContent);
|
|
280
289
|
}
|
|
281
290
|
catch (err) {
|
|
282
|
-
|
|
291
|
+
logger_1.logger.error(`Failed to convert spec to YAML: ${(0, error_handler_1.getErrorMessage)(err)}`);
|
|
292
|
+
return undefined;
|
|
283
293
|
}
|
|
284
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Converts a JSON or YAML specification to JSON format.
|
|
297
|
+
*
|
|
298
|
+
* @param spec - The specification content as a string
|
|
299
|
+
* @returns The JSON formatted string, or undefined if conversion fails
|
|
300
|
+
*/
|
|
285
301
|
function convertToJSON(spec) {
|
|
286
302
|
try {
|
|
287
303
|
// JSON or YAML String -> JS object
|
|
@@ -290,6 +306,7 @@ function convertToJSON(spec) {
|
|
|
290
306
|
return JSON.stringify(jsonContent, null, 2);
|
|
291
307
|
}
|
|
292
308
|
catch (err) {
|
|
293
|
-
|
|
309
|
+
logger_1.logger.error(`Failed to convert spec to JSON: ${(0, error_handler_1.getErrorMessage)(err)}`);
|
|
310
|
+
return undefined;
|
|
294
311
|
}
|
|
295
312
|
}
|
|
@@ -9,7 +9,6 @@ const http_1 = require("http");
|
|
|
9
9
|
const ws_1 = require("ws");
|
|
10
10
|
const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
|
|
11
11
|
const open_1 = tslib_1.__importDefault(require("open"));
|
|
12
|
-
const next_1 = tslib_1.__importDefault(require("next"));
|
|
13
12
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
14
13
|
const package_json_1 = require("@asyncapi/studio/package.json");
|
|
15
14
|
const picocolors_1 = require("picocolors");
|
|
@@ -20,6 +19,13 @@ exports.DEFAULT_PORT = 0;
|
|
|
20
19
|
function isValidFilePath(filePath) {
|
|
21
20
|
return (0, fs_1.existsSync)(filePath);
|
|
22
21
|
}
|
|
22
|
+
function resolveStudioNextInstance(studioPath) {
|
|
23
|
+
var _a;
|
|
24
|
+
const resolvedNextPath = require.resolve('next', { paths: [studioPath] });
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires,security/detect-non-literal-require
|
|
26
|
+
const nextModule = require(resolvedNextPath);
|
|
27
|
+
return (_a = nextModule.default) !== null && _a !== void 0 ? _a : nextModule;
|
|
28
|
+
}
|
|
23
29
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
24
30
|
function start(filePath, port = exports.DEFAULT_PORT, noBrowser) {
|
|
25
31
|
if (filePath && !isValidFilePath(filePath)) {
|
|
@@ -27,7 +33,8 @@ function start(filePath, port = exports.DEFAULT_PORT, noBrowser) {
|
|
|
27
33
|
}
|
|
28
34
|
// Locate @asyncapi/studio package
|
|
29
35
|
const studioPath = path_1.default.dirname(require.resolve('@asyncapi/studio/package.json'));
|
|
30
|
-
const
|
|
36
|
+
const nextInstance = resolveStudioNextInstance(studioPath);
|
|
37
|
+
const app = nextInstance({
|
|
31
38
|
dev: false,
|
|
32
39
|
dir: studioPath,
|
|
33
40
|
conf: {
|
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
import { ServiceResult } from '../../interfaces';
|
|
2
|
+
import type { Diagnostic } from '@asyncapi/parser/cjs';
|
|
3
|
+
/**
|
|
4
|
+
* Base service class providing common functionality for all domain services.
|
|
5
|
+
* Provides standardized result handling and error management.
|
|
6
|
+
*/
|
|
2
7
|
export declare abstract class BaseService {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a successful service result with the provided data.
|
|
10
|
+
*
|
|
11
|
+
* @param data - The data to include in the result
|
|
12
|
+
* @returns A successful ServiceResult containing the data
|
|
13
|
+
*/
|
|
3
14
|
protected createSuccessResult<T>(data: T): ServiceResult<T>;
|
|
4
|
-
|
|
5
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Creates an error service result with the provided error message.
|
|
17
|
+
*
|
|
18
|
+
* @param error - The error message
|
|
19
|
+
* @param diagnostics - Optional diagnostics array for validation errors
|
|
20
|
+
* @returns A failed ServiceResult containing the error
|
|
21
|
+
*/
|
|
22
|
+
protected createErrorResult<T>(error: string, diagnostics?: Diagnostic[]): ServiceResult<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Handles service errors by converting them to a standardized error result.
|
|
25
|
+
*
|
|
26
|
+
* @param error - The caught error (can be any type)
|
|
27
|
+
* @returns A failed ServiceResult with the error message
|
|
28
|
+
*/
|
|
29
|
+
protected handleServiceError<T>(error: unknown): Promise<ServiceResult<T>>;
|
|
6
30
|
}
|
|
@@ -2,13 +2,30 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseService = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
/**
|
|
6
|
+
* Base service class providing common functionality for all domain services.
|
|
7
|
+
* Provides standardized result handling and error management.
|
|
8
|
+
*/
|
|
5
9
|
class BaseService {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a successful service result with the provided data.
|
|
12
|
+
*
|
|
13
|
+
* @param data - The data to include in the result
|
|
14
|
+
* @returns A successful ServiceResult containing the data
|
|
15
|
+
*/
|
|
6
16
|
createSuccessResult(data) {
|
|
7
17
|
return {
|
|
8
18
|
success: true,
|
|
9
19
|
data,
|
|
10
20
|
};
|
|
11
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates an error service result with the provided error message.
|
|
24
|
+
*
|
|
25
|
+
* @param error - The error message
|
|
26
|
+
* @param diagnostics - Optional diagnostics array for validation errors
|
|
27
|
+
* @returns A failed ServiceResult containing the error
|
|
28
|
+
*/
|
|
12
29
|
createErrorResult(error, diagnostics) {
|
|
13
30
|
return {
|
|
14
31
|
success: false,
|
|
@@ -16,6 +33,12 @@ class BaseService {
|
|
|
16
33
|
diagnostics,
|
|
17
34
|
};
|
|
18
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Handles service errors by converting them to a standardized error result.
|
|
38
|
+
*
|
|
39
|
+
* @param error - The caught error (can be any type)
|
|
40
|
+
* @returns A failed ServiceResult with the error message
|
|
41
|
+
*/
|
|
19
42
|
handleServiceError(error) {
|
|
20
43
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
21
44
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -7,6 +7,19 @@ export declare class ConversionService extends BaseService {
|
|
|
7
7
|
*/
|
|
8
8
|
convertDocument(specFile: Specification, options: ConversionOptions): Promise<ServiceResult<ConversionResult>>;
|
|
9
9
|
handleLogging(specFile: Specification, flags: ConversionOptions): string;
|
|
10
|
+
/**
|
|
11
|
+
* Formats the converted document for output.
|
|
12
|
+
* Objects are stringified with indentation, strings are returned as-is.
|
|
13
|
+
*
|
|
14
|
+
* @param convertedFile - The converted file content
|
|
15
|
+
* @returns Formatted string representation
|
|
16
|
+
*/
|
|
10
17
|
private formatConvertedFile;
|
|
18
|
+
/**
|
|
19
|
+
* Writes the converted document to the specified output path.
|
|
20
|
+
*
|
|
21
|
+
* @param outputPath - The path to write the file to
|
|
22
|
+
* @param convertedFileFormatted - The formatted content to write
|
|
23
|
+
*/
|
|
11
24
|
handleOutput(outputPath: string, convertedFileFormatted: string): Promise<void>;
|
|
12
25
|
}
|
|
@@ -47,16 +47,27 @@ class ConversionService extends base_service_1.BaseService {
|
|
|
47
47
|
};
|
|
48
48
|
return `🎉 The ${outputMap[flags.format]} from ${(0, picocolors_1.cyan)(sourcePath)} has been successfully converted to AsyncAPI version ${(0, picocolors_1.green)(targetVersion)}!!`;
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Formats the converted document for output.
|
|
52
|
+
* Objects are stringified with indentation, strings are returned as-is.
|
|
53
|
+
*
|
|
54
|
+
* @param convertedFile - The converted file content
|
|
55
|
+
* @returns Formatted string representation
|
|
56
|
+
*/
|
|
51
57
|
formatConvertedFile(convertedFile) {
|
|
52
58
|
return typeof convertedFile === 'object'
|
|
53
59
|
? JSON.stringify(convertedFile, null, 4)
|
|
54
60
|
: convertedFile;
|
|
55
61
|
}
|
|
56
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Writes the converted document to the specified output path.
|
|
64
|
+
*
|
|
65
|
+
* @param outputPath - The path to write the file to
|
|
66
|
+
* @param convertedFileFormatted - The formatted content to write
|
|
67
|
+
*/
|
|
57
68
|
handleOutput(outputPath, convertedFileFormatted) {
|
|
58
69
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
59
|
-
yield fs_1.promises.writeFile(
|
|
70
|
+
yield fs_1.promises.writeFile(outputPath, convertedFileFormatted, {
|
|
60
71
|
encoding: 'utf8',
|
|
61
72
|
});
|
|
62
73
|
});
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { GenerationOptions, GenerationResult, ServiceResult } from '../../interfaces';
|
|
2
2
|
import { Specification } from '../models/SpecificationFile';
|
|
3
3
|
import { BaseService } from './base.service';
|
|
4
|
+
/**
|
|
5
|
+
* Options passed to the generator for code generation.
|
|
6
|
+
*/
|
|
7
|
+
interface GeneratorRunOptions {
|
|
8
|
+
path?: Specification;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
4
11
|
export declare class GeneratorService extends BaseService {
|
|
5
12
|
private defaultInteractive;
|
|
6
13
|
constructor(interactive?: boolean);
|
|
@@ -11,6 +18,17 @@ export declare class GeneratorService extends BaseService {
|
|
|
11
18
|
private verifyTemplateSupportForV3;
|
|
12
19
|
private getGenerationSuccessMessage;
|
|
13
20
|
private checkV3NotSupported;
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Generates code from an AsyncAPI specification using the specified template.
|
|
23
|
+
*
|
|
24
|
+
* @param asyncapi - The AsyncAPI specification to generate from
|
|
25
|
+
* @param template - The template to use for generation
|
|
26
|
+
* @param output - The output directory for generated files
|
|
27
|
+
* @param options - Generator options
|
|
28
|
+
* @param genOption - Additional generator run options
|
|
29
|
+
* @param interactive - Whether to show interactive spinner (default: false)
|
|
30
|
+
* @returns ServiceResult containing generation result or error
|
|
31
|
+
*/
|
|
32
|
+
generate(asyncapi: Specification, template: string, output: string, options: GenerationOptions, genOption?: GeneratorRunOptions, interactive?: boolean): Promise<ServiceResult<GenerationResult>>;
|
|
16
33
|
}
|
|
34
|
+
export {};
|
|
@@ -4,11 +4,11 @@ exports.GeneratorService = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const base_service_1 = require("./base.service");
|
|
6
6
|
const generator_1 = tslib_1.__importDefault(require("@asyncapi/generator"));
|
|
7
|
-
const generator_v2_1 = tslib_1.__importDefault(require("generator-v2"));
|
|
8
7
|
const prompts_1 = require("@clack/prompts");
|
|
9
8
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
10
9
|
const os_1 = tslib_1.__importDefault(require("os"));
|
|
11
10
|
const picocolors_1 = require("picocolors");
|
|
11
|
+
const error_handler_1 = require("../../utils/error-handler");
|
|
12
12
|
class GeneratorService extends base_service_1.BaseService {
|
|
13
13
|
constructor(interactive = false) {
|
|
14
14
|
super();
|
|
@@ -45,48 +45,41 @@ class GeneratorService extends base_service_1.BaseService {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Generates code from an AsyncAPI specification using the specified template.
|
|
50
|
+
*
|
|
51
|
+
* @param asyncapi - The AsyncAPI specification to generate from
|
|
52
|
+
* @param template - The template to use for generation
|
|
53
|
+
* @param output - The output directory for generated files
|
|
54
|
+
* @param options - Generator options
|
|
55
|
+
* @param genOption - Additional generator run options
|
|
56
|
+
* @param interactive - Whether to show interactive spinner (default: false)
|
|
57
|
+
* @returns ServiceResult containing generation result or error
|
|
58
|
+
*/
|
|
59
|
+
generate(asyncapi_1, template_1, output_1, options_1) {
|
|
60
|
+
return tslib_1.__awaiter(this, arguments, void 0, function* (asyncapi, template, output, options, genOption = {}, interactive = this.defaultInteractive) {
|
|
50
61
|
const v3NotSupported = this.checkV3NotSupported(asyncapi, template);
|
|
51
62
|
if (v3NotSupported) {
|
|
52
63
|
return this.createErrorResult(v3NotSupported);
|
|
53
64
|
}
|
|
65
|
+
const logs = [];
|
|
54
66
|
const generator = new generator_1.default(template, output || path_1.default.resolve(os_1.default.tmpdir(), 'asyncapi-generator'), options);
|
|
55
67
|
const s = interactive
|
|
56
68
|
? (0, prompts_1.spinner)()
|
|
57
|
-
: { start: () => null, stop: (
|
|
69
|
+
: { start: () => null, stop: (message) => logs.push(message) };
|
|
58
70
|
s.start('Generation in progress. Keep calm and wait a bit');
|
|
59
71
|
try {
|
|
60
72
|
yield generator.generateFromString(asyncapi.text(), Object.assign(Object.assign({}, genOption), { path: asyncapi }));
|
|
61
73
|
}
|
|
62
74
|
catch (err) {
|
|
63
|
-
console.log(err);
|
|
64
75
|
s.stop('Generation failed');
|
|
65
|
-
|
|
76
|
+
const errorMessage = (0, error_handler_1.getErrorMessage)(err, 'Generation failed');
|
|
77
|
+
const diagnostics = err && typeof err === 'object' && 'diagnostics' in err
|
|
78
|
+
? err.diagnostics
|
|
79
|
+
: undefined;
|
|
80
|
+
return this.createErrorResult(errorMessage, diagnostics);
|
|
66
81
|
}
|
|
67
82
|
s.stop(this.getGenerationSuccessMessage(output));
|
|
68
|
-
return this.createSuccessResult({
|
|
69
|
-
success: true,
|
|
70
|
-
outputPath: output,
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
generateUsingNewGenerator(asyncapi, template, output, options, genOption) {
|
|
75
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const v3NotSupported = this.checkV3NotSupported(asyncapi, template);
|
|
77
|
-
if (v3NotSupported) {
|
|
78
|
-
return this.createErrorResult(v3NotSupported);
|
|
79
|
-
}
|
|
80
|
-
const logs = [];
|
|
81
|
-
const generator = new generator_v2_1.default(template, output || path_1.default.resolve(os_1.default.tmpdir(), 'asyncapi-generator'), options);
|
|
82
|
-
try {
|
|
83
|
-
yield generator.generateFromString(asyncapi.text(), Object.assign(Object.assign({}, genOption), { path: asyncapi }));
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
logs.push('Generation failed');
|
|
87
|
-
return this.createErrorResult(err.message, err.diagnostics);
|
|
88
|
-
}
|
|
89
|
-
logs.push(this.getGenerationSuccessMessage(output));
|
|
90
83
|
return this.createSuccessResult({
|
|
91
84
|
success: true,
|
|
92
85
|
outputPath: output,
|
|
@@ -23,6 +23,22 @@ export declare class ValidationService extends BaseService {
|
|
|
23
23
|
* Validates an AsyncAPI document
|
|
24
24
|
*/
|
|
25
25
|
validateDocument(specFile: Specification, options?: ValidationOptions): Promise<ServiceResult<ValidationResult>>;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a custom parser with specific rules turned off.
|
|
28
|
+
*/
|
|
29
|
+
private buildCustomParser;
|
|
30
|
+
/**
|
|
31
|
+
* Registers all schema parsers for the given parser instance.
|
|
32
|
+
*/
|
|
33
|
+
private registerSchemaParsers;
|
|
34
|
+
/**
|
|
35
|
+
* Builds a parser that suppresses all discovered warnings.
|
|
36
|
+
*/
|
|
37
|
+
private buildParserWithAllWarningsSuppressed;
|
|
38
|
+
/**
|
|
39
|
+
* Builds a parser that suppresses specific warnings, handling invalid rules gracefully.
|
|
40
|
+
*/
|
|
41
|
+
private buildParserWithSpecificWarningsSuppressed;
|
|
26
42
|
/**
|
|
27
43
|
* Helper to build and register a custom parser with suppressed rules
|
|
28
44
|
*/
|
|
@@ -126,13 +126,10 @@ class ValidationService extends base_service_1.BaseService {
|
|
|
126
126
|
var _a, _b, _c;
|
|
127
127
|
super();
|
|
128
128
|
// Create parser with custom GitHub resolver
|
|
129
|
-
const customParserOptions = Object.assign(Object.assign({}, parserOptions), { __unstable: Object.assign({ resolver: {
|
|
130
|
-
cache: false,
|
|
131
|
-
resolvers: [
|
|
129
|
+
const customParserOptions = Object.assign(Object.assign({}, parserOptions), { __unstable: Object.assign(Object.assign({}, parserOptions.__unstable), { resolver: Object.assign(Object.assign({}, (_a = parserOptions.__unstable) === null || _a === void 0 ? void 0 : _a.resolver), { cache: false, resolvers: [
|
|
132
130
|
createHttpWithAuthResolver(),
|
|
133
|
-
...(((
|
|
134
|
-
]
|
|
135
|
-
} }, (_c = parserOptions.__unstable) === null || _c === void 0 ? void 0 : _c.resolver) });
|
|
131
|
+
...(((_c = (_b = parserOptions.__unstable) === null || _b === void 0 ? void 0 : _b.resolver) === null || _c === void 0 ? void 0 : _c.resolvers) || [])
|
|
132
|
+
] }) }) });
|
|
136
133
|
this.parser = new cjs_1.Parser(customParserOptions);
|
|
137
134
|
this.parser.registerSchemaParser((0, openapi_schema_parser_1.OpenAPISchemaParser)());
|
|
138
135
|
this.parser.registerSchemaParser((0, raml_dt_schema_parser_1.RamlDTSchemaParser)());
|
|
@@ -206,63 +203,77 @@ class ValidationService extends base_service_1.BaseService {
|
|
|
206
203
|
});
|
|
207
204
|
}
|
|
208
205
|
/**
|
|
209
|
-
*
|
|
206
|
+
* Creates a custom parser with specific rules turned off.
|
|
210
207
|
*/
|
|
211
|
-
|
|
212
|
-
return
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
cache: false,
|
|
222
|
-
resolvers: [createHttpWithAuthResolver()],
|
|
223
|
-
},
|
|
208
|
+
buildCustomParser(rulesToSuppress) {
|
|
209
|
+
return new cjs_1.Parser({
|
|
210
|
+
ruleset: {
|
|
211
|
+
extends: [],
|
|
212
|
+
rules: Object.fromEntries(rulesToSuppress.map((rule) => [rule, 'off'])),
|
|
213
|
+
},
|
|
214
|
+
__unstable: {
|
|
215
|
+
resolver: {
|
|
216
|
+
cache: false,
|
|
217
|
+
resolvers: [createHttpWithAuthResolver()],
|
|
224
218
|
},
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Registers all schema parsers for the given parser instance.
|
|
224
|
+
*/
|
|
225
|
+
registerSchemaParsers(parser) {
|
|
226
|
+
parser.registerSchemaParser((0, avro_schema_parser_1.AvroSchemaParser)());
|
|
227
|
+
parser.registerSchemaParser((0, openapi_schema_parser_1.OpenAPISchemaParser)());
|
|
228
|
+
parser.registerSchemaParser((0, raml_dt_schema_parser_1.RamlDTSchemaParser)());
|
|
229
|
+
parser.registerSchemaParser((0, protobuf_schema_parser_1.ProtoBuffSchemaParser)());
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Builds a parser that suppresses all discovered warnings.
|
|
233
|
+
*/
|
|
234
|
+
buildParserWithAllWarningsSuppressed(specFile) {
|
|
235
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
236
|
+
const diagnostics = yield this.parser.validate(specFile.text(), {
|
|
237
|
+
source: specFile.getSource(),
|
|
225
238
|
});
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (invalidRules.length > 0) {
|
|
249
|
-
const validRules = suppressedWarnings.filter((rule) => !invalidRules.includes(rule));
|
|
250
|
-
activeParser = buildCustomParser(validRules);
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
throw e;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
// Register schema parsers for active parser
|
|
258
|
-
activeParser.registerSchemaParser((0, avro_schema_parser_1.AvroSchemaParser)());
|
|
259
|
-
activeParser.registerSchemaParser((0, openapi_schema_parser_1.OpenAPISchemaParser)());
|
|
260
|
-
activeParser.registerSchemaParser((0, raml_dt_schema_parser_1.RamlDTSchemaParser)());
|
|
261
|
-
activeParser.registerSchemaParser((0, protobuf_schema_parser_1.ProtoBuffSchemaParser)());
|
|
239
|
+
const allRuleNames = Array.from(new Set(diagnostics
|
|
240
|
+
.map((d) => d.code)
|
|
241
|
+
.filter((c) => typeof c === 'string')));
|
|
242
|
+
return this.buildCustomParser(allRuleNames);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Builds a parser that suppresses specific warnings, handling invalid rules gracefully.
|
|
247
|
+
*/
|
|
248
|
+
buildParserWithSpecificWarningsSuppressed(suppressedWarnings) {
|
|
249
|
+
try {
|
|
250
|
+
return this.buildCustomParser(suppressedWarnings);
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
const msg = e instanceof Error ? e.message : '';
|
|
254
|
+
const matches = [
|
|
255
|
+
...msg.matchAll(/Cannot extend non-existing rule: "([^"]+)"/g),
|
|
256
|
+
];
|
|
257
|
+
const invalidRules = matches.map((m) => m[1]);
|
|
258
|
+
if (invalidRules.length > 0) {
|
|
259
|
+
const validRules = suppressedWarnings.filter((rule) => !invalidRules.includes(rule));
|
|
260
|
+
return this.buildCustomParser(validRules);
|
|
262
261
|
}
|
|
263
|
-
|
|
262
|
+
throw e;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Helper to build and register a custom parser with suppressed rules
|
|
267
|
+
*/
|
|
268
|
+
buildAndRegisterCustomParser(specFile, suppressedWarnings, suppressAllWarnings) {
|
|
269
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
270
|
+
if (!suppressAllWarnings && !suppressedWarnings.length) {
|
|
264
271
|
throw new Error('No rules to suppress provided');
|
|
265
272
|
}
|
|
273
|
+
const activeParser = suppressAllWarnings
|
|
274
|
+
? yield this.buildParserWithAllWarningsSuppressed(specFile)
|
|
275
|
+
: this.buildParserWithSpecificWarningsSuppressed(suppressedWarnings);
|
|
276
|
+
this.registerSchemaParsers(activeParser);
|
|
266
277
|
return activeParser;
|
|
267
278
|
});
|
|
268
279
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
3
4
|
var core_1 = require("@oclif/core");
|
|
4
5
|
Object.defineProperty(exports, "run", { enumerable: true, get: function () { return core_1.run; } });
|
|
6
|
+
// Export utilities for external consumption
|
|
7
|
+
tslib_1.__exportStar(require("./utils/error-handler"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./utils/validation"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./utils/proxy"), exports);
|
|
10
|
+
// Export interfaces
|
|
11
|
+
tslib_1.__exportStar(require("./interfaces"), exports);
|
|
5
12
|
/**
|
|
6
13
|
* For NodeJS < 15, unhandled rejections are treated as warnings.
|
|
7
14
|
* This is required for consistency in error handling.
|