gunshi 0.10.4 → 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,13 +1,13 @@
1
1
  import { ArgOptions } from 'args-tokens';
2
- import { C as Command, c as CommandRunner, a as CommandOptions } from './types.d-Cs9oV60-.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
- * @param entry - A {@link Command | entry command} or an {@link CommandRunner | inline command runner}
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
- declare function generate<Options extends ArgOptions = ArgOptions>(command: string | null, entry: Command<Options> | CommandRunner<Options>, opts?: CommandOptions<Options>): Promise<string>;
11
+ declare function generate<Options extends ArgOptions = ArgOptions>(command: string | null, entry: Command<Options>, opts?: CommandOptions<Options>): Promise<string>;
12
12
 
13
13
  export { generate };
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-Cs9oV60-.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-Cs9oV60-.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-Cs9oV60-.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 = "_";
@@ -31,11 +31,19 @@ declare const __constants_ts_COMMON_OPTIONS: typeof COMMON_OPTIONS;
31
31
  declare const __constants_ts_DEFAULT_LOCALE: typeof DEFAULT_LOCALE;
32
32
  declare const __constants_ts_NOOP: typeof NOOP;
33
33
  declare namespace __constants_ts {
34
- export { __constants_ts_BUILT_IN_KEY_SEPARATOR as BUILT_IN_KEY_SEPARATOR, __constants_ts_BUILT_IN_PREFIX as BUILT_IN_PREFIX, __constants_ts_COMMAND_BUILTIN_RESOURCE_KEYS as COMMAND_BUILTIN_RESOURCE_KEYS, __constants_ts_COMMAND_OPTIONS_DEFAULT as COMMAND_OPTIONS_DEFAULT, __constants_ts_COMMON_OPTIONS as COMMON_OPTIONS, __constants_ts_DEFAULT_LOCALE as DEFAULT_LOCALE, __constants_ts_NOOP as NOOP };
34
+ export {
35
+ __constants_ts_BUILT_IN_KEY_SEPARATOR as BUILT_IN_KEY_SEPARATOR,
36
+ __constants_ts_BUILT_IN_PREFIX as BUILT_IN_PREFIX,
37
+ __constants_ts_COMMAND_BUILTIN_RESOURCE_KEYS as COMMAND_BUILTIN_RESOURCE_KEYS,
38
+ __constants_ts_COMMAND_OPTIONS_DEFAULT as COMMAND_OPTIONS_DEFAULT,
39
+ __constants_ts_COMMON_OPTIONS as COMMON_OPTIONS,
40
+ __constants_ts_DEFAULT_LOCALE as DEFAULT_LOCALE,
41
+ __constants_ts_NOOP as NOOP,
42
+ };
35
43
  }
36
44
 
37
45
  /**
38
- * Define a promise type that can be await from T
46
+ * Define a promise type that can be await from T.
39
47
  */
40
48
  type Awaitable<T> = T | Promise<T>;
41
49
  type GenerateNamespacedKey<
@@ -43,216 +51,211 @@ type GenerateNamespacedKey<
43
51
  Prefixed extends string = typeof BUILT_IN_PREFIX
44
52
  > = `${Prefixed}${typeof BUILT_IN_KEY_SEPARATOR}${Key}`;
45
53
  /**
46
- * Command i18n built-in options keys
47
- * @experimental
54
+ * Command i18n built-in options keys.
48
55
  */
49
56
  type CommandBuiltinOptionsKeys = keyof (typeof __constants_ts)["COMMON_OPTIONS"];
50
57
  /**
51
- * Command i18n built-in resource keys
52
- * @experimental
58
+ * Command i18n built-in resource keys.
53
59
  */
54
60
  type CommandBuiltinResourceKeys = (typeof __constants_ts)["COMMAND_BUILTIN_RESOURCE_KEYS"][number];
55
61
  /**
56
- * Command i18n built-in keys
57
- * @description The command i18n built-in keys are used to {@link CommandContext.translate | translate} function
58
- * @experimental
62
+ * Command i18n built-in keys.
63
+ * The command i18n built-in keys are used to {@link CommandContext.translate | translate} function.
59
64
  */
60
65
  type CommandBuiltinKeys = GenerateNamespacedKey<CommandBuiltinOptionsKeys> | GenerateNamespacedKey<CommandBuiltinResourceKeys> | "description" | "examples";
