@gunshi/plugin-global 1.0.0-beta.2 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -8
- package/lib/index.d.ts +3 -3
- package/lib/index.js +67 -27
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -127,9 +127,9 @@ Available extensions:
|
|
|
127
127
|
|
|
128
128
|
- **`showHeader(): Awaitable<string | undefined>`**: Display the application header. Returns `undefined` if no `renderHeader` function is provided in the CLI configuration.
|
|
129
129
|
|
|
130
|
-
- **`showUsage(): Awaitable<string | undefined>`**: Display the command usage information. This is automatically called when `--help` is used. Returns `undefined` if no `renderUsage` function is provided.
|
|
130
|
+
- **`showUsage(): Awaitable<string | undefined>`**: Display the command usage information, with the header as its title. This is automatically called when `--help` is used. Returns `undefined` if no `renderUsage` function is provided.
|
|
131
131
|
|
|
132
|
-
- **`showValidationErrors(error: AggregateError): Awaitable<string | undefined>`**: Display validation errors when argument validation fails. Returns `undefined` if `renderValidationErrors` is null.
|
|
132
|
+
- **`showValidationErrors(error: AggregateError): Awaitable<string | undefined>`**: Display validation errors when argument validation fails. The rendered message is printed to stderr, unless it is empty or `usageSilent` is set. Returns `undefined` if `renderValidationErrors` is null.
|
|
133
133
|
|
|
134
134
|
### Usage Example
|
|
135
135
|
|
|
@@ -143,15 +143,12 @@ const command = {
|
|
|
143
143
|
// Access global extensions
|
|
144
144
|
const { showVersion, showHeader } = ctx.extensions[globalId]
|
|
145
145
|
|
|
146
|
+
// Show the custom header before the output of the command (it prints the header itself)
|
|
147
|
+
await showHeader()
|
|
148
|
+
|
|
146
149
|
// Manually show version if needed
|
|
147
150
|
console.log(`Deploying with CLI version: ${showVersion()}`)
|
|
148
151
|
|
|
149
|
-
// Show custom header
|
|
150
|
-
const header = await showHeader()
|
|
151
|
-
if (header) {
|
|
152
|
-
console.log(header)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
152
|
// Your command logic here...
|
|
156
153
|
}
|
|
157
154
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -18,13 +18,13 @@ interface GlobalExtension {
|
|
|
18
18
|
*/
|
|
19
19
|
showHeader: () => Awaitable<string | undefined>;
|
|
20
20
|
/**
|
|
21
|
-
* Show the usage of the application. if `--help` option is specified, it will print the usage to the console.
|
|
21
|
+
* Show the usage of the application, with the header as its title. if `--help` option is specified, it will print the usage to the console.
|
|
22
22
|
*
|
|
23
|
-
* @returns The usage of the application, or `undefined` if the `renderUsage` is not specified.
|
|
23
|
+
* @returns The header and the usage of the application, or `undefined` if the `renderUsage` is not specified.
|
|
24
24
|
*/
|
|
25
25
|
showUsage: () => Awaitable<string | undefined>;
|
|
26
26
|
/**
|
|
27
|
-
* Show validation errors. This is called when argument validation fails.
|
|
27
|
+
* Show validation errors. This is called when argument validation fails. The rendered message is printed to stderr, unless it is empty or `usageSilent` is set.
|
|
28
28
|
*
|
|
29
29
|
* @param error - The aggregate error containing validation failures
|
|
30
30
|
* @returns The rendered error message, or `undefined` if `renderValidationErrors` is null
|
package/lib/index.js
CHANGED
|
@@ -61,6 +61,36 @@ const pluginId = namespacedId("global");
|
|
|
61
61
|
* @license MIT
|
|
62
62
|
*/
|
|
63
63
|
/**
|
|
64
|
+
* The key of the registry in which the core keeps, for the command context of each run, the set of the
|
|
65
|
+
* errors that have been reported to the user. An error in the set tells `cli()` to end without
|
|
66
|
+
* rejecting. The errors are frozen with the command context, so they are not marked themselves. The key
|
|
67
|
+
* is a registered symbol, since `gunshi` and the plugins bundle their own copies.
|
|
68
|
+
*/
|
|
69
|
+
const REPORTED = Symbol.for("gunshi.reported");
|
|
70
|
+
/**
|
|
71
|
+
* Mark an error as reported to the user, in the set that the core keeps for the run of the context.
|
|
72
|
+
*
|
|
73
|
+
* @param ctx - The command context of the run
|
|
74
|
+
* @param error - The error that has been reported
|
|
75
|
+
* @returns `true` if the error is marked, `false` if the core keeps no set for the run
|
|
76
|
+
*/
|
|
77
|
+
function markReported(ctx, error) {
|
|
78
|
+
const reported = globalThis[REPORTED]?.get(ctx);
|
|
79
|
+
if (reported === void 0) return false;
|
|
80
|
+
reported.add(error);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Set the exit code of the process, where the runtime has one (Node.js, Bun and Deno 2 have `process`).
|
|
85
|
+
* The core does not call the APIs of a runtime, so the plugin, which reports the errors, sets it.
|
|
86
|
+
*
|
|
87
|
+
* @param code - The exit code
|
|
88
|
+
*/
|
|
89
|
+
function setExitCode(code) {
|
|
90
|
+
const proc = globalThis.process;
|
|
91
|
+
if (proc != null && typeof proc === "object") proc.exitCode = code;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
64
94
|
* Decorator function to extend the command with global options.
|
|
65
95
|
*
|
|
66
96
|
* @param baseRunner - The base command runner
|
|
@@ -72,27 +102,25 @@ const decorator = (baseRunner) => async (ctx) => {
|
|
|
72
102
|
* declares the same name — even with an identical schema — is not in that map, so `--version` /
|
|
73
103
|
* `--help` belong to the command.
|
|
74
104
|
*/
|
|
75
|
-
const { values, validationError, env: { globalOptions }, extensions: { [pluginId]: { showVersion,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
105
|
+
const { values, validationError, env: { globalOptions }, extensions: { [pluginId]: { showVersion, showUsage, showValidationErrors } } } = ctx;
|
|
106
|
+
/**
|
|
107
|
+
* NOTE(kazupon): when the plugin has shown the validation errors to the user, they have been
|
|
108
|
+
* reported: the exit code is 1, and `cli()` ends without rejecting, as the other CLI libraries end
|
|
109
|
+
* without a stack trace. They are still thrown, so that the `onErrorCommand` hook sees them. When
|
|
110
|
+
* nothing was shown (`renderValidationErrors: null`, an empty message, or `usageSilent`), `cli()`
|
|
111
|
+
* rejects with them, for the app to report them. So it does when the core keeps no set of reported
|
|
112
|
+
* errors for the run, and then the exit code is left alone.
|
|
113
|
+
*
|
|
114
|
+
* @param error - The aggregate error of the validation errors
|
|
115
|
+
*/
|
|
116
|
+
const report = async (error) => {
|
|
117
|
+
if (await showValidationErrors(error) && !ctx.env.usageSilent && markReported(ctx, error)) setExitCode(1);
|
|
118
|
+
throw error;
|
|
119
|
+
};
|
|
120
|
+
if (hasPriorityValidationError(validationError)) return await report(validationError);
|
|
80
121
|
if (values.version && globalOptions?.has("version")) return showVersion();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (header) buf.push(header);
|
|
84
|
-
if (values.help && globalOptions?.has("help")) {
|
|
85
|
-
const usage = await showUsage();
|
|
86
|
-
if (usage) {
|
|
87
|
-
buf.push(usage);
|
|
88
|
-
return buf.join("\n");
|
|
89
|
-
}
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (validationError) {
|
|
93
|
-
await showValidationErrors(validationError);
|
|
94
|
-
throw validationError;
|
|
95
|
-
}
|
|
122
|
+
if (values.help && globalOptions?.has("help")) return await showUsage();
|
|
123
|
+
if (validationError) return await report(validationError);
|
|
96
124
|
return baseRunner(ctx);
|
|
97
125
|
};
|
|
98
126
|
//#endregion
|
|
@@ -126,19 +154,31 @@ function extension(ctx) {
|
|
|
126
154
|
return header;
|
|
127
155
|
},
|
|
128
156
|
showUsage: async () => {
|
|
129
|
-
if (ctx.env.renderUsage
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
157
|
+
if (ctx.env.renderUsage == null) return;
|
|
158
|
+
const usage = await ctx.env.renderUsage(ctx);
|
|
159
|
+
if (!usage) return;
|
|
160
|
+
/**
|
|
161
|
+
* NOTE(kazupon): the header is the title of the usage, so it comes with the usage, wherever the
|
|
162
|
+
* usage is shown: for `--help`, and when a command that takes `--help` itself shows it. It is not
|
|
163
|
+
* shown before a command runs, where it would come before what the command prints, such as JSON.
|
|
164
|
+
*/
|
|
165
|
+
const header = ctx.env.renderHeader == null ? void 0 : await ctx.env.renderHeader(ctx);
|
|
166
|
+
if (header) {
|
|
167
|
+
ctx.log(header);
|
|
168
|
+
ctx.log();
|
|
135
169
|
}
|
|
170
|
+
ctx.log(usage);
|
|
171
|
+
return header ? [header, usage].join("\n") : usage;
|
|
136
172
|
},
|
|
137
173
|
showValidationErrors: async (error) => {
|
|
138
174
|
if (ctx.env.renderValidationErrors === null) return;
|
|
139
175
|
if (ctx.env.renderValidationErrors !== void 0) {
|
|
140
176
|
const message = await ctx.env.renderValidationErrors(ctx, error);
|
|
141
|
-
|
|
177
|
+
/**
|
|
178
|
+
* NOTE(kazupon): the validation errors are diagnostics, not the output of the command, so they
|
|
179
|
+
* go to stderr, as the other CLI libraries do. stdout stays for what a command prints, such as JSON.
|
|
180
|
+
*/
|
|
181
|
+
if (message && !ctx.env.usageSilent) console.error(message);
|
|
142
182
|
return message;
|
|
143
183
|
}
|
|
144
184
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gunshi/plugin-global",
|
|
3
3
|
"description": "global options plugin for gunshi",
|
|
4
|
-
"version": "1.0.0-
|
|
4
|
+
"version": "1.0.0-rc.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "kazuya kawaguchi",
|
|
7
7
|
"email": "kawakazu80@gmail.com"
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@gunshi/plugin": "1.0.0-
|
|
54
|
+
"@gunshi/plugin": "1.0.0-rc.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@gunshi/shared": "1.0.0-
|
|
57
|
+
"@gunshi/shared": "1.0.0-rc.2",
|
|
58
58
|
"deno": "^2.7.14",
|
|
59
59
|
"jsr": "^0.14.3",
|
|
60
60
|
"jsr-exports-lint": "^0.4.2",
|