juisy 2.0.0-beta.0 → 2.0.0-beta.10

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 (113) hide show
  1. package/LICENSE +661 -0
  2. package/bin/cli/cli.js +6 -4
  3. package/bin/cli/cmds/index.js +10 -10
  4. package/bin/cli/cmds/private/docs/generate-api.js +31 -0
  5. package/bin/cli/cmds/{docs → private/docs}/index.js +4 -6
  6. package/bin/cli/cmds/{print-globals.js → public/print-globals.js} +0 -1
  7. package/bin/cli/index.js +1 -1
  8. package/bin/scripts/prepare.js +22 -0
  9. package/dist/DataExporter.d.ts +6 -0
  10. package/dist/cli/CLIFactory.d.ts +48 -11
  11. package/dist/cli/Command.d.ts +23 -13
  12. package/dist/cli/GlobalSettings.schema.json +1 -0
  13. package/dist/cli/InterfaceUtils.d.ts +8 -2
  14. package/dist/cli/OutputUtils.d.ts +3 -3
  15. package/dist/cli/Plugin.d.ts +21 -0
  16. package/dist/cli/extract-usage.d.ts +7 -1
  17. package/dist/cli/index.d.ts +18 -6
  18. package/dist/cli/index.js +1252 -129
  19. package/dist/cli/plugins/command-handler-injections/augment.d.ts +29 -0
  20. package/dist/cli/{command-visitors → plugins/command-handler-injections/command-visitors}/command-handler-injections.d.ts +1 -1
  21. package/dist/cli/plugins/command-handler-injections/index.d.ts +3 -0
  22. package/dist/cli/plugins/command-meta/augment.d.ts +23 -0
  23. package/dist/cli/{command-visitors/get-command-meta.d.ts → plugins/command-meta/command-visitors/command-meta.d.ts} +1 -1
  24. package/dist/cli/plugins/command-meta/index.d.ts +3 -0
  25. package/dist/cli/plugins/default-command-fallbacks/augment.d.ts +3 -0
  26. package/dist/cli/plugins/default-command-fallbacks/command-visitors/default-command-fallbacks.d.ts +10 -0
  27. package/dist/cli/plugins/default-command-fallbacks/index.d.ts +3 -0
  28. package/dist/cli/plugins/load-env-file/augment.d.ts +9 -0
  29. package/dist/cli/plugins/load-env-file/index.d.ts +3 -0
  30. package/dist/cli/plugins/private-commands/augment.d.ts +6 -0
  31. package/dist/cli/{command-visitors → plugins/private-commands/command-visitors}/private-command.d.ts +1 -1
  32. package/dist/cli/plugins/private-commands/index.d.ts +3 -0
  33. package/dist/cli/plugins/register-bump-version-command/cmds/index.d.ts +3 -0
  34. package/dist/cli/plugins/register-bump-version-command/index.d.ts +3 -0
  35. package/dist/cli/plugins/register-changelog-command/augment.d.ts +110 -0
  36. package/dist/cli/plugins/register-changelog-command/cmds/index.d.ts +3 -0
  37. package/dist/cli/plugins/register-changelog-command/index.d.ts +3 -0
  38. package/dist/cli/plugins/register-docs-commands/augment.d.ts +18 -0
  39. package/dist/cli/plugins/register-docs-commands/cmds/generate-api.d.ts +3 -0
  40. package/dist/cli/plugins/register-docs-commands/cmds/generate-cli.d.ts +3 -0
  41. package/dist/cli/plugins/register-docs-commands/cmds/generate-readme.d.ts +3 -0
  42. package/dist/cli/plugins/register-docs-commands/cmds/index.d.ts +3 -0
  43. package/dist/cli/plugins/register-docs-commands/index.d.ts +3 -0
  44. package/dist/cli/plugins/register-git-hooks-commands/augment.d.ts +40 -0
  45. package/dist/cli/plugins/register-git-hooks-commands/cmds/index.d.ts +3 -0
  46. package/dist/cli/plugins/register-git-hooks-commands/cmds/reset.d.ts +3 -0
  47. package/dist/cli/plugins/register-git-hooks-commands/cmds/sync.d.ts +3 -0
  48. package/dist/cli/plugins/register-git-hooks-commands/index.d.ts +3 -0
  49. package/dist/cli/plugins/register-lint-commands/augment.d.ts +39 -0
  50. package/dist/cli/plugins/register-lint-commands/cmds/commit.d.ts +3 -0
  51. package/dist/cli/plugins/register-lint-commands/cmds/default.d.ts +3 -0
  52. package/dist/cli/plugins/register-lint-commands/cmds/markdown.d.ts +3 -0
  53. package/dist/cli/plugins/register-lint-commands/cmds/staged.d.ts +3 -0
  54. package/dist/cli/plugins/register-lint-commands/index.d.ts +3 -0
  55. package/dist/cli/plugins/register-lint-commands/settings.d.ts +11 -0
  56. package/dist/cli/plugins/register-lint-commands/types.d.ts +26 -0
  57. package/dist/cli/plugins/register-release-command/augment.d.ts +9 -0
  58. package/dist/cli/plugins/register-release-command/cmds/index.d.ts +3 -0
  59. package/dist/cli/plugins/register-release-command/index.d.ts +3 -0
  60. package/dist/cli/plugins/register-test-command/cmds/index.d.ts +3 -0
  61. package/dist/cli/plugins/register-test-command/index.d.ts +3 -0
  62. package/dist/cli/types.d.ts +73 -44
  63. package/dist/cli/utils.d.ts +3 -3
  64. package/dist/eject.d.ts +11 -4
  65. package/dist/index.d.ts +8 -2
  66. package/dist/index.js +80 -76
  67. package/dist/project-globals.d.ts +9 -0
  68. package/dist/templater/index.d.ts +6 -1
  69. package/dist/templater/index.js +18 -31
  70. package/dist/templater/markdown-templater/ReadmeTemplater.d.ts +28 -28
  71. package/dist/templater/markdown-templater/index.d.ts +3 -0
  72. package/dist/templater/types.d.ts +6 -0
  73. package/dist/utils/misc.d.ts +1 -1
  74. package/package.json +201 -179
  75. package/README.md +0 -211
  76. package/bin/cli/cmds/changelog.js +0 -41
  77. package/bin/cli/cmds/docs/generate-api.js +0 -22
  78. package/bin/cli/cmds/docs/generate-cli.js +0 -11
  79. package/bin/cli/cmds/docs/generate-readme.js +0 -11
  80. package/bin/cli/cmds/docs/lint.js +0 -42
  81. package/bin/cli/cmds/eject.js +0 -28
  82. package/bin/cli/cmds/git-hooks/index.js +0 -20
  83. package/bin/cli/cmds/git-hooks/reset.js +0 -48
  84. package/bin/cli/cmds/git-hooks/sync.js +0 -19
  85. package/bin/cli/cmds/release.js +0 -231
  86. package/bin/cli/lib/docs/generate-api-doc.js +0 -78
  87. package/bin/cli/lib/version/update-version.js +0 -52
  88. package/bin/scripts/commit-msg.js +0 -32
  89. package/bin/scripts/pre-commit.js +0 -24
  90. package/dist/cli/command-visitors/index.d.ts +0 -9
  91. package/src/index.js +0 -507
  92. package/template/CHANGELOG.md +0 -0
  93. package/template/bin/cli/cli.js +0 -27
  94. package/template/bin/cli/cmds/changelog.js +0 -71
  95. package/template/bin/cli/cmds/docs.js +0 -30
  96. package/template/bin/cli/cmds/docs_cmds/generate-api.js +0 -75
  97. package/template/bin/cli/cmds/docs_cmds/generate-readme.js +0 -51
  98. package/template/bin/cli/cmds/git-hooks.js +0 -30
  99. package/template/bin/cli/cmds/git_hooks_cmds/reset.js +0 -76
  100. package/template/bin/cli/cmds/git_hooks_cmds/sync.js +0 -44
  101. package/template/bin/cli/cmds/release.js +0 -219
  102. package/template/bin/cli/index.js +0 -7
  103. package/template/bin/cli/lib/docs/generate-api-doc.js +0 -33
  104. package/template/bin/cli/lib/release/generate-release-note.js +0 -3
  105. package/template/bin/cli/lib/version/update-version.js +0 -51
  106. package/template/bin/scripts/commit-msg.js +0 -42
  107. package/template/bin/scripts/pre-commit.js +0 -32
  108. package/template/docs/api/docs.config.js +0 -10
  109. package/template/docs/readme/config.js +0 -22
  110. package/template/docs/readme/readme.js +0 -70
  111. package/template/docs/readme/template.md +0 -53
  112. /package/bin/cli/cmds/{test.js → private/test.js} +0 -0
  113. /package/bin/cli/cmds/{squeeze.js → public/squeeze.js} +0 -0