61
66
  /**
62
- * Command environment
67
+ * Command environment.
63
68
  */
64
69
  interface CommandEnvironment<Options extends ArgOptions = ArgOptions> {
65
70
  /**
66
- * Current working directory
71
+ * Current working directory.
67
72
  * @see {@link CommandOptions.cwd}
68
73
  */
69
74
  cwd: string | undefined;
70
75
  /**
71
- * Command name
76
+ * Command name.
72
77
  * @see {@link CommandOptions.name}
73
78
  */
74
79
  name: string | undefined;
75
80
  /**
76
- * Command description
81
+ * Command description.
77
82
  * @see {@link CommandOptions.description}
78
83
  *
79
84
  */
80
85
  description: string | undefined;
81
86
  /**
82
- * Command version
87
+ * Command version.
83
88
  * @see {@link CommandOptions.version}
84
89
  */
85
90
  version: string | undefined;
86
91
  /**
87
- * Left margin of the command output
92
+ * Left margin of the command output.
88
93
  * @default 2
89
94
  * @see {@link CommandOptions.leftMargin}
90
95
  */
91
96
  leftMargin: number;
92
97
  /**
93
- * Middle margin of the command output
98
+ * Middle margin of the command output.
94
99
  * @default 10
95
100
  * @see {@link CommandOptions.middleMargin}
96
101
  */
97
102
  middleMargin: number;
98
103
  /**
99
- * Whether to display the usage option type
104
+ * Whether to display the usage option type.
100
105
  * @default false
101
106
  * @see {@link CommandOptions.usageOptionType}
102
107
  */
103
108
  usageOptionType: boolean;
104
109
  /**
105
- * Whether to display the command usage
110
+ * Whether to display the command usage.
106
111
  * @default false
107
112
  * @see {@link}
108
113
  */
109
114
  usageSilent: boolean;
110
115
  /**
111
- * Sub commands
116
+ * Sub commands.
112
117
  * @see {@link CommandOptions.subCommands}
113
118
  */
114
119
  subCommands: Map<string, Command<any> | LazyCommand<any>> | undefined;
115
120
  /**
116
- * Render function the command usage
121
+ * Render function the command usage.
117
122
  */
118
123
  renderUsage: ((ctx: CommandContext<Options>) => Promise<string>) | null | undefined;
119
124
  /**
120
- * Render function the header section in the command usage
125
+ * Render function the header section in the command usage.
121
126
  */
122
127
  renderHeader: ((ctx: CommandContext<Options>) => Promise<string>) | null | undefined;
123
128
  /**
124
- * Render function the validation errors
129
+ * Render function the validation errors.
125
130
  */
126
131
  renderValidationErrors: ((ctx: CommandContext<Options>, error: AggregateError) => Promise<string>) | null | undefined;
127
132
  }
128
133
  /**
129
- * Command options
134
+ * Command options.
130
135
  */
131
136
  interface CommandOptions<Options extends ArgOptions = ArgOptions> {
132
137
  /**
133
- * Current working directory
138
+ * Current working directory.
134
139
  */
135
140
  cwd?: string;
136
141
  /**
137
- * Command program name
142
+ * Command program name.
138
143
  */
139
144
  name?: string;
140
145
  /**
141
- * Command program description
146
+ * Command program description.
142
147
  *
143
148
  */
144
149
  description?: string;
145
150
  /**
146
- * Command program version
151
+ * Command program version.
147
152
  */
148
153
  version?: string;
149
154
  /**
150
- * Command program locale
155
+ * Command program locale.
151
156
  */
152
157
  locale?: string | Intl.Locale;
153
158
  /**
154
- * Sub commands
159
+ * Sub commands.
155
160
  */
156
161
  subCommands?: Map<string, Command<any> | LazyCommand<any>>;
157
162
  /**
158
- * Left margin of the command output
163
+ * Left margin of the command output.
159
164
  */
160
165
  leftMargin?: number;
161
166
  /**
162
- * Middle margin of the command output
167
+ * Middle margin of the command output.
163
168
  */
164
169
  middleMargin?: number;
165
170
  /**
166
- * Whether to display the usage option type
171
+ * Whether to display the usage option type.
167
172
  */
168
173
  usageOptionType?: boolean;
169
174
  /**
170
- * Whether to display the command usage
175
+ * Whether to display the command usage.
171
176
  */
172
177
  usageSilent?: boolean;
173
178
  /**
174
- * Render function the command usage
179
+ * Render function the command usage.
175
180
  */
176
181
  renderUsage?: ((ctx: Readonly<CommandContext<Options>>) => Promise<string>) | null;
177
182
  /**
178
- * Render function the header section in the command usage
183
+ * Render function the header section in the command usage.
179
184
  */
180
185
  renderHeader?: ((ctx: Readonly<CommandContext<Options>>) => Promise<string>) | null;
181
186
  /**
182
- * Render function the validation errors
187
+ * Render function the validation errors.
183
188
  */
184
189
  renderValidationErrors?: ((ctx: Readonly<CommandContext<Options>>, error: AggregateError) => Promise<string>) | null;
185
190
  /**
186
- * Translation adapter factory
187
- * @experimental
191
+ * Translation adapter factory.
188
192
  */
189
193
  translationAdapterFactory?: TranslationAdapterFactory;
190
194
  }
