gunshi 0.11.0 → 0.12.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.
@@ -1,4 +1,5 @@
1
- import { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, DEFAULT_LOCALE, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, resolveLazyCommand } from "./utils-zZSVaYTy.js";
1
+ import { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, DEFAULT_LOCALE, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, renderHeader, renderUsage, renderValidationErrors, resolveLazyCommand } from "./renderer-DAUAIZxV.js";
2
+ import { parseArgs, resolveArgs } from "args-tokens";
2
3
 
3
4
  //#region src/locales/en-US.json
4
5
  var COMMAND = "COMMAND";
@@ -29,10 +30,11 @@ function createTranslationAdapter(options) {
29
30
  }
30
31
  var DefaultTranslation = class {
31
32
  #resources = new Map();
32
- options;
33
+ #options;
33
34
  constructor(options) {
34
- this.options = options;
35
- this.#resources = new Map();
35
+ this.#options = options;
36
+ this.#resources.set(options.locale, create());
37
+ if (options.locale !== options.fallbackLocale) this.#resources.set(options.fallbackLocale, create());
36
38
  }
37
39
  getResource(locale) {
38
40
  return this.#resources.get(locale);
@@ -45,14 +47,13 @@ var DefaultTranslation = class {
45
47
  if (resource) return resource[key];
46
48
  return void 0;
47
49
  }
48
- translate(locale, key, _values = create()) {
49
- /**
50
- * NOTE:
51
- * DefaultTranslation support static message only
52
- * If you want to resolve message with values and use the complex message format,
53
- * you should inherit this class or implement your own translation adapter.
54
- */
55
- return this.getMessage(locale, key) || this.getMessage(this.options.fallbackLocale, key);
50
+ translate(locale, key, values = create()) {
51
+ let message = this.getMessage(locale, key);
52
+ if (message === void 0 && locale !== this.#options.fallbackLocale) message = this.getMessage(this.#options.fallbackLocale, key);
53
+ if (message === void 0) return;
54
+ return message.replaceAll(/\{\{(\w+)\}\}/g, (_, name) => {
55
+ return values[name] == null ? "" : values[name].toString();
56
+ });
56
57
  }
57
58
  };
58
59
 
@@ -164,4 +165,91 @@ async function loadCommandResource(ctx, command) {
164
165
  }
165
166
 
166
167
  //#endregion
167
- export { DefaultTranslation, createCommandContext };
168
+ //#region src/cli.ts
169
+ async function cli(args, entry, opts = {}) {
170
+ const tokens = parseArgs(args);
171
+ const subCommand = getSubCommand(tokens);
172
+ const resolvedCommandOptions = resolveCommandOptions(opts, entry);
173
+ const [name, command] = await resolveCommand(subCommand, entry, resolvedCommandOptions);
174
+ if (!command) throw new Error(`Command not found: ${name || ""}`);
175
+ const options = resolveArgOptions(command.options);
176
+ const { values, positionals, error } = resolveArgs(options, tokens);
177
+ const omitted = !subCommand;
178
+ const ctx = await createCommandContext({
179
+ options,
180
+ values,
181
+ positionals,
182
+ omitted,
183
+ command,
184
+ commandOptions: resolvedCommandOptions
185
+ });
186
+ if (values.version) {
187
+ showVersion(ctx);
188
+ return;
189
+ }
190
+ const usageBuffer = [];
191
+ const header = await showHeader(ctx);
192
+ if (header) usageBuffer.push(header);
193
+ if (values.help) {
194
+ const usage = await showUsage(ctx);
195
+ if (usage) usageBuffer.push(usage);
196
+ return usageBuffer.join("\n");
197
+ }
198
+ if (error) {
199
+ await showValidationErrors(ctx, error);
200
+ return;
201
+ }
202
+ await command.run(ctx);
203
+ }
204
+ function resolveArgOptions(options) {
205
+ return Object.assign(create(), options, COMMON_OPTIONS);
206
+ }
207
+ function resolveCommandOptions(options, entry) {
208
+ const subCommands = new Map(options.subCommands);
209
+ if (typeof entry === "object" && entry.name) subCommands.set(entry.name, entry);
210
+ const resolvedOptions = Object.assign(create(), COMMAND_OPTIONS_DEFAULT, options, { subCommands });
211
+ return resolvedOptions;
212
+ }
213
+ function getSubCommand(tokens) {
214
+ const firstToken = tokens[0];
215
+ return firstToken && firstToken.kind === "positional" && firstToken.index === 0 && firstToken.value ? firstToken.value : "";
216
+ }
217
+ async function showUsage(ctx) {
218
+ if (ctx.env.renderUsage === null) return;
219
+ const usage = await (ctx.env.renderUsage || renderUsage)(ctx);
220
+ if (usage) {
221
+ ctx.log(usage);
222
+ return usage;
223
+ }
224
+ }
225
+ function showVersion(ctx) {
226
+ ctx.log(ctx.env.version);
227
+ }
228
+ async function showHeader(ctx) {
229
+ if (ctx.env.renderHeader === null) return;
230
+ const header = await (ctx.env.renderHeader || renderHeader)(ctx);
231
+ if (header) {
232
+ ctx.log(header);
233
+ ctx.log();
234
+ return header;
235
+ }
236
+ }
237
+ async function showValidationErrors(ctx, error) {
238
+ if (ctx.env.renderValidationErrors === null) return;
239
+ const render = ctx.env.renderValidationErrors || renderValidationErrors;
240
+ ctx.log(await render(ctx, error));
241
+ }
242
+ async function resolveCommand(sub, entry, options) {
243
+ const omitted = !sub;
244
+ if (typeof entry === "function") return [void 0, { run: entry }];
245
+ else if (omitted) return typeof entry === "object" ? [entry.name, await resolveLazyCommand(entry)] : [void 0, void 0];
246
+ else {
247
+ if (options.subCommands == null) return [sub, void 0];
248
+ const cmd = options.subCommands?.get(sub);
249
+ if (cmd == null) return [sub, void 0];
250
+ return [sub, await resolveLazyCommand(cmd, sub)];
251
+ }
252
+ }
253
+
254
+ //#endregion
255
+ export { DefaultTranslation, cli };
@@ -1,12 +1,12 @@
1
1
  import { ArgOptions } from 'args-tokens';
2
- import { C as Command, a as CommandOptions } from './types.d-VymWn7vz.js';
2
+ import { C as Command, a as CommandOptions } from './types.d-DIY9YbHU.js';
3
3
 
4
4
  /**
5
- * Generate the command usage
5
+ * Generate the command usage.
6
6
  * @param command - usage generate command, if you want to generate the usage of the default command where there are target commands and sub-commands, specify `null`.
7
7
  * @param entry - A {@link Command | entry command}
8
8
  * @param opts - A {@link CommandOptions | command options}
9
- * @returns A rendered usage
9
+ * @returns A rendered usage.
10
10
  */
11
11
  declare function generate<Options extends ArgOptions = ArgOptions>(command: string | null, entry: Command<Options>, opts?: CommandOptions<Options>): Promise<string>;
12
12
 
package/lib/generator.js CHANGED
@@ -1,7 +1,5 @@
1
- import { create } from "./utils-zZSVaYTy.js";
2
- import "./context-ZNBQwQKN.js";
3
- import "./renderer-Dm_6iF2f.js";
4
- import { cli } from "./cli-CKcZ5eWi.js";
1
+ import { create } from "./renderer-DAUAIZxV.js";
2
+ import { cli } from "./cli-C-y15OeH.js";
5
3
 
6
4
  //#region src/generator.ts
7
5
  async function generate(command, entry, opts = {}) {
package/lib/index.d.ts CHANGED
@@ -1,25 +1,24 @@
1
1
  import { ArgOptions } from 'args-tokens';
2
2
  export { ArgOptionSchema, ArgOptions, ArgValues } from 'args-tokens';
3
- import { C as Command, c as CommandRunner, a as CommandOptions, T as TranslationAdapter, d as TranslationAdapterFactoryOptions } from './types.d-VymWn7vz.js';
4
- export { g as CommandBuiltinKeys, e as CommandBuiltinOptionsKeys, f as CommandBuiltinResourceKeys, b as CommandContext, h as CommandEnvironment, i as CommandResource, j as CommandResourceFetcher, l as Commandable, G as GenerateNamespacedKey, L as LazyCommand, k as TranslationAdapterFactory } from './types.d-VymWn7vz.js';
3
+ import { C as Command, b as CommandRunner, a as CommandOptions, T as TranslationAdapter, c as TranslationAdapterFactoryOptions } from './types.d-DIY9YbHU.js';
4
+ export { f as CommandBuiltinKeys, d as CommandBuiltinOptionsKeys, e as CommandBuiltinResourceKeys, h as CommandContext, g as CommandEnvironment, i as CommandResource, j as CommandResourceFetcher, l as Commandable, D as DEFAULT_LOCALE, G as GenerateNamespacedKey, L as LazyCommand, k as TranslationAdapterFactory } from './types.d-DIY9YbHU.js';
5
5
 
6
6
  /**
7
- * Run the command
8
- * @param args - command line arguments
9
- * @param entry - A {@link Command | entry command} or an {@link CommandRunner | inline command runner}
10
- * @param opts - A {@link CommandOptions | command options}
7
+ * Run the command.
8
+ * @param args Command line arguments
9
+ * @param entry A {@link Command | entry command} or an {@link CommandRunner | inline command runner}
10
+ * @param opts A {@link CommandOptions | command options}
11
11
  * @returns A rendered usage or undefined. if you will use {@link CommandOptions.usageSilent} option, it will return rendered usage string.
12
12
  */
13
13
  declare function cli<Options extends ArgOptions = ArgOptions>(args: string[], entry: Command<Options> | CommandRunner<Options>, opts?: CommandOptions<Options>): Promise<string | undefined>;
14
14
 
15
15
  declare class DefaultTranslation implements TranslationAdapter {
16
16
  #private;
17
- options: TranslationAdapterFactoryOptions;
18
17
  constructor(options: TranslationAdapterFactoryOptions);
19
18
  getResource(locale: string): Record<string, string> | undefined;
20
19
  setResource(locale: string, resource: Record<string, string>): void;
21
20
  getMessage(locale: string, key: string): string | undefined;
22
- translate(locale: string, key: string, _values?: Record<string, unknown>): string | undefined;
21
+ translate(locale: string, key: string, values?: Record<string, unknown>): string | undefined;
23
22
  }
24
23
 
25
24
  export { Command, CommandOptions, CommandRunner, DefaultTranslation, TranslationAdapter, TranslationAdapterFactoryOptions, cli };
package/lib/index.js CHANGED
@@ -1,6 +1,4 @@
1
- import "./utils-zZSVaYTy.js";
2
- import { DefaultTranslation } from "./context-ZNBQwQKN.js";
3
- import "./renderer-Dm_6iF2f.js";
4
- import { cli } from "./cli-CKcZ5eWi.js";
1
+ import { DEFAULT_LOCALE } from "./renderer-DAUAIZxV.js";
2
+ import { DefaultTranslation, cli } from "./cli-C-y15OeH.js";
5
3
 
6
- export { DefaultTranslation, cli };
4
+ export { DEFAULT_LOCALE, DefaultTranslation, cli };
@@ -1,25 +1,25 @@
1
1
  import { ArgOptions } from 'args-tokens';
2
- import { b as CommandContext } from '../types.d-VymWn7vz.js';
2
+ import { h as CommandContext } from '../types.d-DIY9YbHU.js';
3
3
 
4
4
  /**
5
- * Render the header
5
+ * Render the header.
6
6
  * @param ctx A {@link CommandContext | command context}
7
- * @returns A rendered header
7
+ * @returns A rendered header.
8
8
  */
9
9
  declare function renderHeader<Options extends ArgOptions = ArgOptions>(ctx: Readonly<CommandContext<Options>>): Promise<string>;
10
10
 
11
11
  /**
12
- * Render the usage
12
+ * Render the usage.
13
13
  * @param ctx A {@link CommandContext | command context}
14
- * @returns A rendered usage
14
+ * @returns A rendered usage.
15
15
  */
16
16
  declare function renderUsage<Options extends ArgOptions = ArgOptions>(ctx: Readonly<CommandContext<Options>>): Promise<string>;
17
17
 
18
18
  /**
19
- * Render the validation errors
19
+ * Render the validation errors.
20
20
  * @param ctx A {@link CommandContext | command context}
21
21
  * @param error An {@link AggregateError} of option in `args-token` validation
22
- * @returns A rendered validation error
22
+ * @returns A rendered validation error.
23
23
  */
24
24
  declare function renderValidationErrors<Options extends ArgOptions = ArgOptions>(_ctx: CommandContext<Options>, error: AggregateError): Promise<string>;
25
25
 
@@ -1,4 +1,3 @@
1
- import "../utils-zZSVaYTy.js";
2
- import { renderHeader, renderUsage, renderValidationErrors } from "../renderer-Dm_6iF2f.js";
1
+ import { renderHeader, renderUsage, renderValidationErrors } from "../renderer-DAUAIZxV.js";
3
2
 
4
3
  export { renderHeader, renderUsage, renderValidationErrors };
@@ -1,5 +1,69 @@
1
- import { create, resolveBuiltInKey } from "./utils-zZSVaYTy.js";
2
1
 
2
+ //#region src/constants.ts
3
+ const DEFAULT_LOCALE = "en-US";
4
+ const BUILT_IN_PREFIX = "_";
5
+ const BUILT_IN_KEY_SEPARATOR = ":";
6
+ const NOOP = () => {};
7
+ const COMMON_OPTIONS = {
8
+ help: {
9
+ type: "boolean",
10
+ short: "h",
11
+ description: "Display this help message"
12
+ },
13
+ version: {
14
+ type: "boolean",
15
+ short: "v",
16
+ description: "Display this version"
17
+ }
18
+ };
19
+ const COMMAND_OPTIONS_DEFAULT = {
20
+ name: void 0,
21
+ description: void 0,
22
+ version: void 0,
23
+ cwd: void 0,
24
+ usageSilent: false,
25
+ subCommands: void 0,
26
+ leftMargin: 2,
27
+ middleMargin: 10,
28
+ usageOptionType: false,
29
+ renderHeader: void 0,
30
+ renderUsage: void 0,
31
+ renderValidationErrors: void 0,
32
+ translationAdapterFactory: void 0
33
+ };
34
+
35
+ //#endregion
36
+ //#region src/utils.ts
37
+ async function resolveLazyCommand(cmd, name) {
38
+ const resolved = Object.assign(create(), typeof cmd == "function" ? await cmd() : cmd);
39
+ if (resolved.name == null && name) resolved.name = name;
40
+ return deepFreeze(resolved);
41
+ }
42
+ function resolveBuiltInKey(key) {
43
+ return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
44
+ }
45
+ function mapResourceWithBuiltinKey(resource) {
46
+ return Object.entries(resource).reduce((acc, [key, value]) => {
47
+ acc[resolveBuiltInKey(key)] = value;
48
+ return acc;
49
+ }, create());
50
+ }
51
+ function create(obj = null) {
52
+ return Object.create(obj);
53
+ }
54
+ function log(...args) {
55
+ console.log(...args);
56
+ }
57
+ function deepFreeze(obj) {
58
+ if (obj === null || typeof obj !== "object") return obj;
59
+ for (const key of Object.keys(obj)) {
60
+ const value = obj[key];
61
+ if (typeof value === "object" && value !== null) deepFreeze(value);
62
+ }
63
+ return Object.freeze(obj);
64
+ }
65
+
66
+ //#endregion
3
67
  //#region src/renderer/header.ts
4
68
  function renderHeader(ctx) {
5
69
  const title = ctx.env.description || ctx.env.name || "";
@@ -198,4 +262,4 @@ function renderValidationErrors(_ctx, error) {
198
262
  }
199
263
 
200
264
  //#endregion
201
- export { renderHeader, renderUsage, renderValidationErrors };
265
+ export { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, DEFAULT_LOCALE, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, renderHeader, renderUsage, renderValidationErrors, resolveLazyCommand };
@@ -1,7 +1,7 @@
1
1
  import { ArgOptions, ArgValues } from 'args-tokens';
2
2
 
3
3
  /**
4
- * The default locale string, which format is BCP 47 language tag
4
+ * The default locale string, which format is BCP 47 language tag.
5
5
  */
6
6
  declare const DEFAULT_LOCALE = "en-US";
7
7
  declare const BUILT_IN_PREFIX = "_";
@@ -43,7 +43,7 @@ declare namespace __constants_ts {
43
43
  }
44
44
 
45
45
  /**
46
- * Define a promise type that can be await from T
46
+ * Define a promise type that can be await from T.
47
47
  */
48
48
  type Awaitable<T> = T | Promise<T>;
49
49
  type GenerateNamespacedKey<
@@ -51,216 +51,211 @@ type GenerateNamespacedKey<
51
51
  Prefixed extends string = typeof BUILT_IN_PREFIX
52
52
  > = `${Prefixed}${typeof BUILT_IN_KEY_SEPARATOR}${Key}`;
53
53
  /**
54
- * Command i18n built-in options keys
55
- * @experimental
54
+ * Command i18n built-in options keys.
56
55
  */
57
56
  type CommandBuiltinOptionsKeys = keyof (typeof __constants_ts)["COMMON_OPTIONS"];
58
57
  /**
59
- * Command i18n built-in resource keys
60
- * @experimental
58
+ * Command i18n built-in resource keys.
61
59
  */
62
60
  type CommandBuiltinResourceKeys = (typeof __constants_ts)["COMMAND_BUILTIN_RESOURCE_KEYS"][number];
63
61
  /**
64
- * Command i18n built-in keys
65
- * @description The command i18n built-in keys are used to {@link CommandContext.translate | translate} function
66
- * @experimental
62
+ * Command i18n built-in keys.
63
+ * The command i18n built-in keys are used to {@link CommandContext.translate | translate} function.
67
64
  */
68
65
  type CommandBuiltinKeys = GenerateNamespacedKey<CommandBuiltinOptionsKeys> | GenerateNamespacedKey<CommandBuiltinResourceKeys> | "description" | "examples";
69
66
  /**
70
- * Command environment
67
+ * Command environment.
71
68
  */
72
69
  interface CommandEnvironment<Options extends ArgOptions = ArgOptions> {
73
70
  /**
74
- * Current working directory
71
+ * Current working directory.
75
72
  * @see {@link CommandOptions.cwd}
76
73
  */
77
74
  cwd: string | undefined;
78
75
  /**
79
- * Command name
76
+ * Command name.
80
77
  * @see {@link CommandOptions.name}
81
78
  */
82
79
  name: string | undefined;
83
80
  /**
84
- * Command description
81
+ * Command description.
85
82
  * @see {@link CommandOptions.description}
86
83
  *
87
84
  */
88
85
  description: string | undefined;
89
86
  /**
90
- * Command version
87
+ * Command version.
91
88
  * @see {@link CommandOptions.version}
92
89
  */
93
90
  version: string | undefined;
94
91
  /**
95
- * Left margin of the command output
92
+ * Left margin of the command output.
96
93
  * @default 2
97
94
  * @see {@link CommandOptions.leftMargin}
98
95
  */
99
96
  leftMargin: number;
100
97
  /**
101
- * Middle margin of the command output
98
+ * Middle margin of the command output.
102
99
  * @default 10
103
100
  * @see {@link CommandOptions.middleMargin}
104
101
  */
105
102
  middleMargin: number;
106
103
  /**
107
- * Whether to display the usage option type
104
+ * Whether to display the usage option type.
108
105
  * @default false
109
106
  * @see {@link CommandOptions.usageOptionType}
110
107
  */
111
108
  usageOptionType: boolean;
112
109
  /**
113
- * Whether to display the command usage
110
+ * Whether to display the command usage.
114
111
  * @default false
115
112
  * @see {@link}
116
113
  */
117
114
  usageSilent: boolean;
118
115
  /**
119
- * Sub commands
116
+ * Sub commands.
120
117
  * @see {@link CommandOptions.subCommands}
121
118
  */
122
119
  subCommands: Map<string, Command<any> | LazyCommand<any>> | undefined;
123
120
  /**
124
- * Render function the command usage
121
+ * Render function the command usage.
125
122
  */
126
123
  renderUsage: ((ctx: CommandContext<Options>) => Promise<string>) | null | undefined;
127
124
  /**
128
- * Render function the header section in the command usage
125
+ * Render function the header section in the command usage.
129
126
  */
130
127
  renderHeader: ((ctx: CommandContext<Options>) => Promise<string>) | null | undefined;
131
128
  /**
132
- * Render function the validation errors
129
+ * Render function the validation errors.
133
130
  */
134
131
  renderValidationErrors: ((ctx: CommandContext<Options>, error: AggregateError) => Promise<string>) | null | undefined;
135
132
  }
136
133
  /**
137
- * Command options
134
+ * Command options.
138
135
  */
139
136
  interface CommandOptions<Options extends ArgOptions = ArgOptions> {
140
137
  /**
141
- * Current working directory
138
+ * Current working directory.
142
139
  */
143
140
  cwd?: string;
144
141
  /**
145
- * Command program name
142
+ * Command program name.
146
143
  */
147
144
  name?: string;
148
145
  /**
149
- * Command program description
146
+ * Command program description.
150
147
  *
151
148
  */
152
149
  description?: string;
153
150
  /**
154
- * Command program version
151
+ * Command program version.
155
152
  */
156
153
  version?: string;
157
154
  /**
158
- * Command program locale
155
+ * Command program locale.
159
156
  */
160
157
  locale?: string | Intl.Locale;
161
158
  /**
162
- * Sub commands
159
+ * Sub commands.
163
160
  */
164
161
  subCommands?: Map<string, Command<any> | LazyCommand<any>>;
165
162
  /**
166
- * Left margin of the command output
163
+ * Left margin of the command output.
167
164
  */
168
165
  leftMargin?: number;
169
166
  /**
170
- * Middle margin of the command output
167
+ * Middle margin of the command output.
171
168
  */
172
169
  middleMargin?: number;
173
170
  /**
174
- * Whether to display the usage option type
171
+ * Whether to display the usage option type.
175
172
  */
176
173
  usageOptionType?: boolean;
177
174
  /**
178
- * Whether to display the command usage
175
+ * Whether to display the command usage.
179
176
  */
180
177
  usageSilent?: boolean;
181
178
  /**
182
- * Render function the command usage
179
+ * Render function the command usage.
183
180
  */
184
181
  renderUsage?: ((ctx: Readonly<CommandContext<Options>>) => Promise<string>) | null;
185
182
  /**
186
- * Render function the header section in the command usage
183
+ * Render function the header section in the command usage.
187
184
  */
188
185
  renderHeader?: ((ctx: Readonly<CommandContext<Options>>) => Promise<string>) | null;
189
186
  /**
190
- * Render function the validation errors
187
+ * Render function the validation errors.
191
188
  */
192
189
  renderValidationErrors?: ((ctx: Readonly<CommandContext<Options>>, error: AggregateError) => Promise<string>) | null;
193
190
  /**
194
- * Translation adapter factory
195
- * @experimental
191
+ * Translation adapter factory.
196
192
  */
197
193
  translationAdapterFactory?: TranslationAdapterFactory;
198
194
  }
199
195
  /**
200
- * Command context
201
- * @description Command context is the context of the command execution
196
+ * Command context.
197
+ * Command context is the context of the command execution.
202
198
  */
203
199
  interface CommandContext<
204
200
  Options extends ArgOptions = ArgOptions,
205
201
  Values = ArgValues<Options>
206
202
  > {
207
203
  /**
208
- * Command name, that is the command that is executed
209
- * @description The command name is same {@link CommandEnvironment.name}
204
+ * Command name, that is the command that is executed.
205
+ * The command name is same {@link CommandEnvironment.name}.
210
206
  */
211
207
  name: string | undefined;
212
208
  /**
213
- * Command description, that is the description of the command that is executed
214
- * @description The command description is same {@link CommandEnvironment.description}
209
+ * Command description, that is the description of the command that is executed.
210
+ * The command description is same {@link CommandEnvironment.description}.
215
211
  */
216
212
  description: string | undefined;
217
213
  /**
218
- * Command locale, that is the locale of the command that is executed
214
+ * Command locale, that is the locale of the command that is executed.
219
215
  */
220
216
  locale: Intl.Locale;
221
217
  /**
222
- * Command environment, that is the environment of the command that is executed
223
- * @description The command environment is same {@link CommandEnvironment}
218
+ * Command environment, that is the environment of the command that is executed.
219
+ * The command environment is same {@link CommandEnvironment}.
224
220
  */
225
221
  env: Readonly<CommandEnvironment<Options>>;
226
222
  /**
227
- * Command options, that is the options of the command that is executed
228
- * @description The command options is same {@link Command.options}
223
+ * Command options, that is the options of the command that is executed.
224
+ * The command options is same {@link Command.options}.
229
225
  */
230
226
  options: Options;
231
227
  /**
232
- * Command values, that is the values of the command that is executed
233
- * @description Resolve values with `resolveArgs` from command arguments and {@link Command.options}
228
+ * Command values, that is the values of the command that is executed.
229
+ * Resolve values with `resolveArgs` from command arguments and {@link Command.options}.
234
230
  */
235
231
  values: Values;
236
232
  /**
237
- * Command positionals arguments, that is the positionals of the command that is executed
238
- * @description Resolve positionals with `resolveArgs` from command arguments
233
+ * Command positionals arguments, that is the positionals of the command that is executed.
234
+ * Resolve positionals with `resolveArgs` from command arguments.
239
235
  */
240
236
  positionals: string[];
241
237
  /**
242
- * Whether the currently executing command has been executed with the sub-command name omitted
238
+ * Whether the currently executing command has been executed with the sub-command name omitted.
243
239
  */
244
240
  omitted: boolean;
245
241
  /**
246
- * Output a message
247
- * @description if {@link CommandEnvironment.usageSilent} is true, the message is not output
242
+ * Output a message.
243
+ * If {@link CommandEnvironment.usageSilent} is true, the message is not output.
248
244
  * @param message an output message, @see {@link console.log}
249
245
  * @param optionalParams an optional parameters, @see {@link console.log}
250
246
  */
251
247
  log: (message?: any, ...optionalParams: any[]) => void;
252
248
  /**
253
- * Load sub-commands
254
- * @description The loaded commands are cached and returned when called again
255
- * @returns loaded commands
249
+ * Load sub-commands.
250
+ * The loaded commands are cached and returned when called again.
251
+ * @returns loaded commands.
256
252
  */
257
253
  loadCommands: () => Promise<Command<Options>[]>;
258
254
  /**
259
- * Translate function
255
+ * Translate function.
260
256
  * @param key the key to be translated
261
257
  * @param values the values to be formatted
262
- * @returns A translated string
263
- * @experimental
258
+ * @returns A translated string.
264
259
  */
265
260
  translate: <
266
261
  T extends string = CommandBuiltinKeys,
@@ -268,137 +263,127 @@ interface CommandContext<
268
263
  >(key: Key, values?: Record<string, unknown>) => string;
269
264
  }
270
265
  /**
271
- * Command interface
266
+ * Command interface.
272
267
  */
273
268
  interface Command<Options extends ArgOptions = ArgOptions> {
274
269
  /**
275
- * Command name
276
- * @description
277
- * Command name is used to find command line arguments to execute from sub commands, so it's recommended to specify.
270
+ * Command name.
271
+ * It's used to find command line arguments to execute from sub commands, and it's recommended to specify.
278
272
  */
279
273
  name?: string;
280
274
  /**
281
- * Command description
282
- * @description command description is used to describe the command in usage, so it's recommended to specify.
275
+ * Command description.
276
+ * It's used to describe the command in usage and it's recommended to specify.
283
277
  */
284
278
  description?: string;
285
279
  /**
286
- * whether the command is default or not
287
- * @description if the command is default, it is executed when no sub-command is specified
288
- */
289
- default?: boolean;
290
- /**
291
- * Command options
292
- * @description each option can include a description property to describe the option in usage.
280
+ * Command options.
281
+ * Each option can include a description property to describe the option in usage.
293
282
  */
294
283
  options?: Options;
295
284
  /**
296
- * Command examples
297
- * @description examples of how to use the command.
285
+ * Command examples.
286
+ * examples of how to use the command.
298
287
  */
299
288
  examples?: string;
300
289
  /**
301
- * Command runner, that's the command to be executed
290
+ * Command runner. it's the command to be executed
302
291
  */
303
292
  run: CommandRunner<Options>;
304
293
  /**
305
- * Command resource fetcher
306
- * @experimental
294
+ * Command resource fetcher.
307
295
  */
308
296
  resource?: CommandResourceFetcher<Options>;
309
297
  }
310
298
  /**
311
- * Command resource
312
- * @experimental
299
+ * Command resource.
313
300
  */
314
301
  type CommandResource<Options extends ArgOptions = ArgOptions> = {
315
302
  /**
316
- * Command description
303
+ * Command description.
317
304
  */
318
305
  description: string
319
306
  /**
320
- * Examples usage
307
+ * Examples usage.
321
308
  */
322
309
  examples: string
323
310
  } & { [Option in keyof Options] : string } & {
324
311
  [key: string]: string
325
312
  };
326
313
  /**
327
- * Command resource fetcher
314
+ * Command resource fetcher.
328
315
  * @param ctx A {@link CommandContext | command context}
329
- * @returns A fetched {@link CommandResource | command resource}
330
- * @experimental
316
+ * @returns A fetched {@link CommandResource | command resource}.
331
317
  */
332
318
  type CommandResourceFetcher<
333
319
  Options extends ArgOptions = ArgOptions,
334
320
  Values = ArgValues<Options>
335
321
  > = (ctx: Readonly<CommandContext<Options, Values>>) => Promise<CommandResource<Options>>;
336
322
  /**
337
- * Translation adapter factory
323
+ * Translation adapter factory.
338
324
  */
339
325
  type TranslationAdapterFactory = (options: TranslationAdapterFactoryOptions) => TranslationAdapter;
340
326
  /**
341
- * Translation adapter factory options
327
+ * Translation adapter factory options.
342
328
  */
343
329
  interface TranslationAdapterFactoryOptions {
344
330
  /**
345
- * A locale
331
+ * A locale.
346
332
  */
347
333
  locale: string;
348
334
  /**
349
- * A fallback locale
335
+ * A fallback locale.
350
336
  */
351
337
  fallbackLocale: string;
352
338
  }
353
339
  /**
354
- * Translation adapter
355
- *
356
- * @description
340
+ * Translation adapter.
357
341
  * This adapter is used to custom message formatter like {@link https://github.com/intlify/vue-i18n/blob/master/spec/syntax.ebnf | Intlify message format}, {@link https://github.com/tc39/proposal-intl-messageformat | `Intl.MessageFormat` (MF2)}, and etc.
358
- * This adapter will support localization with your preferred message format
342
+ * This adapter will support localization with your preferred message format.
359
343
  */
360
344
  interface TranslationAdapter<MessageResource = string> {
361
345
  /**
362
- * Get a resource of locale
346
+ * Get a resource of locale.
363
347
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
364
- * @returns A resource of locale. if resource not found, return `undefined`
348
+ * @returns A resource of locale. if resource not found, return `undefined`.
365
349
  */
366
350
  getResource(locale: string): Record<string, string> | undefined;
367
351
  /**
368
- * Set a resource of locale
352
+ * Set a resource of locale.
369
353
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
370
354
  * @param resource A resource of locale
371
355
  */
372
356
  setResource(locale: string, resource: Record<string, string>): void;
373
357
  /**
374
- * Get a message of locale
358
+ * Get a message of locale.
375
359
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
376
360
  * @param key A key of message resource
377
- * @returns A message of locale. if message not found, return `undefined`
361
+ * @returns A message of locale. if message not found, return `undefined`.
378
362
  */
379
363
  getMessage(locale: string, key: string): MessageResource | undefined;
380
364
  /**
381
- * Translate a message
365
+ * Translate a message.
382
366
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
383
367
  * @param key A key of message resource
384
368
  * @param values A values to be resolved in the message
385
- * @returns A translated message, if message is not translated, return `undefined`
369
+ * @returns A translated message, if message is not translated, return `undefined`.
386
370
  */
387
371
  translate(locale: string, key: string, values?: Record<string, unknown>): string | undefined;
388
372
  }
389
373
  /**
390
- * Command runner
374
+ * Command runner.
391
375
  * @param ctx A {@link CommandContext | command context}
392
376
  */
393
377
  type CommandRunner<Options extends ArgOptions = ArgOptions> = (ctx: Readonly<CommandContext<Options>>) => Awaitable<void>;
394
378
  /**
395
- * Lazy command interface
396
- * @description lazy command that's not loaded until it is executed
379
+ * Lazy command interface.
380
+ * Lazy command that's not loaded until it is executed.
397
381
  */
398
382
  type LazyCommand<Options extends ArgOptions = ArgOptions> = () => Awaitable<Command<Options>>;
399
383
  /**
400
- * Define a command type
384
+ * Define a command type.
401
385
  */
402
386
  type Commandable<Options extends ArgOptions> = Command<Options> | LazyCommand<Options>;
403
387
 
404
- export type { Command as C, GenerateNamespacedKey as G, LazyCommand as L, TranslationAdapter as T, CommandOptions as a, CommandContext as b, CommandRunner as c, TranslationAdapterFactoryOptions as d, CommandBuiltinOptionsKeys as e, CommandBuiltinResourceKeys as f, CommandBuiltinKeys as g, CommandEnvironment as h, CommandResource as i, CommandResourceFetcher as j, TranslationAdapterFactory as k, Commandable as l };
388
+ export { DEFAULT_LOCALE as D };
389
+ export type { Command as C, GenerateNamespacedKey as G, LazyCommand as L, TranslationAdapter as T, CommandOptions as a, CommandRunner as b, TranslationAdapterFactoryOptions as c, CommandBuiltinOptionsKeys as d, CommandBuiltinResourceKeys as e, CommandBuiltinKeys as f, CommandEnvironment as g, CommandContext as h, CommandResource as i, CommandResourceFetcher as j, TranslationAdapterFactory as k, Commandable as l };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gunshi",
3
3
  "description": "Modern javascript command-line library",
4
- "version": "0.11.0",
4
+ "version": "0.12.0",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",
7
7
  "email": "kawakazu80@gmail.com"
@@ -41,12 +41,6 @@
41
41
  "require": "./lib/index.js",
42
42
  "default": "./lib/index.js"
43
43
  },
44
- "./context": {
45
- "types": "./lib/context.d.ts",
46
- "import": "./lib/context.js",
47
- "require": "./lib/context.js",
48
- "default": "./lib/context.js"
49
- },
50
44
  "./renderer": {
51
45
  "types": "./lib/renderer/index.d.ts",
52
46
  "import": "./lib/renderer/index.js",
@@ -72,7 +66,7 @@
72
66
  }
73
67
  },
74
68
  "dependencies": {
75
- "args-tokens": "^0.12.0"
69
+ "args-tokens": "^0.14.0"
76
70
  },
77
71
  "devDependencies": {
78
72
  "@eslint/markdown": "^6.3.0",
@@ -102,10 +96,14 @@
102
96
  "pkg-pr-new": "^0.0.41",
103
97
  "prettier": "^3.5.3",
104
98
  "tsdown": "^0.6.10",
99
+ "typedoc": "^0.28.1",
100
+ "typedoc-plugin-markdown": "^4.6.0",
101
+ "typedoc-vitepress-theme": "^1.1.2",
105
102
  "typescript": "^5.8.2",
106
103
  "typescript-eslint": "^8.28.0",
107
104
  "vitepress": "^1.6.3",
108
105
  "vitepress-plugin-group-icons": "^1.3.8",
106
+ "vitepress-plugin-llms": "^0.0.21",
109
107
  "vitest": "^3.0.9"
110
108
  },
111
109
  "prettier": "@kazupon/prettier-config",
@@ -128,8 +126,12 @@
128
126
  "clean": "git clean -df",
129
127
  "dev": "pnpx @eslint/config-inspector --config eslint.config.ts",
130
128
  "dev:eslint": "pnpx @eslint/config-inspector --config eslint.config.ts",
131
- "docs:build": "vitepress build docs",
132
- "docs:dev": "vitepress dev docs",
129
+ "dev:typedoc": "typedoc --watch --preserveWatchOutput",
130
+ "docs:build": "pnpm run docs:build:typedoc && pnpm docs:build:vitepress",
131
+ "docs:build:typedoc": "typedoc",
132
+ "docs:build:vitepress": "vitepress build docs",
133
+ "docs:dev": "pnpm run docs:build:typedoc && pnpm docs:dev:vitepress",
134
+ "docs:dev:vitepress": "vitepress dev docs",
133
135
  "docs:preview": "vitepress preview docs",
134
136
  "fix": "pnpm run --stream --color \"/^fix:/\"",
135
137
  "fix:eslint": "eslint . --fix",
@@ -1,96 +0,0 @@
1
- import { COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, create, resolveLazyCommand } from "./utils-zZSVaYTy.js";
2
- import { createCommandContext } from "./context-ZNBQwQKN.js";
3
- import { renderHeader, renderUsage, renderValidationErrors } from "./renderer-Dm_6iF2f.js";
4
- import { parseArgs, resolveArgs } from "args-tokens";
5
-
6
- //#region src/cli.ts
7
- async function cli(args, entry, opts = {}) {
8
- const tokens = parseArgs(args);
9
- const subCommand = getSubCommand(tokens);
10
- const resolvedCommandOptions = resolveCommandOptions(opts, entry);
11
- const [name, command] = await resolveCommand(subCommand, entry, resolvedCommandOptions);
12
- if (!command) throw new Error(`Command not found: ${name || ""}`);
13
- const options = resolveArgOptions(command.options);
14
- const { values, positionals, error } = resolveArgs(options, tokens);
15
- const omitted = !subCommand;
16
- const ctx = await createCommandContext({
17
- options,
18
- values,
19
- positionals,
20
- omitted,
21
- command,
22
- commandOptions: resolvedCommandOptions
23
- });
24
- if (values.version) {
25
- showVersion(ctx);
26
- return;
27
- }
28
- const usageBuffer = [];
29
- const header = await showHeader(ctx);
30
- if (header) usageBuffer.push(header);
31
- if (values.help) {
32
- const usage = await showUsage(ctx);
33
- if (usage) usageBuffer.push(usage);
34
- return usageBuffer.join("\n");
35
- }
36
- if (error) {
37
- await showValidationErrors(ctx, error);
38
- return;
39
- }
40
- await command.run(ctx);
41
- }
42
- function resolveArgOptions(options) {
43
- return Object.assign(create(), options, COMMON_OPTIONS);
44
- }
45
- function resolveCommandOptions(options, entry) {
46
- const subCommands = new Map(options.subCommands);
47
- if (typeof entry === "object" && entry.name) subCommands.set(entry.name, entry);
48
- const resolvedOptions = Object.assign(create(), COMMAND_OPTIONS_DEFAULT, options, { subCommands });
49
- return resolvedOptions;
50
- }
51
- function getSubCommand(tokens) {
52
- const firstToken = tokens[0];
53
- return firstToken && firstToken.kind === "positional" && firstToken.index === 0 && firstToken.value ? firstToken.value : "";
54
- }
55
- async function showUsage(ctx) {
56
- if (ctx.env.renderUsage === null) return;
57
- const usage = await (ctx.env.renderUsage || renderUsage)(ctx);
58
- if (usage) {
59
- ctx.log(usage);
60
- return usage;
61
- }
62
- }
63
- function showVersion(ctx) {
64
- ctx.log(ctx.env.version);
65
- }
66
- async function showHeader(ctx) {
67
- if (ctx.env.renderHeader === null) return;
68
- const header = await (ctx.env.renderHeader || renderHeader)(ctx);
69
- if (header) {
70
- ctx.log(header);
71
- ctx.log();
72
- return header;
73
- }
74
- }
75
- async function showValidationErrors(ctx, error) {
76
- if (ctx.env.renderValidationErrors === null) return;
77
- const render = ctx.env.renderValidationErrors || renderValidationErrors;
78
- ctx.log(await render(ctx, error));
79
- }
80
- async function resolveCommand(sub, entry, options) {
81
- const omitted = !sub;
82
- if (typeof entry === "function") return [void 0, {
83
- run: entry,
84
- default: true
85
- }];
86
- else if (omitted) return typeof entry === "object" ? [entry.name, await resolveLazyCommand(entry, void 0, true)] : [void 0, void 0];
87
- else {
88
- if (options.subCommands == null) return [sub, void 0];
89
- const cmd = options.subCommands?.get(sub);
90
- if (cmd == null) return [sub, void 0];
91
- return [sub, await resolveLazyCommand(cmd, sub)];
92
- }
93
- }
94
-
95
- //#endregion
96
- export { cli };
package/lib/context.d.ts DELETED
@@ -1,46 +0,0 @@
1
- import { ArgOptions, ArgValues } from 'args-tokens';
2
- import { C as Command, a as CommandOptions, b as CommandContext } from './types.d-VymWn7vz.js';
3
-
4
- /**
5
- * Parameters of {@link createCommandContext}
6
- */
7
- interface CommandContextParams<
8
- Options extends ArgOptions,
9
- Values
10
- > {
11
- /**
12
- * An options of target command
13
- */
14
- options: Options;
15
- /**
16
- * A values of target command
17
- */
18
- values: Values;
19
- /**
20
- * A positionals arguments, which passed to the target command
21
- */
22
- positionals: string[];
23
- /**
24
- * Whether the command is omitted
25
- */
26
- omitted: boolean;
27
- /**
28
- * A target {@link Command | command}
29
- */
30
- command: Command<Options>;
31
- /**
32
- * A command options, which is spicialized from `cli` function
33
- */
34
- commandOptions: CommandOptions<Options>;
35
- }
36
- /**
37
- * Create a {@link CommandContext | command context}
38
- * @param param A {@link CommandContextParams | parameters} to create a {@link CommandContext | command context}
39
- * @returns A {@link CommandContext | command context}, which is readonly
40
- */
41
- declare function createCommandContext<
42
- Options extends ArgOptions = ArgOptions,
43
- Values extends ArgValues<Options> = ArgValues<Options>
44
- >({ options, values, positionals, command, commandOptions, omitted }: CommandContextParams<Options, Values>): Promise<Readonly<CommandContext<Options, Values>>>;
45
-
46
- export { createCommandContext };
package/lib/context.js DELETED
@@ -1,4 +0,0 @@
1
- import "./utils-zZSVaYTy.js";
2
- import { createCommandContext } from "./context-ZNBQwQKN.js";
3
-
4
- export { createCommandContext };
@@ -1,67 +0,0 @@
1
-
2
- //#region src/constants.ts
3
- const DEFAULT_LOCALE = "en-US";
4
- const BUILT_IN_PREFIX = "_";
5
- const BUILT_IN_KEY_SEPARATOR = ":";
6
- const NOOP = () => {};
7
- const COMMON_OPTIONS = {
8
- help: {
9
- type: "boolean",
10
- short: "h",
11
- description: "Display this help message"
12
- },
13
- version: {
14
- type: "boolean",
15
- short: "v",
16
- description: "Display this version"
17
- }
18
- };
19
- const COMMAND_OPTIONS_DEFAULT = {
20
- name: void 0,
21
- description: void 0,
22
- version: void 0,
23
- cwd: void 0,
24
- usageSilent: false,
25
- subCommands: void 0,
26
- leftMargin: 2,
27
- middleMargin: 10,
28
- usageOptionType: false,
29
- renderHeader: void 0,
30
- renderUsage: void 0,
31
- renderValidationErrors: void 0,
32
- translationAdapterFactory: void 0
33
- };
34
-
35
- //#endregion
36
- //#region src/utils.ts
37
- async function resolveLazyCommand(cmd, name, entry = false) {
38
- const resolved = Object.assign(create(), typeof cmd == "function" ? await cmd() : cmd, { default: entry });
39
- if (resolved.name == null && name) resolved.name = name;
40
- return deepFreeze(resolved);
41
- }
42
- function resolveBuiltInKey(key) {
43
- return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
44
- }
45
- function mapResourceWithBuiltinKey(resource) {
46
- return Object.entries(resource).reduce((acc, [key, value]) => {
47
- acc[resolveBuiltInKey(key)] = value;
48
- return acc;
49
- }, create());
50
- }
51
- function create(obj = null) {
52
- return Object.create(obj);
53
- }
54
- function log(...args) {
55
- console.log(...args);
56
- }
57
- function deepFreeze(obj) {
58
- if (obj === null || typeof obj !== "object") return obj;
59
- for (const key of Object.keys(obj)) {
60
- const value = obj[key];
61
- if (typeof value === "object" && value !== null) deepFreeze(value);
62
- }
63
- return Object.freeze(obj);
64
- }
65
-
66
- //#endregion
67
- export { BUILT_IN_PREFIX, COMMAND_OPTIONS_DEFAULT, COMMON_OPTIONS, DEFAULT_LOCALE, NOOP, create, deepFreeze, log, mapResourceWithBuiltinKey, resolveBuiltInKey, resolveLazyCommand };