@asyncapi/cli 3.4.2 → 3.5.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.
- package/lib/apps/cli/commands/generate/client.d.ts +30 -0
- package/lib/apps/cli/commands/generate/client.js +94 -0
- package/lib/apps/cli/commands/generate/fromTemplate.d.ts +28 -16
- package/lib/apps/cli/commands/generate/fromTemplate.js +29 -296
- package/lib/apps/cli/commands/start/preview.d.ts +1 -0
- package/lib/apps/cli/commands/start/preview.js +1 -1
- package/lib/apps/cli/commands/start/studio.d.ts +1 -0
- package/lib/apps/cli/commands/start/studio.js +1 -1
- package/lib/apps/cli/internal/args/generate.args.d.ts +3 -0
- package/lib/apps/cli/internal/args/generate.args.js +10 -0
- package/lib/apps/cli/internal/base/BaseGeneratorCommand.d.ts +42 -0
- package/lib/apps/cli/internal/base/BaseGeneratorCommand.js +119 -0
- package/lib/apps/cli/internal/flags/generate/clients.flags.d.ts +16 -0
- package/lib/apps/cli/internal/flags/generate/clients.flags.js +8 -0
- package/lib/apps/cli/internal/flags/generate/fromTemplate.flags.d.ts +25 -1
- package/lib/apps/cli/internal/flags/generate/fromTemplate.flags.js +2 -58
- package/lib/apps/cli/internal/flags/generate/sharedFlags.d.ts +16 -0
- package/lib/apps/cli/internal/flags/generate/sharedFlags.js +57 -0
- package/lib/apps/cli/internal/flags/start/preview.flags.d.ts +1 -0
- package/lib/apps/cli/internal/flags/start/preview.flags.js +1 -0
- package/lib/apps/cli/internal/flags/start/studio.flags.d.ts +1 -0
- package/lib/apps/cli/internal/flags/start/studio.flags.js +1 -0
- package/lib/domains/models/Preview.d.ts +1 -1
- package/lib/domains/models/Preview.js +145 -132
- package/lib/domains/models/Studio.d.ts +1 -1
- package/lib/domains/models/Studio.js +115 -100
- package/lib/domains/models/generate/ClientLanguages.d.ts +12 -0
- package/lib/domains/models/generate/ClientLanguages.js +17 -0
- package/lib/domains/models/generate/Flags.d.ts +9 -0
- package/lib/domains/models/generate/Flags.js +2 -0
- package/lib/domains/services/generator.service.d.ts +1 -0
- package/lib/domains/services/generator.service.js +5 -2
- package/lib/utils/generate/flags.d.ts +2 -0
- package/lib/utils/generate/flags.js +14 -0
- package/lib/utils/generate/mapBaseUrl.d.ts +6 -0
- package/lib/utils/generate/mapBaseUrl.js +34 -0
- package/lib/utils/generate/parseParams.d.ts +3 -0
- package/lib/utils/generate/parseParams.js +58 -0
- package/lib/utils/generate/prompts.d.ts +4 -0
- package/lib/utils/generate/prompts.js +77 -0
- package/lib/utils/generate/registry.d.ts +2 -0
- package/lib/utils/generate/registry.js +30 -0
- package/lib/utils/{fileWatcher.d.ts → generate/watcher.d.ts} +3 -0
- package/lib/utils/{fileWatcher.js → generate/watcher.js} +75 -8
- package/oclif.manifest.json +167 -3
- package/package.json +6 -4
- package/scripts/generateTypesForGenerateCommand.js +40 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseGeneratorCommand } from '../../internal/base/BaseGeneratorCommand';
|
|
2
|
+
export default class Client extends BaseGeneratorCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static readonly flags: {
|
|
6
|
+
proxyHost: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
proxyPort: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
9
|
+
'disable-hook': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
'no-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
install: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
debug: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'no-overwrite': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
output: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
'force-write': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
watch: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
param: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
'map-base-url': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
'registry-url': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
'registry-auth': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
'registry-token': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
};
|
|
23
|
+
static args: {
|
|
24
|
+
asyncapi: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
25
|
+
language: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
26
|
+
};
|
|
27
|
+
run(): Promise<void>;
|
|
28
|
+
private parseArgs;
|
|
29
|
+
private getTemplateName;
|
|
30
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const BaseGeneratorCommand_1 = require("../../internal/base/BaseGeneratorCommand");
|
|
6
|
+
// eslint-disable-next-line
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
const generator_v2_1 = require("generator-v2");
|
|
9
|
+
const prompts_1 = require("@clack/prompts");
|
|
10
|
+
const picocolors_1 = require("picocolors");
|
|
11
|
+
const clients_flags_1 = require("../../internal/flags/generate/clients.flags");
|
|
12
|
+
const flags_1 = require("../../../../utils/generate/flags");
|
|
13
|
+
const prompts_2 = require("../../../../utils/generate/prompts");
|
|
14
|
+
const ClientLanguages_1 = require("../../../../domains/models/generate/ClientLanguages");
|
|
15
|
+
const generator_error_1 = require("../../../../errors/generator-error");
|
|
16
|
+
class Client extends BaseGeneratorCommand_1.BaseGeneratorCommand {
|
|
17
|
+
run() {
|
|
18
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
var _a, _b, _c;
|
|
20
|
+
const { args, flags } = yield this.parse(Client); // NOSONAR
|
|
21
|
+
const interactive = !flags['no-interactive'];
|
|
22
|
+
let asyncapi = (_a = args['asyncapi']) !== null && _a !== void 0 ? _a : '';
|
|
23
|
+
let language = args['language'];
|
|
24
|
+
let output = flags.output;
|
|
25
|
+
const { proxyPort, proxyHost } = flags;
|
|
26
|
+
if (interactive) {
|
|
27
|
+
(0, prompts_1.intro)((0, picocolors_1.inverse)('Client generation with AsyncAPI Generator'));
|
|
28
|
+
(0, prompts_1.note)((0, picocolors_1.yellow)('This feature is in the experimental phase. Please provide feedback at: https://github.com/asyncapi/generator/issues'));
|
|
29
|
+
const parsedArgs = yield this.parseArgs(args, output);
|
|
30
|
+
asyncapi = parsedArgs.asyncapi;
|
|
31
|
+
language = parsedArgs.language;
|
|
32
|
+
output = parsedArgs.output;
|
|
33
|
+
}
|
|
34
|
+
const template = this.getTemplateName(language);
|
|
35
|
+
const parsedFlags = (0, flags_1.parseGeneratorFlags)(flags['disable-hook'], flags['param'], flags['map-base-url'], flags['registry-url'], flags['registry-auth'], flags['registry-token']);
|
|
36
|
+
const options = yield this.buildGeneratorOptions(flags, parsedFlags);
|
|
37
|
+
// Apply proxy configuration using base class method
|
|
38
|
+
asyncapi = this.applyProxyConfiguration(asyncapi, proxyHost, proxyPort);
|
|
39
|
+
const asyncapiInput = yield this.loadAsyncAPIInput(asyncapi);
|
|
40
|
+
this.specFile = asyncapiInput;
|
|
41
|
+
this.metricsMetadata.language = language;
|
|
42
|
+
const watchTemplate = flags['watch'];
|
|
43
|
+
const genOption = this.buildGenOption(flags, parsedFlags);
|
|
44
|
+
// Use GeneratorService with new generator (v2) for client generation
|
|
45
|
+
const specification = yield this.loadSpecificationSafely(asyncapi);
|
|
46
|
+
const result = yield this.generatorService.generateUsingNewGenerator(specification, template, output, options, // GeneratorService expects different options interface
|
|
47
|
+
genOption);
|
|
48
|
+
if (!result.success) {
|
|
49
|
+
throw new generator_error_1.GeneratorError(new Error(result.error));
|
|
50
|
+
}
|
|
51
|
+
this.log((_c = (_b = result.data) === null || _b === void 0 ? void 0 : _b.logs) === null || _c === void 0 ? void 0 : _c.join('\n'));
|
|
52
|
+
if (watchTemplate) {
|
|
53
|
+
yield this.handleWatchMode(asyncapi, template, output, options, genOption, interactive);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
parseArgs(args, output) {
|
|
58
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
// Use base class method for common args
|
|
60
|
+
const commonArgs = yield this.parseCommonArgs(args, output);
|
|
61
|
+
let language = args['language'];
|
|
62
|
+
if (!language) {
|
|
63
|
+
const defaultLanguage = (0, ClientLanguages_1.getDefaultLanguage)();
|
|
64
|
+
language = (yield (0, prompts_2.promptForLanguage)(defaultLanguage));
|
|
65
|
+
}
|
|
66
|
+
this.handleCancellation(language);
|
|
67
|
+
return {
|
|
68
|
+
asyncapi: commonArgs.asyncapi,
|
|
69
|
+
language,
|
|
70
|
+
output: commonArgs.output
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getTemplateName(language) {
|
|
75
|
+
var _a;
|
|
76
|
+
const template = (_a = (0, generator_v2_1.listBakedInTemplates)({ type: 'client' }).find((template) => {
|
|
77
|
+
return template.target === language;
|
|
78
|
+
})) === null || _a === void 0 ? void 0 : _a.name;
|
|
79
|
+
if (!template) {
|
|
80
|
+
this.log(`❌ Client generation for "${language}" is not yet available.`);
|
|
81
|
+
this.log(`✅ Available languages: ${ClientLanguages_1.availableLanguages.join(', ')}`);
|
|
82
|
+
this.log('🙏 Help us create the missing one. Start discussion at: https://github.com/asyncapi/generator/issues.');
|
|
83
|
+
this.exit(1);
|
|
84
|
+
}
|
|
85
|
+
return template;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
Client.description = `Generates clients baked-in AsyncAPI Generator. Available for: ${ClientLanguages_1.availableLanguages.join(', ')}. If some language is not supported or you want to improve existing client, join us at https://github.com/asyncapi/generator`;
|
|
89
|
+
Client.examples = [
|
|
90
|
+
'asyncapi generate client javascript asyncapi.yaml --param version=1.0.0 singleFile=true --output ./docs --force-write'
|
|
91
|
+
];
|
|
92
|
+
Client.flags = Object.assign(Object.assign({}, (0, clients_flags_1.clientsFlags)()), BaseGeneratorCommand_1.BaseGeneratorCommand.flags);
|
|
93
|
+
Client.args = Object.assign({ language: core_1.Args.string({ description: `The language you want the client generated for. Available target languages: ${ClientLanguages_1.availableLanguages.join(', ')}`, required: true }) }, BaseGeneratorCommand_1.BaseGeneratorCommand.args);
|
|
94
|
+
exports.default = Client;
|
|
@@ -1,12 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export default class Template extends Command {
|
|
1
|
+
import { BaseGeneratorCommand } from '../../internal/base/BaseGeneratorCommand';
|
|
2
|
+
export default class Template extends BaseGeneratorCommand {
|
|
4
3
|
static description: string;
|
|
5
|
-
private generatorService;
|
|
6
4
|
static examples: string[];
|
|
7
5
|
static readonly flags: {
|
|
8
6
|
proxyHost: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
7
|
proxyPort: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
'use-new-generator': {
|
|
9
|
+
name: string;
|
|
10
|
+
char?: import("@oclif/core/lib/interfaces").AlphabetLowercase | import("@oclif/core/lib/interfaces").AlphabetUppercase;
|
|
11
|
+
summary?: string;
|
|
12
|
+
description: string;
|
|
13
|
+
helpLabel?: string;
|
|
14
|
+
helpGroup?: string;
|
|
15
|
+
env?: string;
|
|
16
|
+
hidden?: boolean;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
dependsOn?: string[];
|
|
19
|
+
exclusive?: string[];
|
|
20
|
+
exactlyOne?: string[];
|
|
21
|
+
relationships?: import("@oclif/core/lib/interfaces/parser").Relationship[];
|
|
22
|
+
deprecated?: true | import("@oclif/core/lib/interfaces").Deprecation;
|
|
23
|
+
aliases?: string[];
|
|
24
|
+
charAliases?: (import("@oclif/core/lib/interfaces").AlphabetLowercase | import("@oclif/core/lib/interfaces").AlphabetUppercase)[];
|
|
25
|
+
deprecateAliases?: boolean;
|
|
26
|
+
noCacheDefault?: boolean;
|
|
27
|
+
atLeastOne?: string[];
|
|
28
|
+
type: "boolean";
|
|
29
|
+
allowNo: boolean;
|
|
30
|
+
default: import("@oclif/core/lib/interfaces/parser").FlagDefault<boolean>;
|
|
31
|
+
parse: (input: boolean, context: import("@oclif/core/lib/interfaces/parser").FlagParserContext, opts: import("@oclif/core/lib/interfaces/parser").FlagProps & import("@oclif/core/lib/interfaces/parser").BooleanFlagProps) => Promise<boolean>;
|
|
32
|
+
};
|
|
10
33
|
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
11
34
|
'disable-hook': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
35
|
'no-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -21,22 +44,11 @@ export default class Template extends Command {
|
|
|
21
44
|
'registry-url': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
45
|
'registry-auth': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
46
|
'registry-token': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
-
'use-new-generator': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
47
|
};
|
|
26
48
|
static args: {
|
|
27
|
-
asyncapi: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
28
49
|
template: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
50
|
+
asyncapi: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
29
51
|
};
|
|
30
|
-
parser: Parser;
|
|
31
52
|
run(): Promise<undefined>;
|
|
32
53
|
private parseArgs;
|
|
33
|
-
private disableHooksParser;
|
|
34
|
-
private parseFlags;
|
|
35
|
-
private registryURLParser;
|
|
36
|
-
private registryValidation;
|
|
37
|
-
private paramParser;
|
|
38
|
-
private mapBaseURLParser;
|
|
39
|
-
private runWatchMode;
|
|
40
|
-
private watcherHandler;
|
|
41
|
-
private getMapBaseUrlToFolderResolver;
|
|
42
54
|
}
|
|
@@ -2,57 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
|
-
const
|
|
6
|
-
// eslint-disable-next-line
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
const generator_1 = tslib_1.__importDefault(require("@asyncapi/generator"));
|
|
9
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
10
|
-
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
5
|
+
const BaseGeneratorCommand_1 = require("../../internal/base/BaseGeneratorCommand");
|
|
11
6
|
const SpecificationFile_1 = require("../../../../domains/models/SpecificationFile");
|
|
12
|
-
const fileWatcher_1 = require("../../../../utils/fileWatcher");
|
|
13
7
|
const validation_error_1 = require("../../../../errors/validation-error");
|
|
14
8
|
const generator_error_1 = require("../../../../errors/generator-error");
|
|
15
|
-
const parser_1 = require("@asyncapi/parser");
|
|
16
9
|
const prompts_1 = require("@clack/prompts");
|
|
17
10
|
const picocolors_1 = require("picocolors");
|
|
18
11
|
const fromTemplate_flags_1 = require("../../internal/flags/generate/fromTemplate.flags");
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
super(...arguments);
|
|
24
|
-
this.generatorService = new generator_service_1.GeneratorService(true);
|
|
25
|
-
this.parser = new parser_1.Parser();
|
|
26
|
-
this.getMapBaseUrlToFolderResolver = (urlToFolder) => {
|
|
27
|
-
return {
|
|
28
|
-
order: 1,
|
|
29
|
-
canRead() {
|
|
30
|
-
return true;
|
|
31
|
-
},
|
|
32
|
-
read(file) {
|
|
33
|
-
const baseUrl = urlToFolder.url;
|
|
34
|
-
const baseDir = urlToFolder.folder;
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
let localpath = file.url;
|
|
37
|
-
localpath = localpath.replace(baseUrl, baseDir);
|
|
38
|
-
try {
|
|
39
|
-
fs_1.default.readFile(localpath, (err, data) => {
|
|
40
|
-
if (err) {
|
|
41
|
-
reject(`Error opening file "${localpath}"`);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
resolve(data);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
catch (err) {
|
|
49
|
-
reject(`Error opening file "${localpath}"`);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
}
|
|
12
|
+
const flags_1 = require("../../../../utils/generate/flags");
|
|
13
|
+
const prompts_2 = require("../../../../utils/generate/prompts");
|
|
14
|
+
const inProgressMsg = 'Generation in progress. Keep calm and wait a bit';
|
|
15
|
+
class Template extends BaseGeneratorCommand_1.BaseGeneratorCommand {
|
|
56
16
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
57
17
|
run() {
|
|
58
18
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
@@ -70,48 +30,30 @@ class Template extends base_1.default {
|
|
|
70
30
|
template = parsedArgs.template;
|
|
71
31
|
output = parsedArgs.output;
|
|
72
32
|
}
|
|
73
|
-
const parsedFlags =
|
|
74
|
-
const options =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
templateParams: parsedFlags.params,
|
|
79
|
-
noOverwriteGlobs: flags['no-overwrite'],
|
|
80
|
-
mapBaseUrlToFolder: parsedFlags.mapBaseUrlToFolder,
|
|
81
|
-
disabledHooks: parsedFlags.disableHooks,
|
|
82
|
-
registry: {
|
|
83
|
-
url: flags['registry-url'],
|
|
84
|
-
auth: flags['registry-auth'],
|
|
85
|
-
token: flags['registry-token'],
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
if (proxyHost && proxyPort) {
|
|
89
|
-
const proxyUrl = `http://${proxyHost}:${proxyPort}`;
|
|
90
|
-
asyncapi = `${asyncapi}+${proxyUrl}`;
|
|
91
|
-
}
|
|
92
|
-
const asyncapiInput = (yield (0, SpecificationFile_1.load)(asyncapi)) || (yield (0, SpecificationFile_1.load)());
|
|
33
|
+
const parsedFlags = (0, flags_1.parseGeneratorFlags)(flags['disable-hook'], flags['param'], flags['map-base-url'], flags['registry-url'], flags['registry-auth'], flags['registry-token']);
|
|
34
|
+
const options = yield this.buildGeneratorOptions(flags, parsedFlags);
|
|
35
|
+
// Apply proxy configuration using base class method
|
|
36
|
+
asyncapi = this.applyProxyConfiguration(asyncapi, proxyHost, proxyPort);
|
|
37
|
+
const asyncapiInput = yield this.loadAsyncAPIInput(asyncapi);
|
|
93
38
|
this.specFile = asyncapiInput;
|
|
94
39
|
this.metricsMetadata.template = template;
|
|
95
40
|
const watchTemplate = flags['watch'];
|
|
96
|
-
const genOption =
|
|
97
|
-
if (flags['map-base-url']) {
|
|
98
|
-
genOption.resolve = {
|
|
99
|
-
resolve: this.getMapBaseUrlToFolderResolver(parsedFlags.mapBaseUrlToFolder),
|
|
100
|
-
};
|
|
101
|
-
}
|
|
41
|
+
const genOption = this.buildGenOption(flags, parsedFlags);
|
|
102
42
|
let specification;
|
|
103
43
|
try {
|
|
104
44
|
specification = yield (0, SpecificationFile_1.load)(asyncapi);
|
|
105
45
|
}
|
|
106
46
|
catch (err) {
|
|
107
47
|
return this.error(new validation_error_1.ValidationError({
|
|
48
|
+
// eslint-disable-next-line sonarjs/no-duplicate-string
|
|
108
49
|
type: 'invalid-file',
|
|
109
50
|
filepath: asyncapi,
|
|
110
51
|
}), { exit: 1 });
|
|
111
52
|
}
|
|
112
53
|
if (flags['use-new-generator']) {
|
|
113
|
-
this.log(
|
|
114
|
-
const result = yield this.generatorService.generateUsingNewGenerator(specification, template, output, options,
|
|
54
|
+
this.log(inProgressMsg);
|
|
55
|
+
const result = yield this.generatorService.generateUsingNewGenerator(specification, template, output, options, // GeneratorService expects different options interface
|
|
56
|
+
genOption);
|
|
115
57
|
if (!result.success) {
|
|
116
58
|
throw new generator_error_1.GeneratorError(new Error(result.error));
|
|
117
59
|
}
|
|
@@ -120,231 +62,31 @@ class Template extends base_1.default {
|
|
|
120
62
|
}
|
|
121
63
|
}
|
|
122
64
|
else {
|
|
123
|
-
const result = yield this.generatorService.generate(specification, template, output, options,
|
|
65
|
+
const result = yield this.generatorService.generate(specification, template, output, options, // GeneratorService expects different options interface
|
|
66
|
+
genOption, interactive);
|
|
124
67
|
if (!result.success) {
|
|
125
68
|
throw new generator_error_1.GeneratorError(new Error(result.error));
|
|
126
69
|
}
|
|
127
70
|
}
|
|
128
71
|
if (watchTemplate) {
|
|
129
|
-
|
|
130
|
-
yield this.runWatchMode(asyncapi, template, output, watcherHandler);
|
|
72
|
+
yield this.handleWatchMode(asyncapi, template, output, options, genOption, interactive);
|
|
131
73
|
}
|
|
132
74
|
});
|
|
133
75
|
}
|
|
134
76
|
parseArgs(args, output) {
|
|
135
77
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
136
|
-
|
|
78
|
+
// Use base class method for common args
|
|
79
|
+
const commonArgs = yield this.parseCommonArgs(args, output);
|
|
137
80
|
let template = args['template'];
|
|
138
|
-
const cancellationMessage = 'Operation cancelled';
|
|
139
|
-
if (!asyncapi) {
|
|
140
|
-
asyncapi = yield (0, prompts_1.text)({
|
|
141
|
-
message: 'Please provide the path to the AsyncAPI document',
|
|
142
|
-
placeholder: 'asyncapi.yaml',
|
|
143
|
-
defaultValue: 'asyncapi.yaml',
|
|
144
|
-
validate(value) {
|
|
145
|
-
if (!value) {
|
|
146
|
-
return 'The path to the AsyncAPI document is required';
|
|
147
|
-
}
|
|
148
|
-
else if (!fs_1.default.existsSync(value)) {
|
|
149
|
-
return 'The file does not exist';
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
if ((0, prompts_1.isCancel)(asyncapi)) {
|
|
155
|
-
this.error(cancellationMessage, { exit: 1 });
|
|
156
|
-
}
|
|
157
81
|
if (!template) {
|
|
158
|
-
template = yield (0,
|
|
159
|
-
message: 'Please provide the name of the generator template',
|
|
160
|
-
placeholder: '@asyncapi/html-template',
|
|
161
|
-
defaultValue: '@asyncapi/html-template',
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
if (!output) {
|
|
165
|
-
output = (yield (0, prompts_1.text)({
|
|
166
|
-
message: 'Please provide the output directory',
|
|
167
|
-
placeholder: './docs',
|
|
168
|
-
validate(value) {
|
|
169
|
-
if (!value) {
|
|
170
|
-
return 'The output directory is required';
|
|
171
|
-
}
|
|
172
|
-
else if (typeof value !== 'string') {
|
|
173
|
-
return 'The output directory must be a string';
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
}));
|
|
177
|
-
}
|
|
178
|
-
if ((0, prompts_1.isCancel)(output) || (0, prompts_1.isCancel)(template)) {
|
|
179
|
-
this.error(cancellationMessage, { exit: 1 });
|
|
180
|
-
}
|
|
181
|
-
return { asyncapi, template, output };
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
disableHooksParser(inputs) {
|
|
185
|
-
if (!inputs) {
|
|
186
|
-
return {};
|
|
187
|
-
}
|
|
188
|
-
const disableHooks = {};
|
|
189
|
-
for (const input of inputs) {
|
|
190
|
-
const [hookType, hookNames] = input.split(/=/);
|
|
191
|
-
if (!hookType) {
|
|
192
|
-
throw new Error('Invalid --disable-hook flag. It must be in the format of: --disable-hook <hookType> or --disable-hook <hookType>=<hookName1>,<hookName2>,...');
|
|
193
|
-
}
|
|
194
|
-
if (hookNames) {
|
|
195
|
-
disableHooks[String(hookType)] = hookNames.split(',');
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
disableHooks[String(hookType)] = true;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return disableHooks;
|
|
202
|
-
}
|
|
203
|
-
parseFlags(disableHooks, params, mapBaseUrl, registryUrl, registryAuth, registryToken) {
|
|
204
|
-
return {
|
|
205
|
-
params: this.paramParser(params),
|
|
206
|
-
disableHooks: this.disableHooksParser(disableHooks),
|
|
207
|
-
mapBaseUrlToFolder: this.mapBaseURLParser(mapBaseUrl),
|
|
208
|
-
registryURLValidation: this.registryURLParser(registryUrl),
|
|
209
|
-
registryAuthentication: this.registryValidation(registryUrl, registryAuth, registryToken),
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
registryURLParser(input) {
|
|
213
|
-
if (!input) {
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
const isURL = /^https?:/;
|
|
217
|
-
if (!isURL.test(input.toLowerCase())) {
|
|
218
|
-
throw new Error('Invalid --registry-url flag. The param requires a valid http/https url.');
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
registryValidation(registryUrl, registryAuth, registryToken) {
|
|
222
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
223
|
-
if (!registryUrl) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
try {
|
|
227
|
-
const response = yield fetch(registryUrl);
|
|
228
|
-
if (response.status === 401 && !registryAuth && !registryToken) {
|
|
229
|
-
this.error('You Need to pass either registryAuth in username:password encoded in Base64 or need to pass registryToken', { exit: 1 });
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
this.error(`Can't fetch registryURL: ${registryUrl}`, { exit: 1 });
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
paramParser(inputs) {
|
|
238
|
-
if (!inputs) {
|
|
239
|
-
return {};
|
|
240
|
-
}
|
|
241
|
-
const params = {};
|
|
242
|
-
for (const input of inputs) {
|
|
243
|
-
if (!input.includes('=')) {
|
|
244
|
-
throw new Error(`Invalid param ${input}. It must be in the format of --param name1=value1 name2=value2 `);
|
|
245
|
-
}
|
|
246
|
-
const [paramName, paramValue] = input.split(/=(.+)/, 2);
|
|
247
|
-
params[String(paramName)] = paramValue;
|
|
248
|
-
}
|
|
249
|
-
return params;
|
|
250
|
-
}
|
|
251
|
-
mapBaseURLParser(input) {
|
|
252
|
-
if (!input) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
const mapBaseURLToFolder = {};
|
|
256
|
-
const re = /(.*):(.*)/g; // NOSONAR
|
|
257
|
-
let mapping = [];
|
|
258
|
-
if ((mapping = re.exec(input)) === null || mapping.length !== 3) {
|
|
259
|
-
throw new Error('Invalid --map-base-url flag. A mapping <url>:<folder> with delimiter : expected.');
|
|
260
|
-
}
|
|
261
|
-
mapBaseURLToFolder.url = mapping[1].replace(/\/$/, '');
|
|
262
|
-
mapBaseURLToFolder.folder = path_1.default.resolve(mapping[2]);
|
|
263
|
-
const isURL = /^https?:/;
|
|
264
|
-
if (!isURL.test(mapBaseURLToFolder.url.toLowerCase())) {
|
|
265
|
-
throw new Error('Invalid --map-base-url flag. The mapping <url>:<folder> requires a valid http/https url and valid folder with delimiter `:`.');
|
|
266
|
-
}
|
|
267
|
-
return mapBaseURLToFolder;
|
|
268
|
-
}
|
|
269
|
-
runWatchMode(asyncapi, template, output, watchHandler) {
|
|
270
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
271
|
-
const specification = yield (0, SpecificationFile_1.load)(asyncapi);
|
|
272
|
-
const watchDir = path_1.default.resolve(template);
|
|
273
|
-
const outputPath = path_1.default.resolve(watchDir, output);
|
|
274
|
-
const transpiledTemplatePath = path_1.default.resolve(watchDir, generator_1.default.TRANSPILED_TEMPLATE_LOCATION);
|
|
275
|
-
const ignorePaths = [outputPath, transpiledTemplatePath];
|
|
276
|
-
const specificationFile = specification.getFilePath();
|
|
277
|
-
// Template name is needed as it is not always a part of the cli commad
|
|
278
|
-
// There is a use case that you run generator from a root of the template with `./` path
|
|
279
|
-
let templateName = '';
|
|
280
|
-
try {
|
|
281
|
-
// eslint-disable-next-line
|
|
282
|
-
templateName = require(path_1.default.resolve(watchDir, 'package.json')).name;
|
|
283
|
-
}
|
|
284
|
-
catch (err) {
|
|
285
|
-
// intentional
|
|
286
|
-
}
|
|
287
|
-
let watcher;
|
|
288
|
-
if (specificationFile) {
|
|
289
|
-
// is local AsyncAPI file
|
|
290
|
-
this.log(`[WATCHER] Watching for changes in the template directory ${(0, picocolors_1.magenta)(watchDir)} and in the AsyncAPI file ${(0, picocolors_1.magenta)(specificationFile)}`);
|
|
291
|
-
watcher = new fileWatcher_1.Watcher([specificationFile, watchDir], ignorePaths);
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
this.log(`[WATCHER] Watching for changes in the template directory ${(0, picocolors_1.magenta)(watchDir)}`);
|
|
295
|
-
watcher = new fileWatcher_1.Watcher(watchDir, ignorePaths);
|
|
296
|
-
}
|
|
297
|
-
// Must check template in its installation path in generator to use isLocalTemplate function
|
|
298
|
-
if (!(yield (0, fileWatcher_1.isLocalTemplate)(path_1.default.resolve(generator_1.default.DEFAULT_TEMPLATES_DIR, templateName)))) {
|
|
299
|
-
this.warn(`WARNING: ${template} is a remote template. Changes may be lost on subsequent installations.`);
|
|
300
|
-
}
|
|
301
|
-
yield watcher.watch(watchHandler, (paths) => {
|
|
302
|
-
this.error(`[WATCHER] Could not find the file path ${paths}, are you sure it still exists? If it has been deleted or moved please rerun the generator.`, {
|
|
303
|
-
exit: 1,
|
|
304
|
-
});
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
watcherHandler(asyncapi, template, output, options, genOption, interactive) {
|
|
309
|
-
return (changedFiles) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
310
|
-
console.clear();
|
|
311
|
-
console.log('[WATCHER] Change detected');
|
|
312
|
-
for (const [, value] of Object.entries(changedFiles)) {
|
|
313
|
-
let eventText;
|
|
314
|
-
switch (value.eventType) {
|
|
315
|
-
case 'changed':
|
|
316
|
-
eventText = (0, picocolors_1.green)(value.eventType);
|
|
317
|
-
break;
|
|
318
|
-
case 'removed':
|
|
319
|
-
eventText = (0, picocolors_1.red)(value.eventType);
|
|
320
|
-
break;
|
|
321
|
-
case 'renamed':
|
|
322
|
-
eventText = (0, picocolors_1.yellow)(value.eventType);
|
|
323
|
-
break;
|
|
324
|
-
default:
|
|
325
|
-
eventText = (0, picocolors_1.yellow)(value.eventType);
|
|
326
|
-
}
|
|
327
|
-
this.log(`\t${(0, picocolors_1.magenta)(value.path)} was ${eventText}`);
|
|
328
|
-
}
|
|
329
|
-
let specification;
|
|
330
|
-
try {
|
|
331
|
-
specification = yield (0, SpecificationFile_1.load)(asyncapi);
|
|
332
|
-
}
|
|
333
|
-
catch (err) {
|
|
334
|
-
return this.error(new validation_error_1.ValidationError({
|
|
335
|
-
type: 'invalid-file',
|
|
336
|
-
filepath: asyncapi,
|
|
337
|
-
}), { exit: 1 });
|
|
338
|
-
}
|
|
339
|
-
try {
|
|
340
|
-
const result = yield this.generatorService.generate(specification, template, output, options, genOption, interactive);
|
|
341
|
-
if (!result.success) {
|
|
342
|
-
throw new generator_error_1.GeneratorError(new Error(result.error));
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
catch (err) {
|
|
346
|
-
throw new generator_error_1.GeneratorError(err);
|
|
82
|
+
template = yield (0, prompts_2.promptForTemplate)();
|
|
347
83
|
}
|
|
84
|
+
this.handleCancellation(template);
|
|
85
|
+
return {
|
|
86
|
+
asyncapi: commonArgs.asyncapi,
|
|
87
|
+
template,
|
|
88
|
+
output: commonArgs.output
|
|
89
|
+
};
|
|
348
90
|
});
|
|
349
91
|
}
|
|
350
92
|
}
|
|
@@ -352,15 +94,6 @@ Template.description = 'Generates whatever you want using templates compatible w
|
|
|
352
94
|
Template.examples = [
|
|
353
95
|
'asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template --param version=1.0.0 singleFile=true --output ./docs --force-write',
|
|
354
96
|
];
|
|
355
|
-
Template.flags = Object.assign(Object.assign({}, (0, fromTemplate_flags_1.fromTemplateFlags)()),
|
|
356
|
-
Template.args = {
|
|
357
|
-
asyncapi: core_1.Args.string({
|
|
358
|
-
description: '- Local path, url or context-name pointing to AsyncAPI file',
|
|
359
|
-
required: false,
|
|
360
|
-
}),
|
|
361
|
-
template: core_1.Args.string({
|
|
362
|
-
description: '- Name of the generator template like for example @asyncapi/html-template or https://github.com/asyncapi/html-template',
|
|
363
|
-
required: false,
|
|
364
|
-
}),
|
|
365
|
-
};
|
|
97
|
+
Template.flags = Object.assign(Object.assign({}, (0, fromTemplate_flags_1.fromTemplateFlags)()), BaseGeneratorCommand_1.BaseGeneratorCommand.flags);
|
|
98
|
+
Template.args = Object.assign(Object.assign({}, BaseGeneratorCommand_1.BaseGeneratorCommand.args), { template: core_1.Args.string({ description: '- Name of the generator template like for example @asyncapi/html-template or https://github.com/asyncapi/html-template', required: false }) });
|
|
366
99
|
exports.default = Template;
|
|
@@ -8,6 +8,7 @@ export default class PreviewStudio extends Command {
|
|
|
8
8
|
baseDir: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
9
|
xOrigin: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
suppressLogs: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
noBrowser: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
};
|
|
12
13
|
static readonly args: {
|
|
13
14
|
'spec-file': import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
@@ -26,7 +26,7 @@ class PreviewStudio extends base_1.default {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
this.metricsMetadata.port = previewPort;
|
|
29
|
-
yield (0, Preview_1.startPreview)(filePath, flags.base, flags.baseDir, flags.xOrigin, flags.suppressLogs, previewPort);
|
|
29
|
+
yield (0, Preview_1.startPreview)(filePath, flags.base, flags.baseDir, flags.xOrigin, flags.suppressLogs, previewPort, flags.noBrowser);
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -6,6 +6,7 @@ export default class StartStudio extends Command {
|
|
|
6
6
|
file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
7
|
port: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
'no-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
noBrowser: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
};
|
|
10
11
|
static readonly args: {
|
|
11
12
|
'spec-file': import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateArgs = void 0;
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
exports.generateArgs = {
|
|
6
|
+
asyncapi: core_1.Args.string({
|
|
7
|
+
description: '- Local path, url or context-name pointing to AsyncAPI file',
|
|
8
|
+
required: false
|
|
9
|
+
})
|
|
10
|
+
};
|