191
195
  /**
192
- * Command context
193
- * @description Command context is the context of the command execution
196
+ * Command context.
197
+ * Command context is the context of the command execution.
194
198
  */
195
199
  interface CommandContext<
196
200
  Options extends ArgOptions = ArgOptions,
197
201
  Values = ArgValues<Options>
198
202
  > {
199
203
  /**
200
- * Command name, that is the command that is executed
201
- * @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}.
202
206
  */
203
207
  name: string | undefined;
204
208
  /**
205
- * Command description, that is the description of the command that is executed
206
- * @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}.
207
211
  */
208
212
  description: string | undefined;
209
213
  /**
210
- * 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.
211
215
  */
212
216
  locale: Intl.Locale;
213
217
  /**
214
- * Command environment, that is the environment of the command that is executed
215
- * @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}.
216
220
  */
217
221
  env: Readonly<CommandEnvironment<Options>>;
218
222
  /**
219
- * Command options, that is the options of the command that is executed
220
- * @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}.
221
225
  */
222
226
  options: Options;
223
227
  /**
224
- * Command values, that is the values of the command that is executed
225
- * @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}.
226
230
  */
227
231
  values: Values;
228
232
  /**
229
- * Command positionals arguments, that is the positionals of the command that is executed
230
- * @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.
231
235
  */
232
236
  positionals: string[];
233
237
  /**
234
- * 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.
235
239
  */
236
240
  omitted: boolean;
237
241
  /**
238
- * Output a message
239
- * @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.
240
244
  * @param message an output message, @see {@link console.log}
241
245
  * @param optionalParams an optional parameters, @see {@link console.log}
242
246
  */
243
247
  log: (message?: any, ...optionalParams: any[]) => void;
244
248
  /**
245
- * Load sub-commands
246
- * @description The loaded commands are cached and returned when called again
247
- * @returns loaded commands
249
+ * Load sub-commands.
250
+ * The loaded commands are cached and returned when called again.
251
+ * @returns loaded commands.
248
252
  */
249
253
  loadCommands: () => Promise<Command<Options>[]>;
250
254
  /**
251
- * Translate function
255
+ * Translate function.
252
256
  * @param key the key to be translated
253
257
  * @param values the values to be formatted
254
- * @returns A translated string
255
- * @experimental
258
+ * @returns A translated string.
256
259
  */
257
260
  translate: <
258
261
  T extends string = CommandBuiltinKeys,
@@ -260,137 +263,127 @@ interface CommandContext<
260
263
  >(key: Key, values?: Record<string, unknown>) => string;
261
264
  }
262
265
  /**
263
- * Command interface
266
+ * Command interface.
264
267
  */
265
268
  interface Command<Options extends ArgOptions = ArgOptions> {
266
269
  /**
267
- * Command name
268
- * @description
269
- * 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.
270
272
  */
271
273
  name?: string;
272
274
  /**
273
- * Command description
274
- * @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.
275
277
  */
276
278
  description?: string;
277
279
  /**
278
- * whether the command is default or not
279
- * @description if the command is default, it is executed when no sub-command is specified
280
- */
281
- default?: boolean;
282
- /**
283
- * Command options
284
- * @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.
285
282
  */
286
283
  options?: Options;
287
284
  /**
288
- * Command examples
289
- * @description examples of how to use the command.
285
+ * Command examples.
286
+ * examples of how to use the command.
290
287
  */
291
288
  examples?: string;
292
289
  /**
293
- * Command runner, that's the command to be executed
290
+ * Command runner. it's the command to be executed
294
291
  */
295
292
  run: CommandRunner<Options>;
296
293
  /**
297
- * Command resource fetcher
298
- * @experimental
294
+ * Command resource fetcher.
299
295
  */
300
296
  resource?: CommandResourceFetcher<Options>;
301
297
  }
