@gunshi/plugin-global 0.26.3

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 kazuya kawaguchi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # @gunshi/plugin-global
2
+
3
+ > global options plugin for gunshi.
4
+
5
+ This plugin provides standard global options (`--help` and `--version`) for all commands in your CLI application. It's installed by default in gunshi, ensuring consistent behavior across all CLI applications.
6
+
7
+ ## 💿 Installation
8
+
9
+ ```sh
10
+ # npm
11
+ npm install --save @gunshi/plugin-global
12
+
13
+ # pnpm
14
+ pnpm add @gunshi/plugin-global
15
+
16
+ # yarn
17
+ yarn add @gunshi/plugin-global
18
+
19
+ # deno
20
+ deno add jsr:@gunshi/plugin-global
21
+
22
+ # bun
23
+ bun add @gunshi/plugin-global
24
+ ```
25
+
26
+ ## 🚀 Usage
27
+
28
+ ```ts
29
+ import global from '@gunshi/plugin-global'
30
+ import { cli } from 'gunshi'
31
+
32
+ const command = {
33
+ name: 'my-command',
34
+ args: {
35
+ target: {
36
+ type: 'string',
37
+ description: 'Target to process'
38
+ }
39
+ },
40
+ run: ctx => {
41
+ console.log(`Processing ${ctx.values.target}`)
42
+ }
43
+ }
44
+
45
+ await cli(process.argv.slice(2), command, {
46
+ name: 'my-cli',
47
+ version: '1.0.0',
48
+ plugins: [
49
+ global() // Adds --help and --version options
50
+ ]
51
+ })
52
+ ```
53
+
54
+ <!-- eslint-disable markdown/no-missing-label-refs -->
55
+
56
+ > [!TIP]
57
+ > This plugin is installed in gunshi **by default**. You don't need to explicitly add it unless you've disabled default plugins.
58
+
59
+ <!-- eslint-enable markdown/no-missing-label-refs -->
60
+
61
+ ## ✨ Features
62
+
63
+ ### Global Options
64
+
65
+ This plugin automatically adds the following options to all commands:
66
+
67
+ - **`--help`, `-h`**: Display the command usage and available options
68
+ - **`--version`, `-v`**: Display the application version
69
+
70
+ ### Automatic Behavior
71
+
72
+ When these options are used:
73
+
74
+ - **With `--help`**: The command execution is bypassed, and the usage information is displayed instead
75
+ - **With `--version`**: The command execution is bypassed, and only the version number is printed
76
+
77
+ ## 🧩 Context Extensions
78
+
79
+ When using the global options plugin, your command context is extended via `ctx.extensions['g:global']`.
80
+
81
+ <!-- eslint-disable markdown/no-missing-label-refs -->
82
+
83
+ > [!IMPORTANT]
84
+ > This plugin extension is namespaced in `CommandContext.extensions` using this plugin ID `g:global` by the gunshi plugin system.
85
+
86
+ <!-- eslint-enable markdown/no-missing-label-refs -->
87
+
88
+ Available extensions:
89
+
90
+ - **`showVersion(): string`**: Display the application version. Returns `'unknown'` if no version is specified in the CLI configuration.
91
+
92
+ - **`showHeader(): Awaitable<string | undefined>`**: Display the application header. Returns `undefined` if no `renderHeader` function is provided in the CLI configuration.
93
+
94
+ - **`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.
95
+
96
+ - **`showValidationErrors(error: AggregateError): Awaitable<string | undefined>`**: Display validation errors when argument validation fails. Returns `undefined` if `renderValidationErrors` is null.
97
+
98
+ ### Usage Example
99
+
100
+ ```ts
101
+ import global, { pluginId } from '@gunshi/plugin-global'
102
+ import { cli } from 'gunshi'
103
+
104
+ const command = {
105
+ name: 'deploy',
106
+ run: async ctx => {
107
+ // Access globals extensions
108
+ const { showVersion, showHeader } = ctx.extensions[pluginId]
109
+
110
+ // Manually show version if needed
111
+ console.log(`Deploying with CLI version: ${showVersion()}`)
112
+
113
+ // Show custom header
114
+ const header = await showHeader()
115
+ if (header) {
116
+ console.log(header)
117
+ }
118
+
119
+ // Your command logic here...
120
+ }
121
+ }
122
+
123
+ await cli(process.argv.slice(2), command, {
124
+ name: 'deploy-cli',
125
+ version: '2.1.0',
126
+ plugins: [global()],
127
+
128
+ // Optional: Custom header renderer
129
+ renderHeader: async () => {
130
+ return `
131
+ ╔══════════════════════╗
132
+ ║ Deploy CLI v2.1.0 ║
133
+ ╚══════════════════════╝
134
+ `
135
+ }
136
+ })
137
+ ```
138
+
139
+ ## 📚 API References
140
+
141
+ See the [API References](./docs/index.md)
142
+
143
+ ## ©️ License
144
+
145
+ [MIT](http://opensource.org/licenses/MIT)
package/lib/index.d.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { Awaitable, PluginWithExtension } from "@gunshi/plugin";
2
+
3
+ //#region src/extension.d.ts
4
+ /**
5
+ * Extended command context which provides utilities via global options plugin.
6
+ * These utilities are available via `CommandContext.extensions['g:global']`.
7
+ */
8
+
9
+ /**
10
+ * Extended command context which provides utilities via global options plugin.
11
+ * These utilities are available via `CommandContext.extensions['g:global']`.
12
+ */
13
+ interface GlobalCommandContext {
14
+ /**
15
+ * Show the version of the application. if `--version` option is specified, it will print the version to the console.
16
+ * @returns The version of the application, or `unknown` if the version is not specified.
17
+ */
18
+ showVersion: () => string;
19
+ /**
20
+ * Show the header of the application.
21
+ * @returns The header of the application, or `undefined` if the `renderHeader` is not specified.
22
+ */
23
+ showHeader: () => Awaitable<string | undefined>;
24
+ /**
25
+ * Show the usage of the application. if `--help` option is specified, it will print the usage to the console.
26
+ * @returns The usage of the application, or `undefined` if the `renderUsage` is not specified.
27
+ */
28
+ showUsage: () => Awaitable<string | undefined>;
29
+ /**
30
+ * Show validation errors. This is called when argument validation fails.
31
+ * @param error The aggregate error containing validation failures
32
+ * @returns The rendered error message, or `undefined` if `renderValidationErrors` is null
33
+ */
34
+ showValidationErrors: (error: AggregateError) => Awaitable<string | undefined>;
35
+ } //#endregion
36
+ //#region ../shared/src/constants.d.ts
37
+ /**
38
+ * @author kazuya kawaguchi (a.k.a. kazupon)
39
+ * @license MIT
40
+ */
41
+ declare const BUILT_IN_PREFIX = "_";
42
+ declare const PLUGIN_PREFIX = "g";
43
+ declare const BUILT_IN_KEY_SEPARATOR = ":";
44
+
45
+ //#endregion
46
+ //#region ../shared/src/types.d.ts
47
+ /**
48
+ * Generate a namespaced key.
49
+ */
50
+ type GenerateNamespacedKey<Key extends string, Prefixed extends string = typeof BUILT_IN_PREFIX> = `${Prefixed}${typeof BUILT_IN_KEY_SEPARATOR}${Key}`;
51
+
52
+ //#endregion
53
+ //#region src/types.d.ts
54
+ /**
55
+ * Command i18n built-in arguments keys.
56
+ */
57
+ /**
58
+ * The unique identifier for the global options plugin.
59
+ */
60
+ declare const pluginId: GenerateNamespacedKey<'global', typeof PLUGIN_PREFIX>;
61
+ /**
62
+ * Type representing the unique identifier for the global options plugin.
63
+ */
64
+ type PluginId = typeof pluginId;
65
+
66
+ //#endregion
67
+ //#region src/index.d.ts
68
+ /**
69
+ * global options plugin
70
+ */
71
+ declare function global(): PluginWithExtension<GlobalCommandContext>;
72
+
73
+ //#endregion
74
+ export { GlobalCommandContext, PluginId, global as default, pluginId };
package/lib/index.js ADDED
@@ -0,0 +1,122 @@
1
+ import { plugin } from "@gunshi/plugin";
2
+
3
+ //#region ../shared/src/constants.ts
4
+ /**
5
+ * @author kazuya kawaguchi (a.k.a. kazupon)
6
+ * @license MIT
7
+ */
8
+ const BUILT_IN_PREFIX = "_";
9
+ const PLUGIN_PREFIX = "g";
10
+ const ARG_PREFIX = "arg";
11
+ const BUILT_IN_KEY_SEPARATOR = ":";
12
+ const BUILD_IN_PREFIX_AND_KEY_SEPARATOR = `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}`;
13
+ const ARG_PREFIX_AND_KEY_SEPARATOR = `${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}`;
14
+ const COMMON_ARGS = {
15
+ help: {
16
+ type: "boolean",
17
+ short: "h",
18
+ description: "Display this help message"
19
+ },
20
+ version: {
21
+ type: "boolean",
22
+ short: "v",
23
+ description: "Display this version"
24
+ }
25
+ };
26
+
27
+ //#endregion
28
+ //#region ../shared/src/utils.ts
29
+ function namespacedId(id) {
30
+ return `${PLUGIN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${id}`;
31
+ }
32
+
33
+ //#endregion
34
+ //#region src/types.ts
35
+ /**
36
+ * The unique identifier for the global options plugin.
37
+ */
38
+ const pluginId = namespacedId("global");
39
+
40
+ //#endregion
41
+ //#region src/decorator.ts
42
+ /**
43
+ * Decorator function to extend the command with global options.
44
+ */
45
+ const decorator = (baseRunner) => async (ctx) => {
46
+ const { values, validationError, extensions: { [pluginId]: { showVersion, showHeader, showUsage, showValidationErrors } } } = ctx;
47
+ if (values.version) return showVersion();
48
+ const buf = [];
49
+ const header = await showHeader();
50
+ if (header) buf.push(header);
51
+ if (values.help) {
52
+ const usage = await showUsage();
53
+ if (usage) {
54
+ buf.push(usage);
55
+ return buf.join("\n");
56
+ }
57
+ return;
58
+ }
59
+ if (validationError) return await showValidationErrors(validationError);
60
+ return baseRunner(ctx);
61
+ };
62
+ var decorator_default = decorator;
63
+
64
+ //#endregion
65
+ //#region src/extension.ts
66
+ function extension(ctx) {
67
+ return {
68
+ showVersion: () => {
69
+ const version = ctx.env.version || "unknown";
70
+ if (!ctx.env.usageSilent) ctx.log(version);
71
+ return version;
72
+ },
73
+ showHeader: async () => {
74
+ let header;
75
+ if (ctx.env.renderHeader != null) {
76
+ header = await ctx.env.renderHeader(ctx);
77
+ if (header) {
78
+ ctx.log(header);
79
+ ctx.log();
80
+ }
81
+ }
82
+ return header;
83
+ },
84
+ showUsage: async () => {
85
+ if (ctx.env.renderUsage != null) {
86
+ const usage = await ctx.env.renderUsage(ctx);
87
+ if (usage) {
88
+ ctx.log(usage);
89
+ return usage;
90
+ }
91
+ }
92
+ },
93
+ showValidationErrors: async (error) => {
94
+ if (ctx.env.renderValidationErrors === null) return;
95
+ if (ctx.env.renderValidationErrors !== void 0) {
96
+ const message = await ctx.env.renderValidationErrors(ctx, error);
97
+ ctx.log(message);
98
+ return message;
99
+ }
100
+ }
101
+ };
102
+ }
103
+
104
+ //#endregion
105
+ //#region src/index.ts
106
+ /**
107
+ * global options plugin
108
+ */
109
+ function global() {
110
+ return plugin({
111
+ id: pluginId,
112
+ name: "global options",
113
+ extension,
114
+ setup(ctx) {
115
+ for (const [name, schema] of Object.entries(COMMON_ARGS)) ctx.addGlobalOption(name, schema);
116
+ ctx.decorateCommand(decorator_default);
117
+ }
118
+ });
119
+ }
120
+
121
+ //#endregion
122
+ export { global as default, pluginId };
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@gunshi/plugin-global",
3
+ "description": "global options plugin for gunshi",
4
+ "version": "0.26.3",
5
+ "author": {
6
+ "name": "kazuya kawaguchi",
7
+ "email": "kawakazu80@gmail.com"
8
+ },
9
+ "license": "MIT",
10
+ "funding": "https://github.com/sponsors/kazupon",
11
+ "bugs": {
12
+ "url": "https://github.com/kazupon/gunshi/issues"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/kazupon/gunshi.git",
17
+ "directory": "packages/plugin-global"
18
+ },
19
+ "keywords": [
20
+ "gunshi",
21
+ "plugin",
22
+ "cli"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "engines": {
28
+ "node": ">= 20"
29
+ },
30
+ "type": "module",
31
+ "files": [
32
+ "lib"
33
+ ],
34
+ "module": "lib/index.js",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./lib/index.d.ts",
38
+ "import": "./lib/index.js",
39
+ "require": "./lib/index.js",
40
+ "default": "./lib/index.js"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "types": "lib/index.d.ts",
45
+ "typesVersions": {
46
+ "*": {
47
+ "*": [
48
+ "./lib/*",
49
+ "./*"
50
+ ]
51
+ }
52
+ },
53
+ "dependencies": {
54
+ "@gunshi/plugin": "0.26.3"
55
+ },
56
+ "devDependencies": {
57
+ "deno": "^2.3.3",
58
+ "jsr": "^0.13.4",
59
+ "jsr-exports-lint": "^0.4.1",
60
+ "publint": "^0.3.12",
61
+ "tsdown": "^0.12.3",
62
+ "typedoc": "^0.28.4",
63
+ "typedoc-plugin-markdown": "^4.6.3",
64
+ "@gunshi/shared": "0.26.3"
65
+ },
66
+ "scripts": {
67
+ "build": "tsdown",
68
+ "build:docs": "typedoc --excludeInternal",
69
+ "lint:jsr": "jsr publish --dry-run --allow-dirty",
70
+ "typecheck:deno": "deno check ./src"
71
+ }
72
+ }