package/dist/cli/index.js CHANGED
@@ -1,21 +1,312 @@
1
1
  /*!
2
- * juisy v1.4.0
2
+ * juisy v2.0.0-beta.10
3
3
  * Copyright © 2022-Present Hervé Perchec
4
4
  */
5
5
 
6
6
  import { hideBin } from 'yargs/helpers';
7
- import execa from 'execa';
7
+ import deepmerge from 'deepmerge';
8
+ import { pathToFileURL } from 'node:url';
9
+ import fs from 'fs-extra';
10
+ import Yargs from 'yargs/yargs';
11
+ import { findUpSync } from 'find-up';
12
+ import { importSingleTs } from 'import-single-ts';
13
+ import lodashGet from 'lodash.get';
14
+ import { execa } from 'execa';
8
15
  import _prompts from 'prompts';
9
16
  import chalk from 'chalk';
10
17
  import indent from 'indent-string';
11
18
  import _stripAnsi from 'strip-ansi';
12
- import Yargs from 'yargs/yargs';
13
- import deepmerge from 'deepmerge';
19
+ import dotenv from '@dotenvx/dotenvx';
20
+ import semver from 'semver';
21
+ import { getPackageInfo } from 'juisy';
22
+ import kebabcase from 'lodash.kebabcase';
23
+ import { ReadmeTemplater } from 'juisy/templater';
24
+ import path from 'node:path';
25
+ import { ESLint } from 'eslint';
26
+ import fs$1 from 'node:fs';
27
+ import yargsParser from 'yargs-parser';
28
+
29
+ class Plugin {
30
+ constructor(name, pluginObject) {
31
+ this.name = name;
32
+ if (pluginObject.beforeCreate) {
33
+ this.beforeCreate = pluginObject.beforeCreate;
34
+ } else {
35
+ this.beforeCreate = () => {
36
+ };
37
+ }
38
+ if (pluginObject.created) {
39
+ this.created = pluginObject.created;
40
+ } else {
41
+ this.created = () => {
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * The plugin unique name
47
+ */
48
+ name;
49
+ /**
50
+ * The beforeCreate hook (can be async)
51
+ */
52
+ beforeCreate;
53
+ /**
54
+ * The created hook (must be sync)
55
+ */
56
+ created;
57
+ }
58
+
59
+ function createEngine(yargs) {
60
+ const xargs = yargs;
61
+ xargs._isPrivate = false;
62
+ xargs._globalCommandVisitors = {};
63
+ xargs._globalCommandVisitorsEnabled = /* @__PURE__ */ new Set([]);
64
+ xargs._disabledDefaultCommands = /* @__PURE__ */ new Set([]);
65
+ xargs._meta = {
66
+ private: false
67
+ };
68
+ xargs._settings = {};
69
+ const originalCommandMethod = xargs.command;
70
+ xargs.originalCommand = originalCommandMethod;
71
+ xargs.command = command;
72
+ xargs.disableDefaultCommand = disableDefaultCommand;
73
+ xargs.hasDefaultCommand = hasDefaultCommand;
74
+ xargs.globalCommandVisitor = globalCommandVisitor;
75
+ xargs.globalCommandVisitorOptions = globalCommandVisitorOptions;
76
+ xargs.hasGlobalCommandVisitor = hasGlobalCommandVisitor;
77
+ xargs.disableGlobalCommandVisitors = disableGlobalCommandVisitors;
78
+ xargs.enableGlobalCommandVisitors = enableGlobalCommandVisitors;
79
+ xargs.isPrivate = isPrivate;
80
+ xargs.getSettings = getSettings;
81
+ return xargs.strict().help();
82
+ }
83
+ function command(...args) {
84
+ const self = this;
85
+ if (args.length === 1) {
86
+ const visit = (cmdModule) => {
87
+ const cmdObj = {
88
+ ...cmdModule
89
+ };
90
+ let failOnFalsyReturn;
91
+ for (const name of self._globalCommandVisitorsEnabled) {
92
+ const globalVisitor = self._globalCommandVisitors[name];
93
+ if (!globalVisitor(cmdObj, self, globalVisitor.options)) {
94
+ failOnFalsyReturn = true;
95
+ }
96
+ }
97
+ return failOnFalsyReturn ? false : cmdObj;
98
+ };
99
+ if (args[0] instanceof Array) {
100
+ const cmdsArray = [];
101
+ for (const commandModule of args[0]) {
102
+ const visited = visit(commandModule);
103
+ if (visited)
104
+ cmdsArray.push(visited);
105
+ }
106
+ return self.originalCommand(cmdsArray);
107
+ } else {
108
+ const visited = visit(args[0]);
109
+ return visited ? self.originalCommand(visited) : self;
110
+ }
111
+ } else {
112
+ return self.originalCommand(...args);
113
+ }
114
+ }
115
+ function disableDefaultCommand(signature) {
116
+ if (getDefaultCommand(signature)) {
117
+ this._disabledDefaultCommands.add(signature);
118
+ } else {
119
+ throw new Error('Default command: "' + signature + '" does not exist.');
120
+ }
121
+ return this;
122
+ }
123
+ function hasDefaultCommand(signature) {
124
+ return !this._disabledDefaultCommands.has(signature);
125
+ }
126
+ function globalCommandVisitor(name, visitor, defaultOptions = {}) {
127
+ this._globalCommandVisitors[name] = visitor;
128
+ return this.enableGlobalCommandVisitors([name]).globalCommandVisitorOptions(name, defaultOptions);
129
+ }
130
+ function globalCommandVisitorOptions(name, options) {
131
+ this._globalCommandVisitors[name].options = {
132
+ ...this._globalCommandVisitors[name].options,
133
+ ...options
134
+ };
135
+ return this;
136
+ }
137
+ function hasGlobalCommandVisitor(name) {
138
+ return Object.keys(this._globalCommandVisitors).includes(name);
139
+ }
140
+ function disableGlobalCommandVisitors(visitors = []) {
141
+ for (const name of visitors) {
142
+ if (this.hasGlobalCommandVisitor(name)) {
143
+ this._globalCommandVisitorsEnabled.delete(name);
144
+ } else {
145
+ throw new Error('Global command visitor: "' + name + '" not defined.');
146
+ }
147
+ }
148
+ return this;
149
+ }
150
+ function enableGlobalCommandVisitors(visitors = []) {
151
+ for (const name of visitors) {
152
+ if (this.hasGlobalCommandVisitor(name)) {
153
+ this._globalCommandVisitorsEnabled.add(name);
154
+ } else {
155
+ throw new Error('Global command visitor: "' + name + '" not defined.');
156
+ }
157
+ }
158
+ return this;
159
+ }
160
+ function isPrivate() {
161
+ return this._isPrivate;
162
+ }
163
+ function getSettings(path) {
164
+ return path ? lodashGet(this._settings, path) : this._settings;
165
+ }
166
+
167
+ const proxify = (target) => {
168
+ const tmp = new Proxy(target instanceof Array ? [] : {}, {
169
+ // Overwrite Object type getter to 'observe'
170
+ get: (obj, prop) => {
171
+ if (prop in obj) {
172
+ if (resolveSettingsCallbacks[prop]) {
173
+ return resolveSettingsCallbacks[prop](obj[prop]);
174
+ }
175
+ return obj[prop];
176
+ }
177
+ return void 0;
178
+ }
179
+ });
180
+ for (const property in target) {
181
+ tmp[property] = target[property];
182
+ }
183
+ return tmp;
184
+ };
185
+ const defaultGlobalSettings = {
186
+ // ...
187
+ };
188
+ const defaultCommands = [];
189
+ const registeredPlugins = [];
190
+ function defineDefaultCommand(command) {
191
+ defaultCommands.push(command);
192
+ }
193
+ const findCommandIn = (fullSignature, commands) => {
194
+ for (const command of commands) {
195
+ if (command.fullSignature === fullSignature) {
196
+ return command;
197
+ } else {
198
+ if (command.children?.length) {
199
+ const found = findCommandIn(fullSignature, command.children);
200
+ if (found)
201
+ return found;
202
+ }
203
+ }
204
+ }
205
+ };
206
+ const getDefaultCommand = (fullSignature) => {
207
+ return findCommandIn(fullSignature, defaultCommands);
208
+ };
209
+ const resolveSettingsCallbacks = {
210
+ // ...
211
+ };
212
+ function defineSettings(target, settings, options) {
213
+ if (options?.resolve) {
214
+ resolveSettingsCallbacks[target] = options.resolve;
215
+ }
216
+ defaultGlobalSettings[target] = settings;
217
+ }
218
+ async function CLIFactory(builder, options) {
219
+ let settingsPath;
220
+ let globalSettings;
221
+ for (const plugin of registeredPlugins) {
222
+ await plugin.beforeCreate({
223
+ defineDefaultCommand,
224
+ defineSettings,
225
+ builder,
226
+ factoryOptions: options || {}
227
+ });
228
+ }
229
+ if (options?.settingsPath) {
230
+ settingsPath = options.settingsPath;
231
+ }
232
+ const configPath = findUpSync(settingsPath ? [settingsPath] : [
233
+ "dev.config.ts",
234
+ "dev.config.js",
235
+ "dev.config.json",
236
+ "cli.config.ts",
237
+ "cli.config.js",
238
+ "cli.config.json",
239
+ ".clirc.ts",
240
+ ".clirc.js",
241
+ ".clirc.json"
242
+ ]);
243
+ if (settingsPath && !configPath) {
244
+ throw new Error("Unable to find file: " + settingsPath);
245
+ } else if (configPath) {
246
+ if (configPath.endsWith(".ts")) {
247
+ globalSettings = deepmerge(defaultGlobalSettings, await importSingleTs(configPath).then((mod) => mod.default || mod));
248
+ } else if (configPath.endsWith(".json")) {
249
+ globalSettings = deepmerge(defaultGlobalSettings, JSON.parse(fs.readFileSync(configPath).toString()));
250
+ } else {
251
+ globalSettings = deepmerge(defaultGlobalSettings, await import(pathToFileURL(configPath).toString()).then((mod) => mod.default || mod));
252
+ }
253
+ } else {
254
+ globalSettings = defaultGlobalSettings;
255
+ }
256
+ const cli = function(argv) {
257
+ let engine = createEngine(Yargs(argv));
258
+ engine._settings = proxify(globalSettings);
259
+ for (const plugin of registeredPlugins) {
260
+ plugin.created({
261
+ engine,
262
+ builder,
263
+ factoryOptions: options || {}
264
+ });
265
+ }
266
+ engine = builder(engine);
267
+ const rootHandlers = engine.getInternalMethods().getCommandInstance().handlers;
268
+ for (const key in rootHandlers) {
269
+ const handler = rootHandlers[key];
270
+ if (defaultCommands.find((cmdObj) => cmdObj.fullSignature === handler.original)) {
271
+ engine.disableDefaultCommand(handler.original);
272
+ }
273
+ }
274
+ for (const defaultCommand of defaultCommands) {
275
+ if (engine.hasDefaultCommand(defaultCommand.fullSignature)) {
276
+ engine.command({
277
+ // @ts-ignore
278
+ aliases: defaultCommand.commandObject.aliases,
279
+ command: defaultCommand.commandObject.command,
280
+ describe: defaultCommand.commandObject.describe,
281
+ builder: (cli2) => {
282
+ return defaultCommand.commandObject.builder(cli2);
283
+ },
284
+ handler: defaultCommand.commandObject.handler,
285
+ meta: defaultCommand.commandObject.meta,
286
+ middlewares: defaultCommand.commandObject.middlewares
287
+ });
288
+ }
289
+ }
290
+ return engine;
291
+ };
292
+ return cli;
293
+ }
294
+ CLIFactory.use = function(plugin) {
295
+ if (plugin instanceof Plugin) {
296
+ if (registeredPlugins.find((rp) => rp.name === plugin.name)) {
297
+ throw new Error(`CLI plugin "${plugin.name}" is already used`);
298
+ } else {
299
+ registeredPlugins.push(plugin);
300
+ }
301
+ } else {
302
+ throw new Error(`Provided plugin is not an instance of Plugin`);
303
+ }
304
+ };
14
305
 
15
306
  class Command {
16
307
  /**
17
- * Creates a Command instance from object (CommandModule)
18
- * @param {CommandModule} commandObject - The command definition object
308
+ * Creates a Command instance from object (CommandObject)
309
+ * @param {CommandObject} commandObject - The command definition object
19
310
  */
20
311
  constructor(commandObject) {
21
312
  this.command = commandObject.command;
@@ -25,6 +316,7 @@ class Command {
25
316
  this.meta = commandObject.meta;
26
317
  this.builder = commandObject.builder || ((cli) => cli);
27
318
  this.handler = commandObject.handler;
319
+ this.middlewares = commandObject.middlewares;
28
320
  }
29
321
  /**
30
322
  * The command
@@ -53,7 +345,12 @@ class Command {
53
345
  /**
54
346
  * Command handler
55
347
  */
348
+ // @ts-ignore
56
349
  handler;
350
+ /**
351
+ * Command middlewares
352
+ */
353
+ middlewares;
57
354
  }
58
355
 
59
356
  const loading = {
@@ -160,7 +457,7 @@ class OutputUtils {
160
457
  }
161
458
  /**
162
459
  * @param msg - The message to display
163
- * @param {Error} [err] - If provided, throw the error
460
+ * @param err - If provided, throw the error
164
461
  * @description
165
462
  * Display error message. Throws `err` if provided.
166
463
  * @example
@@ -168,7 +465,7 @@ class OutputUtils {
168
465
  * error('No configuration file') // => '[31m⨉ ERROR: No configuration file[0m'
169
466
  * error('No configuration file', error) // => Log and throws error
170
467
  */
171
- static error(msg, err = void 0) {
468
+ static error(msg, err) {
172
469
  OutputUtils.log(OutputUtils.$style.red(`⨉ ERROR: ${msg}`));
173
470
  if (err !== void 0) {
174
471
  OutputUtils.log();
@@ -242,6 +539,7 @@ class InterfaceUtils {
242
539
  * @param {string[]} args - Same as execa second arg
243
540
  * @param {object} [opts] - Options
244
541
  * @returns {Promise<object>} The `execa` Promise
542
+ * @throws {RunError}
245
543
  * @description
246
544
  * Run command (child_process). See also `execa` package documentation
247
545
  * @example
@@ -307,6 +605,888 @@ class InterfaceUtils {
307
605
  static prompts = _prompts;
308
606
  }
309
607
 
608
+ const LoadEnvFile = new Plugin("built-in:load-env-file", {
609
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
610
+ if (factoryOptions.loadEnv !== false) {
611
+ dotenv.config({
612
+ // Default to not verbose, can be overridden
613
+ debug: false,
614
+ verbose: false,
615
+ quiet: true
616
+ });
617
+ }
618
+ }
619
+ });
620
+
621
+ const bumpVersion = new Command({
622
+ command: "bump-version",
623
+ describe: "Bump version in package.json file",
624
+ meta: {
625
+ private: true
626
+ },
627
+ builder: function(cli) {
628
+ cli.option("p", {
629
+ alias: "preid",
630
+ type: "string",
631
+ describe: "Pre-release id",
632
+ requiresArg: true
633
+ });
634
+ return cli;
635
+ },
636
+ async handler(argv) {
637
+ const { $style, step, substep, error } = OutputUtils;
638
+ const { run, prompts, abort } = InterfaceUtils;
639
+ const packageJson = getPackageInfo();
640
+ let targetVersion;
641
+ const currentVersion = packageJson.version;
642
+ packageJson.name;
643
+ const preId = argv.preid || semver.prerelease(currentVersion) && semver.prerelease(currentVersion)[0];
644
+ const inc = (i) => semver.inc(currentVersion, i, preId);
645
+ const versionIncrements = [
646
+ "patch",
647
+ "minor",
648
+ "major",
649
+ ...preId ? ["prepatch", "preminor", "premajor", "prerelease"] : []
650
+ ];
651
+ step("Bump version");
652
+ const { release } = await prompts([
653
+ {
654
+ type: "select",
655
+ name: "release",
656
+ message: "Release type:",
657
+ choices: versionIncrements.map((i) => ({ title: `${i} (${inc(i)})`, value: inc(i) })).concat([{ title: "custom", value: "custom" }])
658
+ }
659
+ ]);
660
+ if (release === "custom") {
661
+ const { version: customVersion } = await prompts([
662
+ {
663
+ type: "text",
664
+ name: "version",
665
+ message: "New custom version:",
666
+ initial: currentVersion,
667
+ validate: (value) => Boolean(semver.valid(value))
668
+ }
669
+ ]);
670
+ targetVersion = customVersion;
671
+ } else {
672
+ targetVersion = release;
673
+ }
674
+ const { yes } = await prompts([
675
+ {
676
+ type: "confirm",
677
+ name: "yes",
678
+ message: `Releasing v${targetVersion}. Confirm?`,
679
+ initial: true
680
+ }
681
+ ]);
682
+ if (!yes) {
683
+ abort();
684
+ return;
685
+ }
686
+ this.log();
687
+ let commandError = false;
688
+ try {
689
+ await run("npm", [
690
+ "--no-git-tag-version",
691
+ "version",
692
+ targetVersion
693
+ ], { stdio: "inherit" });
694
+ } catch (e) {
695
+ commandError = e;
696
+ }
697
+ if (commandError) {
698
+ substep($style.red("❌ An error has occured."), { last: true });
699
+ error("An error has occured.", commandError);
700
+ abort(1);
701
+ } else {
702
+ substep($style.green("✔ Version successfuly bumped"), { last: true });
703
+ this.log();
704
+ }
705
+ }
706
+ });
707
+
708
+ const RegisterBumpVersionCommand = new Plugin("built-in:register-bump-version-command", {
709
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
710
+ defineDefaultCommand({
711
+ fullSignature: "bump-version",
712
+ commandObject: bumpVersion,
713
+ children: []
714
+ });
715
+ }
716
+ });
717
+
718
+ const changelog = new Command({
719
+ command: "changelog",
720
+ describe: "Generate CHANGELOG file",
721
+ meta: {
722
+ private: true
723
+ },
724
+ builder: function(cli) {
725
+ return cli;
726
+ },
727
+ async handler(argv) {
728
+ const { $style, step, substep, error, wait } = OutputUtils;
729
+ const { run } = InterfaceUtils;
730
+ step("Generating changelog");
731
+ const { onReleaseConfig, ...commandOptions } = this.engine.getSettings("changelog");
732
+ const flattenOptions = (options) => {
733
+ const _array = [];
734
+ for (const key in options) {
735
+ if (typeof options[key] === "boolean") {
736
+ _array.push("--" + kebabcase(key));
737
+ } else {
738
+ _array.push("--" + kebabcase(key));
739
+ _array.push(String(options[key]));
740
+ }
741
+ }
742
+ return _array;
743
+ };
744
+ await wait("Generating", async () => {
745
+ try {
746
+ await run("npx", [
747
+ "conventional-changelog",
748
+ ...flattenOptions(commandOptions)
749
+ ], { stdio: "inherit" });
750
+ } catch (e) {
751
+ error("Unable to generate changelog", e);
752
+ }
753
+ });
754
+ substep($style.green("✔ Success"), { last: true });
755
+ this.log();
756
+ }
757
+ });
758
+
759
+ const RegisterChangelogCommand = new Plugin("built-in:register-changelog-command", {
760
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
761
+ defineSettings("changelog", {
762
+ infile: "CHANGELOG.md",
763
+ preset: "angular",
764
+ sameFile: true,
765
+ onReleaseConfig: {}
766
+ });
767
+ defineDefaultCommand({
768
+ fullSignature: "changelog",
769
+ commandObject: changelog,
770
+ children: []
771
+ });
772
+ }
773
+ });
774
+
775
+ const docs = new Command({
776
+ command: "docs <command>",
777
+ describe: "Manage project documentation",
778
+ meta: {
779
+ private: true
780
+ },
781
+ builder(cli) {
782
+ return cli.demandCommand(1, "Command is missing. See help to learn more.");
783
+ },
784
+ handler(argv) {
785
+ }
786
+ });
787
+
788
+ const docsGenerateAPI = new Command({
789
+ command: "generate:api",
790
+ describe: "Generate API docs from source code",
791
+ async handler(argv) {
792
+ const { $style } = OutputUtils;
793
+ this.log($style.yellow("Command not implemented. Read the doc and build your own!"));
794
+ this.log();
795
+ }
796
+ });
797
+
798
+ const docsGenerateCLI = new Command({
799
+ command: "generate:cli",
800
+ describe: "Generate CLI docs",
801
+ builder(cli) {
802
+ cli.option("config", {
803
+ alias: "c",
804
+ describe: "Path to config file",
805
+ type: "string",
806
+ default: "./docs/cli/config.js"
807
+ });
808
+ cli.config(cli.getSettings("docs.cli"));
809
+ return cli;
810
+ },
811
+ async handler(argv) {
812
+ const templater = new ReadmeTemplater(argv.config);
813
+ await templater.generate();
814
+ }
815
+ });
816
+
817
+ const docsGenerateReadme = new Command({
818
+ command: "generate:readme",
819
+ describe: "Generate README.md",
820
+ builder(cli) {
821
+ cli.option("config", {
822
+ alias: "c",
823
+ describe: "Path to config file",
824
+ type: "string",
825
+ default: "./docs/readme/config.js"
826
+ });
827
+ cli.config(cli.getSettings("docs.readme"));
828
+ return cli;
829
+ },
830
+ async handler(argv) {
831
+ const templater = new ReadmeTemplater(argv.config);
832
+ await templater.generate();
833
+ }
834
+ });
835
+
836
+ const RegisterDocsCommands = new Plugin("built-in:register-docs-commands", {
837
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
838
+ defineSettings("docs", {
839
+ readme: {
840
+ config: "./docs/readme/config.js"
841
+ },
842
+ cli: {
843
+ config: "./docs/cli/config.js"
844
+ }
845
+ });
846
+ defineDefaultCommand({
847
+ fullSignature: "docs <command>",
848
+ commandObject: docs,
849
+ children: [
850
+ {
851
+ fullSignature: "docs generate:api",
852
+ commandObject: docsGenerateAPI
853
+ },
854
+ {
855
+ fullSignature: "docs generate:cli",
856
+ commandObject: docsGenerateCLI
857
+ },
858
+ {
859
+ fullSignature: "docs generate:readme",
860
+ commandObject: docsGenerateReadme
861
+ }
862
+ ]
863
+ });
864
+ }
865
+ });
866
+
867
+ const gitHooks = new Command({
868
+ command: "git-hooks <command>",
869
+ describe: "Git relative commands",
870
+ meta: {
871
+ private: true
872
+ },
873
+ builder: function(cli) {
874
+ return cli.demandCommand(1, "Command is missing. See help to learn more.");
875
+ },
876
+ handler: async function(argv) {
877
+ }
878
+ });
879
+
880
+ const gitHooksSync = new Command({
881
+ command: "sync",
882
+ describe: "Sync git hooks",
883
+ builder(cli) {
884
+ return cli;
885
+ },
886
+ async handler(argv) {
887
+ const { $style, error, step, substep } = OutputUtils;
888
+ const { run, abort } = InterfaceUtils;
889
+ step("Sync git hooks");
890
+ const gitHooksConfig = getPackageInfo()["simple-git-hooks"] || this.engine.getSettings("gitHooks");
891
+ const tempConfigFilePath = "./__TEMP_SIMPLE_GIT_HOOKS_CONFIG__.json";
892
+ fs.writeFileSync(path.resolve(tempConfigFilePath), JSON.stringify(gitHooksConfig));
893
+ let commandError = false;
894
+ try {
895
+ await run("npx", [
896
+ "simple-git-hooks",
897
+ tempConfigFilePath
898
+ ], { stdio: "pipe" });
899
+ } catch (e) {
900
+ commandError = e;
901
+ }
902
+ fs.unlinkSync(path.resolve(tempConfigFilePath));
903
+ if (commandError) {
904
+ substep($style.red("❌ Unable to sync git hooks."), { last: true });
905
+ error("Unable to sync git hooks.", commandError);
906
+ abort(1);
907
+ } else {
908
+ substep($style.green("✔ Git hooks successfuly sync"), { last: true });
909
+ this.log();
910
+ }
911
+ }
912
+ });
913
+
914
+ const gitHooksReset = new Command({
915
+ command: "reset",
916
+ describe: "Reset git hooks",
917
+ builder(cli) {
918
+ return cli;
919
+ },
920
+ async handler(argv) {
921
+ const { $style, step, substep } = OutputUtils;
922
+ const { rootDir, run, abort } = InterfaceUtils;
923
+ step("Reset git hooks");
924
+ const tempConfigFilePath = "./__TEMP_SIMPLE_GIT_HOOKS_CONFIG__.json";
925
+ fs.writeFileSync(path.resolve(rootDir, tempConfigFilePath), "{}");
926
+ let commandError = false;
927
+ try {
928
+ await run("npx", [
929
+ "simple-git-hooks",
930
+ tempConfigFilePath
931
+ ], { stdio: "pipe" });
932
+ } catch (e) {
933
+ commandError = e;
934
+ }
935
+ fs.unlinkSync(path.resolve(rootDir, tempConfigFilePath));
936
+ if (commandError) {
937
+ substep($style.red("❌ Unable to reset git hooks."), { last: true });
938
+ abort(1);
939
+ } else {
940
+ substep($style.green("✔ Git hooks successfuly reset"), { last: true });
941
+ this.log();
942
+ }
943
+ }
944
+ });
945
+
946
+ const RegisterGitHooksCommands = new Plugin("built-in:register-git-hooks-commands", {
947
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
948
+ defineSettings("gitHooks", {
949
+ "pre-commit": "node ./bin/scripts/pre-commit.js",
950
+ "commit-msg": "node ./bin/scripts/commit-msg.js ${1}"
951
+ });
952
+ defineDefaultCommand({
953
+ fullSignature: "git-hooks <command>",
954
+ commandObject: gitHooks,
955
+ children: [
956
+ {
957
+ fullSignature: "git-hooks reset",
958
+ commandObject: gitHooksReset
959
+ },
960
+ {
961
+ fullSignature: "git-hooks sync",
962
+ commandObject: gitHooksSync
963
+ }
964
+ ]
965
+ });
966
+ }
967
+ });
968
+
969
+ function resolveESLintSettings(settings = []) {
970
+ return settings;
971
+ }
972
+ function resolveCommitlintSettings(settings = {}) {
973
+ return settings;
974
+ }
975
+ function resolveMarkdownlintSettings(settings = []) {
976
+ const normalizeRootConfig = (config = {}) => {
977
+ return {
978
+ config: {},
979
+ ...config
980
+ };
981
+ };
982
+ const normalizeConfig = (config = {}) => {
983
+ return {
984
+ config: {},
985
+ ...config,
986
+ globs: config.globs
987
+ };
988
+ };
989
+ let resolved = [];
990
+ let rootConfig = {
991
+ config: {}
992
+ };
993
+ const globScopedConfigs = [];
994
+ for (const item of settings) {
995
+ if (!item.globs && typeof rootConfig.config !== "string") {
996
+ rootConfig = deepmerge(rootConfig, item);
997
+ } else if (!(item.globs instanceof Array) || !item.globs.length) {
998
+ throw new Error('lint.markdown configuration: if provided, "globs" property must be a non-empty array');
999
+ } else {
1000
+ globScopedConfigs.push(item);
1001
+ }
1002
+ }
1003
+ resolved.push(normalizeRootConfig(rootConfig));
1004
+ resolved.push(...globScopedConfigs.map(normalizeConfig));
1005
+ return resolved;
1006
+ }
1007
+ function resolveLintStagedSettings(settings = {}) {
1008
+ return settings;
1009
+ }
1010
+ function resolveSettings(settings = {}) {
1011
+ const resolved = {
1012
+ default: resolveESLintSettings(settings.default),
1013
+ commit: resolveCommitlintSettings(settings.commit),
1014
+ markdown: resolveMarkdownlintSettings(settings.markdown),
1015
+ staged: resolveLintStagedSettings(settings.staged)
1016
+ };
1017
+ return resolved;
1018
+ }
1019
+
1020
+ const lint = new Command({
1021
+ command: "lint [files]",
1022
+ describe: "Lint source code",
1023
+ meta: {
1024
+ private: true
1025
+ },
1026
+ builder(cli) {
1027
+ cli.strict(false).option("fix", {
1028
+ alias: "f",
1029
+ describe: "Automatically fix problems",
1030
+ type: "boolean",
1031
+ default: false
1032
+ }).option("config", {
1033
+ alias: "c",
1034
+ describe: "Provide configuration file path",
1035
+ type: "string",
1036
+ requiresArg: true
1037
+ });
1038
+ const lintSettings = cli.getSettings("lint.default");
1039
+ if (lintSettings?.config) {
1040
+ cli.config(lintSettings);
1041
+ }
1042
+ return cli;
1043
+ },
1044
+ async handler(argv) {
1045
+ const { step } = OutputUtils;
1046
+ step("Configuring linter");
1047
+ const lintSettings = this.engine.getSettings("lint.default") || {};
1048
+ const eslintOptions = {
1049
+ fix: !!argv.fix
1050
+ };
1051
+ if (argv.config) {
1052
+ eslintOptions.overrideConfigFile = argv.config;
1053
+ } else {
1054
+ eslintOptions.baseConfig = lintSettings;
1055
+ }
1056
+ const eslint = new ESLint(eslintOptions);
1057
+ step("Linting files");
1058
+ const results = await eslint.lintFiles([argv.files || "."]);
1059
+ if (argv.fix) {
1060
+ step("Fix problems");
1061
+ await ESLint.outputFixes(results);
1062
+ }
1063
+ const formatter = await eslint.loadFormatter("stylish");
1064
+ const resultText = formatter.format(results);
1065
+ console.log(resultText);
1066
+ this.log();
1067
+ }
1068
+ });
1069
+
1070
+ const lintCommit = new Command({
1071
+ command: "lint:commit [input]",
1072
+ describe: "Lint commit message with commitlint. Accepts all options of native commitlint. See also https://github.com/conventional-changelog/commitlint",
1073
+ meta: {
1074
+ private: true
1075
+ },
1076
+ builder(cli) {
1077
+ cli.strict(false).option("config", {
1078
+ // No alias because -c is already used by commitlint cli
1079
+ describe: "Provide configuration file path",
1080
+ type: "string",
1081
+ requiresArg: true
1082
+ });
1083
+ const lintSettings = cli.getSettings("lint.commit");
1084
+ if (lintSettings?.config) {
1085
+ cli.config(lintSettings);
1086
+ }
1087
+ return cli;
1088
+ },
1089
+ async handler(argv) {
1090
+ const { abort, run } = InterfaceUtils;
1091
+ const { $style, step, substep, error } = OutputUtils;
1092
+ step("Configuring commitlint");
1093
+ const lintSettings = this.engine.getSettings("lint.commit");
1094
+ const commitLintCmdArgs = yargsParser([...process.argv].slice(3), {
1095
+ configuration: {
1096
+ "halt-at-non-option": true,
1097
+ "unknown-options-as-args": true
1098
+ }
1099
+ })._.map(String);
1100
+ const tempConfigFilePath = "./__TEMP_COMMITLINT_CONFIG__.json";
1101
+ let tempConfig;
1102
+ if (!commitLintCmdArgs.includes("--config") && !commitLintCmdArgs.includes("-g")) {
1103
+ if (argv.config) {
1104
+ commitLintCmdArgs.push("--config", argv.config);
1105
+ } else {
1106
+ if (lintSettings) {
1107
+ tempConfig = lintSettings;
1108
+ commitLintCmdArgs.push("--config", tempConfigFilePath);
1109
+ fs$1.writeFileSync(path.resolve(tempConfigFilePath), JSON.stringify(tempConfig));
1110
+ }
1111
+ }
1112
+ }
1113
+ let commandError;
1114
+ try {
1115
+ await run("npx", ["commitlint", ...commitLintCmdArgs], { stdio: "pipe" });
1116
+ } catch (e) {
1117
+ commandError = e;
1118
+ }
1119
+ if (tempConfig) {
1120
+ fs$1.unlinkSync(path.resolve(tempConfigFilePath));
1121
+ }
1122
+ if (commandError) {
1123
+ substep($style.red("❌ An error has occured."), { last: true });
1124
+ error("An error has occured.", commandError);
1125
+ } else {
1126
+ substep($style.green("✔ Commit successfuly linted"), { last: true });
1127
+ this.log();
1128
+ }
1129
+ }
1130
+ });
1131
+
1132
+ const lintMarkdown = new Command({
1133
+ command: "lint:markdown",
1134
+ describe: "Lint markdown files with markdownlint-cli2. See also https://github.com/DavidAnson/markdownlint-cli2",
1135
+ meta: {
1136
+ private: true
1137
+ },
1138
+ builder(cli) {
1139
+ cli.strict(false).option("fix", {
1140
+ alias: "f",
1141
+ describe: "Fix the problems",
1142
+ type: "boolean"
1143
+ });
1144
+ return cli;
1145
+ },
1146
+ async handler(argv) {
1147
+ const { abort, run } = InterfaceUtils;
1148
+ const { $style, step, substep, error } = OutputUtils;
1149
+ step("Configuring markdownlint");
1150
+ const configs = this.engine.getSettings("lint.markdown") || [];
1151
+ const rootConfig = configs.splice(configs.findIndex((config) => !config.globs), 1);
1152
+ let commandError;
1153
+ for (const item of configs) {
1154
+ let tempConfig;
1155
+ const mdLintCmdArgs = [...item.globs];
1156
+ const tempConfigFilePath = "__TEMP_MARKDOWNLINT_CONFIG__.markdownlint-cli2.jsonc";
1157
+ if (!item.config) {
1158
+ tempConfig = rootConfig;
1159
+ } else {
1160
+ tempConfig = item.config;
1161
+ }
1162
+ if (typeof tempConfig === "string") {
1163
+ mdLintCmdArgs.push("--config", tempConfig);
1164
+ } else {
1165
+ mdLintCmdArgs.push("--config", tempConfigFilePath);
1166
+ fs$1.writeFileSync(path.resolve(tempConfigFilePath), JSON.stringify(tempConfig));
1167
+ }
1168
+ if (argv.fix) {
1169
+ mdLintCmdArgs.push("--fix");
1170
+ }
1171
+ try {
1172
+ await run("npx", ["markdownlint-cli2", ...mdLintCmdArgs], { stdio: "pipe" });
1173
+ } catch (e) {
1174
+ commandError = e;
1175
+ if (fs$1.existsSync(path.resolve(tempConfigFilePath))) {
1176
+ fs$1.unlinkSync(path.resolve(tempConfigFilePath));
1177
+ }
1178
+ break;
1179
+ }
1180
+ }
1181
+ if (commandError) {
1182
+ substep($style.red("❌ An error has occured."), { last: true });
1183
+ if (commandError.stderr) {
1184
+ console.error(commandError.stderr);
1185
+ } else {
1186
+ error("An error has occured.", commandError);
1187
+ }
1188
+ } else {
1189
+ substep($style.green("✔ Markdown files successfuly linted"), { last: true });
1190
+ this.log();
1191
+ }
1192
+ }
1193
+ });
1194
+
1195
+ const lintStaged = new Command({
1196
+ command: "lint:staged",
1197
+ describe: "Lint staged files with lint-staged. Accepts all options of native lint-staged command. See also https://github.com/okonet/lint-staged",
1198
+ meta: {
1199
+ private: true
1200
+ },
1201
+ builder(cli) {
1202
+ cli.strict(false).option("config", {
1203
+ alias: "c",
1204
+ describe: "Provide configuration file path",
1205
+ type: "string",
1206
+ requiresArg: true
1207
+ });
1208
+ const lintSettings = cli.getSettings("lint.staged");
1209
+ if (lintSettings?.config) {
1210
+ cli.config(lintSettings);
1211
+ }
1212
+ return cli;
1213
+ },
1214
+ async handler(argv) {
1215
+ const { abort, run } = InterfaceUtils;
1216
+ const { $style, step, substep, error } = OutputUtils;
1217
+ step("Configuring lint-staged");
1218
+ const lintSettings = this.engine.getSettings("lint.staged");
1219
+ const lintStagedCmdArgs = [
1220
+ // Pass all native options to lint-staged command
1221
+ ...argv._.map(String)
1222
+ ];
1223
+ const tempConfigFilePath = "./__TEMP_LINT_STAGED_CONFIG__.json";
1224
+ let tempConfig;
1225
+ if (argv.config) {
1226
+ lintStagedCmdArgs.push("--config", argv.config);
1227
+ } else {
1228
+ if (lintSettings) {
1229
+ tempConfig = lintSettings;
1230
+ lintStagedCmdArgs.push("--config", tempConfigFilePath);
1231
+ fs$1.writeFileSync(path.resolve(tempConfigFilePath), JSON.stringify(tempConfig));
1232
+ }
1233
+ }
1234
+ let commandError = false;
1235
+ try {
1236
+ await run("npx", [
1237
+ "lint-staged",
1238
+ ...lintStagedCmdArgs
1239
+ ], { stdio: "inherit" });
1240
+ } catch (e) {
1241
+ commandError = e;
1242
+ }
1243
+ if (tempConfig) {
1244
+ fs$1.unlinkSync(path.resolve(tempConfigFilePath));
1245
+ }
1246
+ if (commandError) {
1247
+ substep($style.red("❌ An error has occured."), { last: true });
1248
+ error("An error has occured.", commandError);
1249
+ abort(1);
1250
+ } else {
1251
+ substep($style.green("✔ Files successfuly linted"), { last: true });
1252
+ this.log();
1253
+ }
1254
+ }
1255
+ });
1256
+
1257
+ const RegisterLintCommands = new Plugin("built-in:register-lint-commands", {
1258
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
1259
+ defineSettings("lint", {
1260
+ default: {
1261
+ config: "eslint.config.js"
1262
+ },
1263
+ commit: {
1264
+ extends: [
1265
+ "@commitlint/config-conventional"
1266
+ ]
1267
+ },
1268
+ markdown: [],
1269
+ staged: {
1270
+ "*.{js,cjs,ts}": [
1271
+ "eslint --fix"
1272
+ ]
1273
+ }
1274
+ }, {
1275
+ resolve: resolveSettings
1276
+ });
1277
+ defineDefaultCommand({
1278
+ fullSignature: "lint",
1279
+ commandObject: lint,
1280
+ children: []
1281
+ });
1282
+ defineDefaultCommand({
1283
+ fullSignature: "lint:commit",
1284
+ commandObject: lintCommit,
1285
+ children: []
1286
+ });
1287
+ defineDefaultCommand({
1288
+ fullSignature: "lint:markdown",
1289
+ commandObject: lintMarkdown,
1290
+ children: []
1291
+ });
1292
+ defineDefaultCommand({
1293
+ fullSignature: "lint:staged",
1294
+ commandObject: lintStaged,
1295
+ children: []
1296
+ });
1297
+ }
1298
+ });
1299
+
1300
+ const release = new Command({
1301
+ command: "release",
1302
+ describe: "Make a release",
1303
+ builder(cli) {
1304
+ cli.option("d", {
1305
+ alias: "dry-run",
1306
+ type: "boolean",
1307
+ describe: "Do not touch or write anything, but show the commands"
1308
+ }).option("i", {
1309
+ alias: "increment",
1310
+ type: "string",
1311
+ describe: 'Increment "major", "minor", "patch", or "pre*" version; or specify version',
1312
+ default: "patch",
1313
+ requiresArg: true
1314
+ }).option("ci", {
1315
+ type: "boolean",
1316
+ describe: "No prompts, no user interaction; activated automatically in CI environments"
1317
+ }).option("only-version", {
1318
+ type: "boolean",
1319
+ describe: "Prompt only for version, no further interaction"
1320
+ }).option("release-version", {
1321
+ type: "boolean",
1322
+ describe: "Print version number to be released"
1323
+ }).option("changelog", {
1324
+ type: "boolean",
1325
+ describe: "Print changelog for the version to be released"
1326
+ }).option("v", {
1327
+ alias: "verbose",
1328
+ type: "boolean",
1329
+ describe: "Verbose output (user hooks output)"
1330
+ }).option("V", {
1331
+ alias: "extra-verbose",
1332
+ type: "boolean",
1333
+ describe: "Extra verbose output (also internal commands output)"
1334
+ });
1335
+ return cli;
1336
+ },
1337
+ async handler(argv) {
1338
+ const { $style, step, substep, error, wait } = OutputUtils;
1339
+ const { abort, run } = InterfaceUtils;
1340
+ step("Prepare for release");
1341
+ const tempConfigFilePath = "./__TEMP_RELEASE_IT_CONFIG__.json";
1342
+ const releaseItCmdArgs = [];
1343
+ let tempConfig;
1344
+ let releaseItConfigFound = false;
1345
+ substep($style.green("Resolving configuration"));
1346
+ const releaseSettings = this.engine.getSettings("release");
1347
+ if (getPackageInfo()["release-it"]) {
1348
+ releaseItConfigFound = true;
1349
+ } else {
1350
+ const searchPlaces = [
1351
+ ".release-it.json",
1352
+ ".release-it.js",
1353
+ ".release-it.ts",
1354
+ ".release-it.cjs",
1355
+ ".release-it.yaml",
1356
+ ".release-it.yml",
1357
+ ".release-it.toml"
1358
+ ];
1359
+ for (const fileName of searchPlaces) {
1360
+ if (fs$1.existsSync(path.resolve(fileName))) {
1361
+ releaseItConfigFound = true;
1362
+ break;
1363
+ }
1364
+ }
1365
+ if (!releaseItConfigFound) {
1366
+ if (releaseSettings.config) {
1367
+ if (typeof releaseSettings.config !== "string") {
1368
+ error("release.config must be path to file as string");
1369
+ abort(1);
1370
+ }
1371
+ releaseItCmdArgs.push("--config", releaseSettings.config);
1372
+ } else {
1373
+ const changelogSettings = this.engine.getSettings("changelog");
1374
+ const { onReleaseConfig, preset, infile, context } = changelogSettings;
1375
+ const releaseItChangelogConfig = {
1376
+ infile: onReleaseConfig.infile || infile,
1377
+ header: onReleaseConfig.header,
1378
+ context: onReleaseConfig.context || (context ? JSON.parse(fs$1.readFileSync(path.resolve(context)).toString()) : {}),
1379
+ preset: {
1380
+ name: preset,
1381
+ ...onReleaseConfig.preset || {}
1382
+ },
1383
+ tagOpts: onReleaseConfig.tagOpts,
1384
+ commitsOpts: onReleaseConfig.commitsOpts,
1385
+ whatBump: onReleaseConfig.whatBump,
1386
+ ignoreRecommendedBump: onReleaseConfig.ignoreRecommendedBump,
1387
+ strictSemVer: onReleaseConfig.strictSemVer
1388
+ };
1389
+ tempConfig = {
1390
+ ...releaseSettings,
1391
+ plugins: {
1392
+ "@release-it/conventional-changelog": releaseItChangelogConfig
1393
+ }
1394
+ };
1395
+ releaseItCmdArgs.push("--config", tempConfigFilePath);
1396
+ }
1397
+ }
1398
+ }
1399
+ if (argv["dry-run"]) {
1400
+ releaseItCmdArgs.push("--dry-run");
1401
+ }
1402
+ if (argv.increment !== void 0) {
1403
+ if (argv.increment === false) {
1404
+ releaseItCmdArgs.push("--no-increment");
1405
+ } else {
1406
+ releaseItCmdArgs.push("--increment");
1407
+ releaseItCmdArgs.push(argv.increment);
1408
+ }
1409
+ }
1410
+ if (argv.ci) {
1411
+ releaseItCmdArgs.push("--ci");
1412
+ }
1413
+ if (argv["only-version"]) {
1414
+ releaseItCmdArgs.push("--only-version");
1415
+ }
1416
+ if (argv["release-version"]) {
1417
+ releaseItCmdArgs.push("--release-version");
1418
+ }
1419
+ if (argv.changelog) {
1420
+ releaseItCmdArgs.push("--changelog");
1421
+ }
1422
+ if (argv.verbose) {
1423
+ releaseItCmdArgs.push("--verbose");
1424
+ }
1425
+ if (argv["extra-verbose"]) {
1426
+ releaseItCmdArgs.push("-VV");
1427
+ }
1428
+ if (!releaseItConfigFound) {
1429
+ fs$1.writeFileSync(path.resolve(tempConfigFilePath), JSON.stringify(tempConfig));
1430
+ }
1431
+ let commandError = false;
1432
+ try {
1433
+ await run("npx", [
1434
+ "release-it",
1435
+ ...releaseItCmdArgs
1436
+ ], { stdio: "inherit" });
1437
+ } catch (e) {
1438
+ commandError = e;
1439
+ }
1440
+ if (!releaseItConfigFound) {
1441
+ fs$1.unlinkSync(path.resolve(tempConfigFilePath));
1442
+ }
1443
+ if (commandError) {
1444
+ substep($style.red("❌ Unable to release."), { last: true });
1445
+ abort(1);
1446
+ } else {
1447
+ substep($style.green("✔ Release successfuly created"), { last: true });
1448
+ this.log();
1449
+ }
1450
+ }
1451
+ });
1452
+
1453
+ const RegisterReleaseCommand = new Plugin("built-in:register-release-command", {
1454
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
1455
+ defineSettings("release", {
1456
+ git: {
1457
+ commitMessage: "chore(release): v${version}",
1458
+ requireBranch: "main",
1459
+ tagAnnotation: "v${version}"
1460
+ }
1461
+ });
1462
+ defineDefaultCommand({
1463
+ fullSignature: "release",
1464
+ commandObject: release,
1465
+ children: []
1466
+ });
1467
+ }
1468
+ });
1469
+
1470
+ const test = new Command({
1471
+ command: "test",
1472
+ describe: "Run tests",
1473
+ async handler(argv) {
1474
+ const { $style } = OutputUtils;
1475
+ this.log($style.yellow("Command not implemented. Read the doc and build your own!"));
1476
+ this.log();
1477
+ }
1478
+ });
1479
+
1480
+ const RegisterTestCommand = new Plugin("built-in:register-test-command", {
1481
+ beforeCreate({ defineDefaultCommand, defineSettings, builder, factoryOptions }) {
1482
+ defineDefaultCommand({
1483
+ fullSignature: "test",
1484
+ commandObject: test,
1485
+ children: []
1486
+ });
1487
+ }
1488
+ });
1489
+
310
1490
  function wrapCommandBuilder(target, builder) {
311
1491
  const _target = target || ((cli) => cli);
312
1492
  return (cli) => {
@@ -320,6 +1500,41 @@ function wrapCommandhandler(target, handler) {
320
1500
  };
321
1501
  }
322
1502
 
1503
+ const visitor$3 = function(commandObject, cli) {
1504
+ const defaultCommand = getDefaultCommand(commandObject.command);
1505
+ if (defaultCommand) {
1506
+ commandObject.builder = wrapCommandBuilder(commandObject.builder, function(_cli) {
1507
+ if (defaultCommand.children?.length) {
1508
+ for (const child of defaultCommand.children) {
1509
+ if (cli.hasDefaultCommand(child.fullSignature)) {
1510
+ cli.command({
1511
+ // @ts-ignore
1512
+ aliases: child.commandObject.aliases,
1513
+ command: child.commandObject.command,
1514
+ describe: child.commandObject.describe,
1515
+ builder: (__cli) => {
1516
+ return child.commandObject.builder(__cli);
1517
+ },
1518
+ handler: child.commandObject.handler,
1519
+ meta: child.commandObject.meta,
1520
+ middlewares: child.commandObject.middlewares
1521
+ });
1522
+ }
1523
+ }
1524
+ }
1525
+ return _cli;
1526
+ });
1527
+ }
1528
+ return commandObject;
1529
+ };
1530
+ const options$3 = {};
1531
+
1532
+ const DefaultCommandFallbacks = new Plugin("built-in:default-command-fallbacks", {
1533
+ created({ engine, builder, factoryOptions }) {
1534
+ engine.globalCommandVisitor("default-command-fallbacks-visitor", visitor$3, options$3);
1535
+ }
1536
+ });
1537
+
323
1538
  const visitor$2 = function(commandObject, cli) {
324
1539
  commandObject.handler = wrapCommandhandler(commandObject.handler, function(args) {
325
1540
  Object.defineProperty(this, "engine", {
@@ -342,11 +1557,11 @@ const visitor$2 = function(commandObject, cli) {
342
1557
  };
343
1558
  const options$2 = {};
344
1559
 
345
- const commandHandlerInjections = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
346
- __proto__: null,
347
- options: options$2,
348
- visitor: visitor$2
349
- }, Symbol.toStringTag, { value: 'Module' }));
1560
+ const CommandHandlerInjections = new Plugin("built-in:command-handler-injections", {
1561
+ created({ engine, builder, factoryOptions }) {
1562
+ engine.globalCommandVisitor("command-handler-injections-visitor", visitor$2, options$2);
1563
+ }
1564
+ });
350
1565
 
351
1566
  const visitor$1 = function(commandObject, cli) {
352
1567
  if (commandObject.meta) {
@@ -360,11 +1575,14 @@ const visitor$1 = function(commandObject, cli) {
360
1575
  };
361
1576
  const options$1 = {};
362
1577
 
363
- const getCommandMeta = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
364
- __proto__: null,
365
- options: options$1,
366
- visitor: visitor$1
367
- }, Symbol.toStringTag, { value: 'Module' }));
1578
+ const CommandMeta = new Plugin("built-in:command-meta", {
1579
+ created({ engine, builder, factoryOptions }) {
1580
+ engine.getMeta = function() {
1581
+ return this._meta;
1582
+ };
1583
+ engine.globalCommandVisitor("command-meta-visitor", visitor$1, options$1);
1584
+ }
1585
+ });
368
1586
 
369
1587
  const visitor = function(commandObject, engine, options2) {
370
1588
  const { metaProp, envKey } = options2;
@@ -385,118 +1603,11 @@ const options = {
385
1603
  envKey: "CLI_ENV"
386
1604
  };
387
1605
 
388
- const privateCommand = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
389
- __proto__: null,
390
- options,
391
- visitor
392
- }, Symbol.toStringTag, { value: 'Module' }));
393
-
394
- const commandVisitors = {
395
- commandHandlerInjections,
396
- getCommandMeta,
397
- privateCommand
398
- };
399
-
400
- function createEngine(yargs) {
401
- const xargs = yargs;
402
- xargs._isPrivate = false;
403
- xargs._globalCommandVisitors = {};
404
- xargs._globalCommandVisitorsEnabled = /* @__PURE__ */ new Set([]);
405
- xargs._meta = {
406
- private: false
407
- };
408
- const originalCommandMethod = xargs.command;
409
- xargs.originalCommand = originalCommandMethod;
410
- xargs.command = command;
411
- xargs.globalCommandVisitor = globalCommandVisitor;
412
- xargs.globalCommandVisitorOptions = globalCommandVisitorOptions;
413
- xargs.hasGlobalCommandVisitor = hasGlobalCommandVisitor;
414
- xargs.disableGlobalCommandVisitors = disableGlobalCommandVisitors;
415
- xargs.enableGlobalCommandVisitors = enableGlobalCommandVisitors;
416
- xargs.isPrivate = isPrivate;
417
- xargs.getMeta = getMeta;
418
- return xargs.globalCommandVisitor("command-handler-injections-visitor", commandVisitors.commandHandlerInjections.visitor, commandVisitors.commandHandlerInjections.options).globalCommandVisitor("get-meta-command-visitor", commandVisitors.getCommandMeta.visitor, commandVisitors.getCommandMeta.options).globalCommandVisitor("private-command-visitor", commandVisitors.privateCommand.visitor, commandVisitors.privateCommand.options).strict().help();
419
- }
420
- function command(...args) {
421
- const self = this;
422
- if (args.length === 1) {
423
- const visit = (cmdModule) => {
424
- const cmdObj = {
425
- ...cmdModule
426
- };
427
- let failOnFalsyReturn;
428
- for (const name of self._globalCommandVisitorsEnabled) {
429
- const globalVisitor = self._globalCommandVisitors[name];
430
- if (!globalVisitor(cmdObj, self, globalVisitor.options)) {
431
- failOnFalsyReturn = true;
432
- }
433
- }
434
- return failOnFalsyReturn ? false : cmdObj;
435
- };
436
- if (args[0] instanceof Array) {
437
- const cmdsArray = [];
438
- for (const commandModule of args[0]) {
439
- const visited = visit(commandModule);
440
- if (visited)
441
- cmdsArray.push(visited);
442
- }
443
- return self.originalCommand(cmdsArray);
444
- } else {
445
- const visited = visit(args[0]);
446
- return visited ? self.originalCommand(visited) : self;
447
- }
448
- } else {
449
- return self.originalCommand(...args);
1606
+ const PrivateCommands = new Plugin("built-in:private-commands", {
1607
+ created({ engine, builder, factoryOptions }) {
1608
+ engine.globalCommandVisitor("private-command-visitor", visitor, options);
450
1609
  }
451
- }
452
- function globalCommandVisitor(name, visitor, defaultOptions = {}) {
453
- this._globalCommandVisitors[name] = visitor;
454
- return this.enableGlobalCommandVisitors([name]).globalCommandVisitorOptions(name, defaultOptions);
455
- }
456
- function globalCommandVisitorOptions(name, options) {
457
- this._globalCommandVisitors[name].options = {
458
- ...this._globalCommandVisitors[name].options,
459
- ...options
460
- };
461
- return this;
462
- }
463
- function hasGlobalCommandVisitor(name) {
464
- return Object.keys(this._globalCommandVisitors).includes(name);
465
- }
466
- function disableGlobalCommandVisitors(visitors = []) {
467
- for (const name of visitors) {
468
- if (this.hasGlobalCommandVisitor(name)) {
469
- this._globalCommandVisitorsEnabled.delete(name);
470
- } else {
471
- throw new Error('Global command visitor: "' + name + '" not defined.');
472
- }
473
- }
474
- return this;
475
- }
476
- function enableGlobalCommandVisitors(visitors = []) {
477
- for (const name of visitors) {
478
- if (this.hasGlobalCommandVisitor(name)) {
479
- this._globalCommandVisitorsEnabled.add(name);
480
- } else {
481
- throw new Error('Global command visitor: "' + name + '" not defined.');
482
- }
483
- }
484
- return this;
485
- }
486
- function isPrivate() {
487
- return this._isPrivate;
488
- }
489
- function getMeta() {
490
- return this._meta;
491
- }
492
-
493
- function CLIFactory(builder) {
494
- const cli = function(argv) {
495
- const engine = createEngine(Yargs(argv));
496
- return builder(engine);
497
- };
498
- return cli;
499
- }
1610
+ });
500
1611
 
501
1612
  async function extractUsage(factory, recursive = false, args = [""], locale = "en") {
502
1613
  const innerYargs = factory([""]);
@@ -555,5 +1666,17 @@ globalThis.CLI = {
555
1666
  InterfaceUtils,
556
1667
  OutputUtils
557
1668
  };
1669
+ CLIFactory.use(LoadEnvFile);
1670
+ CLIFactory.use(RegisterBumpVersionCommand);
1671
+ CLIFactory.use(RegisterChangelogCommand);
1672
+ CLIFactory.use(RegisterDocsCommands);
1673
+ CLIFactory.use(RegisterGitHooksCommands);
1674
+ CLIFactory.use(RegisterLintCommands);
1675
+ CLIFactory.use(RegisterReleaseCommand);
1676
+ CLIFactory.use(RegisterTestCommand);
1677
+ CLIFactory.use(DefaultCommandFallbacks);
1678
+ CLIFactory.use(CommandHandlerInjections);
1679
+ CLIFactory.use(CommandMeta);
1680
+ CLIFactory.use(PrivateCommands);
558
1681
 
559
1682
  export { CLIFactory, Command, InterfaceUtils, OutputUtils, extractUsage };