302
298
  /**
303
- * Command resource
304
- * @experimental
299
+ * Command resource.
305
300
  */
306
301
  type CommandResource<Options extends ArgOptions = ArgOptions> = {
307
302
  /**
308
- * Command description
303
+ * Command description.
309
304
  */
310
305
  description: string
311
306
  /**
312
- * Examples usage
307
+ * Examples usage.
313
308
  */
314
309
  examples: string
315
310
  } & { [Option in keyof Options] : string } & {
316
311
  [key: string]: string
317
312
  };
318
313
  /**
319
- * Command resource fetcher
314
+ * Command resource fetcher.
320
315
  * @param ctx A {@link CommandContext | command context}
321
- * @returns A fetched {@link CommandResource | command resource}
322
- * @experimental
316
+ * @returns A fetched {@link CommandResource | command resource}.
323
317
  */
324
318
  type CommandResourceFetcher<
325
319
  Options extends ArgOptions = ArgOptions,
326
320
  Values = ArgValues<Options>
327
321
  > = (ctx: Readonly<CommandContext<Options, Values>>) => Promise<CommandResource<Options>>;
328
322
  /**
329
- * Translation adapter factory
323
+ * Translation adapter factory.
330
324
  */
331
325
  type TranslationAdapterFactory = (options: TranslationAdapterFactoryOptions) => TranslationAdapter;
332
326
  /**
333
- * Translation adapter factory options
327
+ * Translation adapter factory options.
334
328
  */
335
329
  interface TranslationAdapterFactoryOptions {
336
330
  /**
337
- * A locale
331
+ * A locale.
338
332
  */
339
333
  locale: string;
340
334
  /**
341
- * A fallback locale
335
+ * A fallback locale.
342
336
  */
343
337
  fallbackLocale: string;
344
338
  }
345
339
  /**
346
- * Translation adapter
347
- *
348
- * @description
340
+ * Translation adapter.
349
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.
350
- * This adapter will support localization with your preferred message format
342
+ * This adapter will support localization with your preferred message format.
351
343
  */
352
344
  interface TranslationAdapter<MessageResource = string> {
353
345
  /**
354
- * Get a resource of locale
346
+ * Get a resource of locale.
355
347
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
356
- * @returns A resource of locale. if resource not found, return `undefined`
348
+ * @returns A resource of locale. if resource not found, return `undefined`.
357
349
  */
358
350
  getResource(locale: string): Record<string, string> | undefined;
359
351
  /**
360
- * Set a resource of locale
352
+ * Set a resource of locale.
361
353
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
362
354
  * @param resource A resource of locale
363
355
  */
364
356
  setResource(locale: string, resource: Record<string, string>): void;
365
357
  /**
366
- * Get a message of locale
358
+ * Get a message of locale.
367
359
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
368
360
  * @param key A key of message resource
369
- * @returns A message of locale. if message not found, return `undefined`
361
+ * @returns A message of locale. if message not found, return `undefined`.
370
362
  */
371
363
  getMessage(locale: string, key: string): MessageResource | undefined;
372
364
  /**
373
- * Translate a message
365
+ * Translate a message.
374
366
  * @param locale A Locale at the time of command execution. That is Unicord locale ID (BCP 47)
375
367
  * @param key A key of message resource
376
368
  * @param values A values to be resolved in the message
377
- * @returns A translated message, if message is not translated, return `undefined`
369
+ * @returns A translated message, if message is not translated, return `undefined`.
378
370
  */
379
371
  translate(locale: string, key: string, values?: Record<string, unknown>): string | undefined;
380
372
  }
381
373
  /**
382
- * Command runner
374
+ * Command runner.
383
375
  * @param ctx A {@link CommandContext | command context}
384
376
  */
385
377
  type CommandRunner<Options extends ArgOptions = ArgOptions> = (ctx: Readonly<CommandContext<Options>>) => Awaitable<void>;
386
378
  /**
387
- * Lazy command interface
388
- * @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.
389
381
  */
