@gunshi/plugin-renderer 0.27.0-alpha.8 → 0.27.0-alpha.9
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/lib/index.d.ts +25 -58
- package/lib/index.js +115 -49
- package/package.json +7 -7
package/lib/index.d.ts
CHANGED
|
@@ -1,50 +1,7 @@
|
|
|
1
|
-
import { Command, CommandContext, DefaultGunshiParams, GunshiParams, PluginWithExtension } from "@gunshi/plugin";
|
|
2
|
-
import { Args
|
|
1
|
+
import { Args, Command, CommandContext, DefaultGunshiParams, GunshiParams, PluginWithExtension } from "@gunshi/plugin";
|
|
2
|
+
import { Args as Args$1 } from "args-tokens";
|
|
3
3
|
|
|
4
4
|
//#region rolldown:runtime
|
|
5
|
-
|
|
6
|
-
//#endregion
|
|
7
|
-
//#region ../gunshi/src/types.d.ts
|
|
8
|
-
/**
|
|
9
|
-
* Extend command context type. This type is used to extend the command context with additional properties at {@link CommandContext.extensions}.
|
|
10
|
-
* @since v0.27.0
|
|
11
|
-
*/
|
|
12
|
-
type ExtendContext = Record<string, unknown>;
|
|
13
|
-
/**
|
|
14
|
-
* Gunshi unified parameter type.
|
|
15
|
-
* This type combines both argument definitions and command context extensions.
|
|
16
|
-
* @since v0.27.0
|
|
17
|
-
*/
|
|
18
|
-
interface GunshiParams$1<P extends {
|
|
19
|
-
args?: Args;
|
|
20
|
-
extensions?: ExtendContext;
|
|
21
|
-
} = {
|
|
22
|
-
args: Args;
|
|
23
|
-
extensions: {};
|
|
24
|
-
}> {
|
|
25
|
-
/**
|
|
26
|
-
* Command argument definitions
|
|
27
|
-
*/
|
|
28
|
-
args: P extends {
|
|
29
|
-
args: infer A extends Args;
|
|
30
|
-
} ? A : Args;
|
|
31
|
-
/**
|
|
32
|
-
* Command context extensions
|
|
33
|
-
*/
|
|
34
|
-
extensions: P extends {
|
|
35
|
-
extensions: infer E extends ExtendContext;
|
|
36
|
-
} ? E : {};
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Default Gunshi parameters
|
|
40
|
-
* @since v0.27.0
|
|
41
|
-
*/
|
|
42
|
-
type DefaultGunshiParams$1 = GunshiParams$1;
|
|
43
|
-
/**
|
|
44
|
-
* Generic constraint for command-related types.
|
|
45
|
-
* This type constraint allows both GunshiParams and objects with extensions.
|
|
46
|
-
* @since v0.27.0
|
|
47
|
-
*/
|
|
48
5
|
declare namespace constants_d_exports {
|
|
49
6
|
export { ARG_NEGATABLE_PREFIX, ARG_PREFIX, ARG_PREFIX_AND_KEY_SEPARATOR, BUILD_IN_PREFIX_AND_KEY_SEPARATOR, BUILT_IN_KEY_SEPARATOR, BUILT_IN_PREFIX, COMMAND_BUILTIN_RESOURCE_KEYS, COMMON_ARGS, PLUGIN_PREFIX };
|
|
50
7
|
}
|
|
@@ -94,28 +51,34 @@ type CommandBuiltinArgsKeys = keyof (typeof constants_d_exports)['COMMON_ARGS'];
|
|
|
94
51
|
*/
|
|
95
52
|
type CommandBuiltinResourceKeys = (typeof constants_d_exports)['COMMAND_BUILTIN_RESOURCE_KEYS'][number];
|
|
96
53
|
/**
|
|
97
|
-
*
|
|
54
|
+
* Built-in resource keys.
|
|
98
55
|
*/
|
|
99
56
|
type BuiltinResourceKeys = CommandBuiltinArgsKeys | CommandBuiltinResourceKeys;
|
|
100
57
|
/**
|
|
101
|
-
* Command
|
|
102
|
-
* The command i18n built-in keys are used by the i18n plugin for translation.
|
|
58
|
+
* Command built-in keys.
|
|
103
59
|
*/
|
|
104
|
-
type CommandBuiltinKeys = GenerateNamespacedKey<BuiltinResourceKeys
|
|
60
|
+
type CommandBuiltinKeys = GenerateNamespacedKey<BuiltinResourceKeys>;
|
|
105
61
|
/**
|
|
106
62
|
* Command i18n option keys.
|
|
107
63
|
* The command i18n option keys are used by the i18n plugin for translation.
|
|
108
64
|
*/
|
|
109
|
-
type CommandArgKeys<A extends Args$1
|
|
65
|
+
type CommandArgKeys<A extends Args$1, C = {}, K extends string = GenerateNamespacedKey<Extract<KeyOfArgs<RemovedIndex<A>>, string>, typeof ARG_PREFIX>> = C extends {
|
|
66
|
+
name: infer N;
|
|
67
|
+
} ? (N extends string ? GenerateNamespacedKey<K, N> : K) : K;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve translation keys for command context.
|
|
70
|
+
*/
|
|
71
|
+
type ResolveTranslationKeys<A extends Args$1, C = {},
|
|
72
|
+
// for CommandContext
|
|
73
|
+
E extends Record<string, string> = {},
|
|
74
|
+
// for extended resources
|
|
75
|
+
R extends string = keyof RemovedIndex<E>, T extends string = (C extends {
|
|
76
|
+
name: infer N;
|
|
77
|
+
} ? N extends string ? GenerateNamespacedKey<R, N> : R : R | CommandBuiltinKeys), O = CommandArgKeys<A, C>> = CommandBuiltinKeys | O | T;
|
|
110
78
|
/**
|
|
111
79
|
* Translation function interface
|
|
112
80
|
*/
|
|
113
81
|
//#endregion
|
|
114
|
-
//#region ../shared/src/localize.d.ts
|
|
115
|
-
interface Localization<T extends string = CommandBuiltinKeys, G extends GunshiParams$1<any> = DefaultGunshiParams$1> {
|
|
116
|
-
<O = CommandArgKeys<G['args']>, K = CommandBuiltinKeys | O | T>(key: K, values?: Record<string, unknown>): Promise<string>;
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
82
|
//#region src/types.d.ts
|
|
120
83
|
/**
|
|
121
84
|
* Extended command context which provides utilities via usage renderer plugin.
|
|
@@ -125,10 +88,14 @@ interface UsageRendererCommandContext<G extends GunshiParams<any> = DefaultGunsh
|
|
|
125
88
|
/**
|
|
126
89
|
* Render the text message
|
|
127
90
|
*/
|
|
128
|
-
text:
|
|
91
|
+
text: <A extends Args = G['args'], C = {},
|
|
92
|
+
// for CommandContext
|
|
93
|
+
E extends Record<string, string> = {},
|
|
94
|
+
// for extended resources
|
|
95
|
+
K = ResolveTranslationKeys<A, C, E>>(key: K, values?: Record<string, unknown>) => string;
|
|
129
96
|
/**
|
|
130
97
|
* Load commands
|
|
131
|
-
* @returns A list of commands loaded from the
|
|
98
|
+
* @returns A list of commands loaded from the usage renderert plugin.
|
|
132
99
|
*/
|
|
133
100
|
loadCommands: <G extends GunshiParams = DefaultGunshiParams>() => Promise<Command<G>[]>;
|
|
134
101
|
}
|
|
@@ -164,4 +131,4 @@ declare function renderValidationErrors<G extends GunshiParams = DefaultGunshiPa
|
|
|
164
131
|
*/
|
|
165
132
|
declare function renderer(): PluginWithExtension<UsageRendererCommandContext>;
|
|
166
133
|
//#endregion
|
|
167
|
-
export { UsageRendererCommandContext, renderer as default, renderHeader, renderUsage, renderValidationErrors };
|
|
134
|
+
export { type UsageRendererCommandContext, renderer as default, renderHeader, renderUsage, renderValidationErrors };
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { plugin } from "@gunshi/plugin";
|
|
1
|
+
import { ANONYMOUS_COMMAND_NAME, plugin } from "@gunshi/plugin";
|
|
2
2
|
|
|
3
3
|
//#region ../../node_modules/.pnpm/args-tokens@0.22.0/node_modules/args-tokens/lib/utils-N7UlhLbz.js
|
|
4
4
|
/**
|
|
@@ -125,11 +125,35 @@ var en_US_default = {
|
|
|
125
125
|
|
|
126
126
|
//#endregion
|
|
127
127
|
//#region ../shared/src/utils.ts
|
|
128
|
+
/**
|
|
129
|
+
* Resolve a namespaced key for built-in resources.
|
|
130
|
+
* Built-in keys are prefixed with "_:".
|
|
131
|
+
* @param key The built-in key to resolve.
|
|
132
|
+
* @returns Prefixed built-in key.
|
|
133
|
+
*/
|
|
128
134
|
function resolveBuiltInKey(key) {
|
|
129
135
|
return `${BUILT_IN_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
|
|
130
136
|
}
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Resolve a namespaced key for argument resources.
|
|
139
|
+
* Argument keys are prefixed with "arg:".
|
|
140
|
+
* If the command name is provided, it will be prefixed with the command name (e.g. "cmd1:arg:foo").
|
|
141
|
+
* @param key The argument key to resolve.
|
|
142
|
+
* @param ctx The command context.
|
|
143
|
+
* @returns Prefixed argument key.
|
|
144
|
+
*/
|
|
145
|
+
function resolveArgKey(key, ctx) {
|
|
146
|
+
return `${ctx?.name ? `${ctx.name}${BUILT_IN_KEY_SEPARATOR}` : ""}${ARG_PREFIX}${BUILT_IN_KEY_SEPARATOR}${key}`;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Resolve a namespaced key for non-built-in resources.
|
|
150
|
+
* Non-built-in keys are not prefixed with any special characters. If the command name is provided, it will be prefixed with the command name (e.g. "cmd1:foo").
|
|
151
|
+
* @param key The non-built-in key to resolve.
|
|
152
|
+
* @param ctx The command context.
|
|
153
|
+
* @returns Prefixed non-built-in key.
|
|
154
|
+
*/
|
|
155
|
+
function resolveKey(key, ctx) {
|
|
156
|
+
return `${ctx?.name ? `${ctx.name}${BUILT_IN_KEY_SEPARATOR}` : ""}${key}`;
|
|
133
157
|
}
|
|
134
158
|
async function resolveExamples$1(ctx, examples) {
|
|
135
159
|
return typeof examples === "string" ? examples : typeof examples === "function" ? await examples(ctx) : "";
|
|
@@ -145,15 +169,25 @@ function makeShortLongOptionPair(schema, name, toKebab) {
|
|
|
145
169
|
}
|
|
146
170
|
|
|
147
171
|
//#endregion
|
|
148
|
-
//#region ../shared/src/
|
|
172
|
+
//#region ../shared/src/localization.ts
|
|
173
|
+
/**
|
|
174
|
+
* Create a localizable function for a command.
|
|
175
|
+
* This function will resolve the translation key based on the command context and the provided translation function.
|
|
176
|
+
* @param ctx Command context
|
|
177
|
+
* @param cmd Command
|
|
178
|
+
* @param translate Translation function
|
|
179
|
+
* @returns Localizable function
|
|
180
|
+
*/
|
|
149
181
|
function localizable(ctx, cmd, translate) {
|
|
150
182
|
async function localize(key, values) {
|
|
151
183
|
if (translate) return translate(key, values);
|
|
152
|
-
|
|
184
|
+
if (key.startsWith(BUILD_IN_PREFIX_AND_KEY_SEPARATOR)) {
|
|
153
185
|
const resKey = key.slice(BUILD_IN_PREFIX_AND_KEY_SEPARATOR.length);
|
|
154
186
|
return en_US_default[resKey] || key;
|
|
155
|
-
}
|
|
156
|
-
|
|
187
|
+
}
|
|
188
|
+
const namaspacedArgKey = resolveKey(ARG_PREFIX_AND_KEY_SEPARATOR, ctx);
|
|
189
|
+
if (key.startsWith(namaspacedArgKey)) {
|
|
190
|
+
let argKey = key.slice(namaspacedArgKey.length);
|
|
157
191
|
let negatable = false;
|
|
158
192
|
if (argKey.startsWith(ARG_NEGATABLE_PREFIX)) {
|
|
159
193
|
argKey = argKey.slice(ARG_NEGATABLE_PREFIX.length);
|
|
@@ -162,8 +196,9 @@ function localizable(ctx, cmd, translate) {
|
|
|
162
196
|
const schema = ctx.args[argKey];
|
|
163
197
|
if (!schema) return argKey;
|
|
164
198
|
return negatable && schema.type === "boolean" && schema.negatable ? `${en_US_default["NEGATABLE"]} ${makeShortLongOptionPair(schema, argKey, ctx.toKebab)}` : schema.description || "";
|
|
165
|
-
}
|
|
166
|
-
|
|
199
|
+
}
|
|
200
|
+
if (key === resolveKey("description", ctx)) return "";
|
|
201
|
+
else if (key === resolveKey("examples", ctx)) return await resolveExamples$1(ctx, cmd.examples);
|
|
167
202
|
else return key;
|
|
168
203
|
}
|
|
169
204
|
return localize;
|
|
@@ -204,8 +239,8 @@ async function renderUsage(ctx) {
|
|
|
204
239
|
}
|
|
205
240
|
messages.push(...await renderUsageSection(ctx), "");
|
|
206
241
|
if (ctx.omitted && await hasCommands(ctx)) messages.push(...await renderCommandsSection(ctx), "");
|
|
207
|
-
if (hasPositionalArgs(ctx)) messages.push(...await renderPositionalArgsSection(ctx), "");
|
|
208
|
-
if (hasOptionalArgs(ctx)) messages.push(...await renderOptionalArgsSection(ctx), "");
|
|
242
|
+
if (hasPositionalArgs(ctx.args)) messages.push(...await renderPositionalArgsSection(ctx), "");
|
|
243
|
+
if (hasOptionalArgs(ctx.args)) messages.push(...await renderOptionalArgsSection(ctx), "");
|
|
209
244
|
const examples = await renderExamplesSection(ctx);
|
|
210
245
|
if (examples.length > 0) messages.push(...examples, "");
|
|
211
246
|
return messages.join("\n");
|
|
@@ -253,19 +288,21 @@ async function renderExamplesSection(ctx) {
|
|
|
253
288
|
*/
|
|
254
289
|
async function renderUsageSection(ctx) {
|
|
255
290
|
const messages = [`${await ctx.extensions[pluginId].text(resolveBuiltInKey("USAGE"))}:`];
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
messages.push(defaultCommand.padStart(ctx.env.leftMargin + defaultCommand.length));
|
|
259
|
-
if (await hasCommands(ctx)) {
|
|
260
|
-
const commandsUsage = `${await resolveEntry(ctx)} <${await ctx.extensions[pluginId].text(resolveBuiltInKey("COMMANDS"))}>`;
|
|
261
|
-
messages.push(commandsUsage.padStart(ctx.env.leftMargin + commandsUsage.length));
|
|
262
|
-
}
|
|
263
|
-
} else {
|
|
264
|
-
const usageStr = `${await resolveEntry(ctx)} ${await resolveSubCommand(ctx)} ${[await generateOptionsSymbols(ctx), generatePositionalSymbols(ctx)].filter(Boolean).join(" ")}`;
|
|
265
|
-
messages.push(usageStr.padStart(ctx.env.leftMargin + usageStr.length));
|
|
266
|
-
}
|
|
291
|
+
const usageStr = await makeUsageSymbols(ctx);
|
|
292
|
+
messages.push(usageStr.padStart(ctx.env.leftMargin + usageStr.length));
|
|
267
293
|
return messages;
|
|
268
294
|
}
|
|
295
|
+
async function makeUsageSymbols(ctx) {
|
|
296
|
+
const messages = [await resolveEntry(ctx)];
|
|
297
|
+
if (ctx.omitted) if (await hasCommands(ctx)) messages.push(` [${await ctx.extensions[pluginId].text(resolveBuiltInKey("COMMANDS"))}]`);
|
|
298
|
+
else messages.push(`${ctx.callMode === "subCommand" ? ` ${await resolveSubCommand(ctx)}` : ""}`);
|
|
299
|
+
else messages.push(`${ctx.callMode === "subCommand" ? ` ${await resolveSubCommand(ctx)}` : ""}`);
|
|
300
|
+
const optionsSymbols = await generateOptionsSymbols(ctx, ctx.args);
|
|
301
|
+
if (optionsSymbols) messages.push(" ", optionsSymbols);
|
|
302
|
+
const positionalSymbols = generatePositionalSymbols(ctx.args);
|
|
303
|
+
if (positionalSymbols) messages.push(" ", positionalSymbols);
|
|
304
|
+
return messages.join("");
|
|
305
|
+
}
|
|
269
306
|
/**
|
|
270
307
|
* Render the commands section
|
|
271
308
|
* @param ctx A {@link CommandContext | command context}
|
|
@@ -275,19 +312,38 @@ async function renderCommandsSection(ctx) {
|
|
|
275
312
|
const messages = [`${await ctx.extensions[pluginId].text(resolveBuiltInKey("COMMANDS"))}:`];
|
|
276
313
|
const loadedCommands = await ctx.extensions?.[pluginId].loadCommands() || [];
|
|
277
314
|
const commandMaxLength = Math.max(...loadedCommands.map((cmd) => (cmd.name || "").length));
|
|
278
|
-
const commandsStr = await Promise.all(loadedCommands.map((cmd) => {
|
|
279
|
-
const key = cmd.name || "";
|
|
315
|
+
const commandsStr = await Promise.all(loadedCommands.map(async (cmd) => {
|
|
280
316
|
const desc = cmd.description || "";
|
|
281
|
-
const
|
|
282
|
-
|
|
317
|
+
const optionSymbol = await generateOptionsSymbols(ctx, ctx.args);
|
|
318
|
+
const positionalSymbol = generatePositionalSymbols(ctx.args);
|
|
319
|
+
const commandStr = await makeCommandSymbol(ctx, cmd);
|
|
320
|
+
const symbolLength = desc.length > 0 ? commandMaxLength + optionSymbol.length + positionalSymbol.length : 0;
|
|
321
|
+
const command = `${commandStr.padEnd(symbolLength + ctx.env.middleMargin)}${desc}`;
|
|
322
|
+
return `${command.padStart(ctx.env.leftMargin + command.length)}`;
|
|
283
323
|
}));
|
|
284
324
|
messages.push(...commandsStr, "", `${await ctx.extensions[pluginId].text(resolveBuiltInKey("FORMORE"))}:`);
|
|
285
325
|
messages.push(...loadedCommands.map((cmd) => {
|
|
286
|
-
|
|
326
|
+
let commandStr = cmd.entry ? "" : cmd.name || "";
|
|
327
|
+
if (commandStr) commandStr += " ";
|
|
328
|
+
const commandHelp = `${ctx.env.name} ${commandStr}--help`;
|
|
287
329
|
return `${commandHelp.padStart(ctx.env.leftMargin + commandHelp.length)}`;
|
|
288
330
|
}));
|
|
289
331
|
return messages;
|
|
290
332
|
}
|
|
333
|
+
async function makeCommandSymbol(ctx, cmd) {
|
|
334
|
+
const optionSymbol = await generateOptionsSymbols(ctx, ctx.args);
|
|
335
|
+
const positionalSymbol = generatePositionalSymbols(ctx.args);
|
|
336
|
+
let commandStr = cmd.entry ? cmd.name === void 0 || cmd.name === ANONYMOUS_COMMAND_NAME ? "" : `[${cmd.name}]` : cmd.name || "";
|
|
337
|
+
if (optionSymbol) {
|
|
338
|
+
if (commandStr) commandStr += " ";
|
|
339
|
+
commandStr += `${optionSymbol}`;
|
|
340
|
+
}
|
|
341
|
+
if (positionalSymbol) {
|
|
342
|
+
if (commandStr) commandStr += " ";
|
|
343
|
+
commandStr += `${positionalSymbol}`;
|
|
344
|
+
}
|
|
345
|
+
return commandStr;
|
|
346
|
+
}
|
|
291
347
|
/**
|
|
292
348
|
* Resolve the entry command name
|
|
293
349
|
* @param ctx A {@link CommandContext | command context}
|
|
@@ -310,7 +366,7 @@ async function resolveSubCommand(ctx) {
|
|
|
310
366
|
* @returns resolved command description
|
|
311
367
|
*/
|
|
312
368
|
async function resolveDescription(ctx) {
|
|
313
|
-
return await ctx.extensions[pluginId].text("description") || ctx.description || "";
|
|
369
|
+
return await ctx.extensions[pluginId].text(resolveKey("description", ctx)) || ctx.description || "";
|
|
314
370
|
}
|
|
315
371
|
/**
|
|
316
372
|
* Resolve the command examples
|
|
@@ -318,7 +374,7 @@ async function resolveDescription(ctx) {
|
|
|
318
374
|
* @returns resolved command examples, if not resolved, return empty string
|
|
319
375
|
*/
|
|
320
376
|
async function resolveExamples(ctx) {
|
|
321
|
-
const ret = await ctx.extensions[pluginId].text("examples");
|
|
377
|
+
const ret = await ctx.extensions[pluginId].text(resolveKey("examples", ctx));
|
|
322
378
|
if (ret) return ret;
|
|
323
379
|
const command = ctx.env.subCommands?.get(ctx.name || "");
|
|
324
380
|
return await resolveExamples$1(ctx, command?.examples);
|
|
@@ -334,35 +390,35 @@ async function hasCommands(ctx) {
|
|
|
334
390
|
}
|
|
335
391
|
/**
|
|
336
392
|
* Check if the command has optional arguments
|
|
337
|
-
* @param
|
|
393
|
+
* @param args A {@link Args | command optional arguments}
|
|
338
394
|
* @returns True if the command has options
|
|
339
395
|
*/
|
|
340
|
-
function hasOptionalArgs(
|
|
341
|
-
return
|
|
396
|
+
function hasOptionalArgs(args) {
|
|
397
|
+
return Object.values(args).some((arg) => arg.type !== "positional");
|
|
342
398
|
}
|
|
343
399
|
/**
|
|
344
400
|
* Check if the command has positional arguments
|
|
345
|
-
* @param
|
|
401
|
+
* @param args A {@link Args | command positional arguments}
|
|
346
402
|
* @returns True if the command has options
|
|
347
403
|
*/
|
|
348
|
-
function hasPositionalArgs(
|
|
349
|
-
return
|
|
404
|
+
function hasPositionalArgs(args) {
|
|
405
|
+
return Object.values(args).some((arg) => arg.type === "positional");
|
|
350
406
|
}
|
|
351
407
|
/**
|
|
352
408
|
* Check if all options have default values
|
|
353
|
-
* @param
|
|
409
|
+
* @param args An {@link Args | command argument}
|
|
354
410
|
* @returns True if all options have default values
|
|
355
411
|
*/
|
|
356
|
-
function hasAllDefaultOptions(
|
|
357
|
-
return !!(
|
|
412
|
+
function hasAllDefaultOptions(args) {
|
|
413
|
+
return !!(args && Object.values(args).every((arg) => arg.default));
|
|
358
414
|
}
|
|
359
415
|
/**
|
|
360
416
|
* Generate options symbols for usage
|
|
361
417
|
* @param ctx A {@link CommandContext | command context}
|
|
362
418
|
* @returns Options symbols for usage
|
|
363
419
|
*/
|
|
364
|
-
async function generateOptionsSymbols(ctx) {
|
|
365
|
-
return hasOptionalArgs(
|
|
420
|
+
async function generateOptionsSymbols(ctx, args) {
|
|
421
|
+
return hasOptionalArgs(args) ? hasAllDefaultOptions(args) ? `[${await ctx.extensions[pluginId].text(resolveBuiltInKey("OPTIONS"))}]` : `<${await ctx.extensions[pluginId].text(resolveBuiltInKey("OPTIONS"))}>` : "";
|
|
366
422
|
}
|
|
367
423
|
/**
|
|
368
424
|
* Get optional arguments pairs for usage
|
|
@@ -413,7 +469,7 @@ async function generateOptionalArgsUsage(ctx, optionsPairs) {
|
|
|
413
469
|
const optionsMaxLength = Math.max(...Object.entries(optionsPairs).map(([_, value]) => value.length));
|
|
414
470
|
const optionSchemaMaxLength = ctx.env.usageOptionType ? Math.max(...Object.entries(optionsPairs).map(([key]) => resolveNegatableType(key, ctx).length)) : 0;
|
|
415
471
|
const usages = await Promise.all(Object.entries(optionsPairs).map(async ([key, value]) => {
|
|
416
|
-
let rawDesc = await ctx.extensions[pluginId].text(resolveArgKey(key));
|
|
472
|
+
let rawDesc = await ctx.extensions[pluginId].text(resolveArgKey(key, ctx));
|
|
417
473
|
if (!rawDesc && key.startsWith(ARG_NEGATABLE_PREFIX)) {
|
|
418
474
|
const name = resolveNegatableKey(key);
|
|
419
475
|
const schema = ctx.args[name];
|
|
@@ -423,26 +479,27 @@ async function generateOptionalArgsUsage(ctx, optionsPairs) {
|
|
|
423
479
|
const optionsSchema = ctx.env.usageOptionType ? `[${resolveNegatableType(key, ctx)}] ` : "";
|
|
424
480
|
const valueDesc = key.startsWith(ARG_NEGATABLE_PREFIX) ? "" : await resolveDisplayValue(ctx, key);
|
|
425
481
|
const desc = `${optionsSchema ? optionsSchema.padEnd(optionSchemaMaxLength + 3) : ""}${rawDesc}`;
|
|
426
|
-
const
|
|
482
|
+
const descLength = desc.length + valueDesc.length;
|
|
483
|
+
const option = `${value.padEnd((descLength > 0 ? optionsMaxLength : 0) + ctx.env.middleMargin)}${desc}${valueDesc ? ` ${valueDesc}` : ""}`;
|
|
427
484
|
return `${option.padStart(ctx.env.leftMargin + option.length)}`;
|
|
428
485
|
}));
|
|
429
486
|
return usages.join("\n");
|
|
430
487
|
}
|
|
431
|
-
function getPositionalArgs(
|
|
432
|
-
return Object.entries(
|
|
488
|
+
function getPositionalArgs(args) {
|
|
489
|
+
return Object.entries(args).filter(([_, schema]) => schema.type === "positional");
|
|
433
490
|
}
|
|
434
491
|
async function generatePositionalArgsUsage(ctx) {
|
|
435
|
-
const positionals = getPositionalArgs(ctx);
|
|
492
|
+
const positionals = getPositionalArgs(ctx.args);
|
|
436
493
|
const argsMaxLength = Math.max(...positionals.map(([name]) => name.length));
|
|
437
494
|
const usages = await Promise.all(positionals.map(async ([name]) => {
|
|
438
|
-
const desc = await ctx.extensions[pluginId].text(resolveArgKey(name)) || ctx.args[name].description || "";
|
|
495
|
+
const desc = await ctx.extensions[pluginId].text(resolveArgKey(name, ctx)) || ctx.args[name].description || "";
|
|
439
496
|
const arg = `${name.padEnd(argsMaxLength + ctx.env.middleMargin)} ${desc}`;
|
|
440
497
|
return `${arg.padStart(ctx.env.leftMargin + arg.length)}`;
|
|
441
498
|
}));
|
|
442
499
|
return usages.join("\n");
|
|
443
500
|
}
|
|
444
|
-
function generatePositionalSymbols(
|
|
445
|
-
return hasPositionalArgs(
|
|
501
|
+
function generatePositionalSymbols(args) {
|
|
502
|
+
return hasPositionalArgs(args) ? getPositionalArgs(args).map(([name]) => `<${name}>`).join(" ") : "";
|
|
446
503
|
}
|
|
447
504
|
|
|
448
505
|
//#endregion
|
|
@@ -480,7 +537,16 @@ function renderer() {
|
|
|
480
537
|
if (cachedCommands) return cachedCommands;
|
|
481
538
|
const subCommands = [...ctx.env.subCommands || []];
|
|
482
539
|
const allCommands = await Promise.all(subCommands.map(async ([name, cmd$1]) => await resolveLazyCommand(cmd$1, name)));
|
|
483
|
-
|
|
540
|
+
cachedCommands = allCommands.filter((cmd$1) => !cmd$1.internal).filter(Boolean);
|
|
541
|
+
cachedCommands.sort((a, b) => {
|
|
542
|
+
if (a.entry && !b.entry) return -1;
|
|
543
|
+
if (!a.entry && b.entry) return 1;
|
|
544
|
+
if (a.name && b.name) return a.name.localeCompare(b.name);
|
|
545
|
+
if (a.name && !b.name) return -1;
|
|
546
|
+
if (!a.name && b.name) return 1;
|
|
547
|
+
return 0;
|
|
548
|
+
});
|
|
549
|
+
return cachedCommands;
|
|
484
550
|
}
|
|
485
551
|
return {
|
|
486
552
|
text: localizable(ctx, cmd, i18n?.translate),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gunshi/plugin-renderer",
|
|
3
3
|
"description": "usage renderer plugin for gunshi",
|
|
4
|
-
"version": "0.27.0-alpha.
|
|
4
|
+
"version": "0.27.0-alpha.9",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "kazuya kawaguchi",
|
|
7
7
|
"email": "kawakazu80@gmail.com"
|
|
@@ -53,20 +53,20 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@gunshi/plugin": "0.27.0-alpha.
|
|
56
|
+
"@gunshi/plugin": "0.27.0-alpha.9"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@gunshi/plugin-i18n": "0.27.0-alpha.
|
|
59
|
+
"@gunshi/plugin-i18n": "0.27.0-alpha.9"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"deno": "^2.4.
|
|
62
|
+
"deno": "^2.4.2",
|
|
63
63
|
"jsr": "^0.13.5",
|
|
64
64
|
"jsr-exports-lint": "^0.4.1",
|
|
65
65
|
"publint": "^0.3.12",
|
|
66
|
-
"tsdown": "^0.
|
|
66
|
+
"tsdown": "^0.13.0",
|
|
67
67
|
"typedoc": "^0.28.7",
|
|
68
|
-
"typedoc-plugin-markdown": "^4.7.
|
|
69
|
-
"@gunshi/shared": "0.27.0-alpha.
|
|
68
|
+
"typedoc-plugin-markdown": "^4.7.1",
|
|
69
|
+
"@gunshi/shared": "0.27.0-alpha.9"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsdown",
|