390
382
  type LazyCommand<Options extends ArgOptions = ArgOptions> = () => Awaitable<Command<Options>>;
391
383
  /**
392
- * Define a command type
384
+ * Define a command type.
393
385
  */
394
386
  type Commandable<Options extends ArgOptions> = Command<Options> | LazyCommand<Options>;
395
387
 
396
- 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.10.4",
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,21 +66,22 @@
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
- "@eslint/markdown": "^6.2.2",
72
+ "@eslint/markdown": "^6.3.0",
79
73
  "@intlify/core": "next",
80
74
  "@kazupon/eslint-config": "^0.26.1",
81
75
  "@kazupon/prettier-config": "^0.1.1",
82
- "@types/node": "^22.13.9",
83
- "@vitest/eslint-plugin": "^1.1.36",
84
- "bumpp": "^10.0.3",
85
- "eslint": "^9.22.0",
86
- "eslint-config-prettier": "^10.0.2",
87
- "eslint-import-resolver-typescript": "^4.2.2",
76
+ "@types/node": "^22.13.14",
77
+ "@vitest/eslint-plugin": "^1.1.38",
78
+ "bumpp": "^10.1.0",
79
+ "deno": "^2.2.6",
80
+ "eslint": "^9.23.0",
81
+ "eslint-config-prettier": "^10.1.1",
82
+ "eslint-import-resolver-typescript": "^4.2.7",
88
83
  "eslint-plugin-import": "^2.31.0",
89
- "eslint-plugin-jsonc": "^2.19.1",
84
+ "eslint-plugin-jsonc": "^2.20.0",
90
85
  "eslint-plugin-module-interop": "^0.3.0",
91
86
  "eslint-plugin-promise": "^7.2.1",
92
87
  "eslint-plugin-regexp": "^2.7.0",
@@ -95,17 +90,21 @@
95
90
  "eslint-plugin-yml": "^1.17.0",
96
91
  "gh-changelogen": "^0.2.8",
97
92
  "jsr": "^0.13.4",
98
- "knip": "^5.45.0",
99
- "lint-staged": "^15.4.3",
93
+ "knip": "^5.46.3",
94
+ "lint-staged": "^15.5.0",
100
95
  "messageformat": "4.0.0-10",
101
96
  "pkg-pr-new": "^0.0.41",
102
97
  "prettier": "^3.5.3",
103
- "tsdown": "^0.6.4",
104
- "typescript": "^5.4.2",
105
- "typescript-eslint": "^8.26.0",
98
+ "tsdown": "^0.6.10",
99
+ "typedoc": "^0.28.1",
100
+ "typedoc-plugin-markdown": "^4.6.0",
101
+ "typedoc-vitepress-theme": "^1.1.2",
102
+ "typescript": "^5.8.2",
103
+ "typescript-eslint": "^8.28.0",
106
104
  "vitepress": "^1.6.3",
107
105
  "vitepress-plugin-group-icons": "^1.3.8",
108
- "vitest": "^3.0.7"
106
+ "vitepress-plugin-llms": "^0.0.21",
107
+ "vitest": "^3.0.9"
109
108
  },
110
109
  "prettier": "@kazupon/prettier-config",
111
110
  "lint-staged": {
@@ -127,8 +126,12 @@
127
126
  "clean": "git clean -df",
128
127
  "dev": "pnpx @eslint/config-inspector --config eslint.config.ts",
129
128
  "dev:eslint": "pnpx @eslint/config-inspector --config eslint.config.ts",
130
- "docs:build": "vitepress build docs",
131
- "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",
132
135
  "docs:preview": "vitepress preview docs",
133
136
  "fix": "pnpm run --stream --color \"/^fix:/\"",
134
137
  "fix:eslint": "eslint . --fix",
@@ -141,6 +144,8 @@
141
144
  "lint:prettier": "prettier . --check",
142
145
  "release": "bumpp --commit \"release: v%s\" --all --push --tag",
143
146
  "test": "vitest run",
144
- "typecheck": "tsc --noEmit"
147
+ "typecheck": "pnpm run --stream --color \"/^typecheck:/\"",
148
+ "typecheck:deno": "deno check --all ./src",
149
+ "typecheck:tsc": "tsc --noEmit"
145
150
  }
146
151
  }
@@ -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-Cs9oV60-.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 };