grimoire-wizard 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -1461
- package/dist/cli.js +33 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +33 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ interface SelectOption {
|
|
|
58
58
|
label: string;
|
|
59
59
|
hint?: string;
|
|
60
60
|
disabled?: boolean | string;
|
|
61
|
+
checked?: boolean;
|
|
61
62
|
}
|
|
62
63
|
interface SeparatorOption {
|
|
63
64
|
separator: string;
|
|
@@ -189,6 +190,7 @@ interface WizardConfig {
|
|
|
189
190
|
version?: string;
|
|
190
191
|
description?: string;
|
|
191
192
|
review?: boolean;
|
|
193
|
+
icon?: string;
|
|
192
194
|
};
|
|
193
195
|
theme?: ThemeConfig;
|
|
194
196
|
steps: StepConfig[];
|
|
@@ -440,6 +442,7 @@ interface RunWizardOptions {
|
|
|
440
442
|
mru?: boolean;
|
|
441
443
|
resume?: boolean;
|
|
442
444
|
configFilePath?: string;
|
|
445
|
+
optionsProvider?: (stepId: string, answers: Record<string, unknown>) => Promise<SelectOption[] | undefined>;
|
|
443
446
|
}
|
|
444
447
|
declare function runPreFlightChecks(checks: PreFlightCheck[], theme: ResolvedTheme, renderer?: WizardRenderer): void;
|
|
445
448
|
declare function runWizard(config: WizardConfig, options?: RunWizardOptions): Promise<Record<string, unknown>>;
|
|
@@ -482,6 +485,7 @@ declare function resolveTemplateStrict(template: string, answers: Record<string,
|
|
|
482
485
|
*/
|
|
483
486
|
declare function renderBanner(name: string, theme: ResolvedTheme, options?: {
|
|
484
487
|
plain?: boolean;
|
|
488
|
+
icon?: string;
|
|
485
489
|
}): string;
|
|
486
490
|
|
|
487
491
|
declare function slugify(name: string): string;
|
package/dist/index.js
CHANGED
|
@@ -242,7 +242,8 @@ var init_schema = __esm({
|
|
|
242
242
|
name: z.string(),
|
|
243
243
|
version: z.string().optional(),
|
|
244
244
|
description: z.string().optional(),
|
|
245
|
-
review: z.boolean().optional()
|
|
245
|
+
review: z.boolean().optional(),
|
|
246
|
+
icon: z.string().optional()
|
|
246
247
|
}),
|
|
247
248
|
theme: themeConfigSchema.optional(),
|
|
248
249
|
steps: z.array(stepConfigSchema).min(1),
|
|
@@ -1188,18 +1189,26 @@ import figlet from "figlet";
|
|
|
1188
1189
|
import gradient from "gradient-string";
|
|
1189
1190
|
var GRIMOIRE_GRADIENT = gradient(["#C084FC", "#5B9BD5", "#6BCB77"]);
|
|
1190
1191
|
function renderBanner(name, theme, options) {
|
|
1192
|
+
const icon = options?.icon;
|
|
1193
|
+
const prefix = icon ? `${icon} ` : "";
|
|
1191
1194
|
if (options?.plain) {
|
|
1192
|
-
return ` ${theme.bold(name)}`;
|
|
1195
|
+
return ` ${prefix}${theme.bold(name)}`;
|
|
1193
1196
|
}
|
|
1194
1197
|
try {
|
|
1195
1198
|
const art = figlet.textSync(name, {
|
|
1196
1199
|
font: "Small",
|
|
1197
1200
|
horizontalLayout: "default"
|
|
1198
1201
|
});
|
|
1199
|
-
const
|
|
1202
|
+
const artLines = art.split("\n");
|
|
1203
|
+
const lines = artLines.map((line, i) => {
|
|
1204
|
+
if (icon && i === Math.floor(artLines.length / 2)) {
|
|
1205
|
+
return ` ${icon} ${line}`;
|
|
1206
|
+
}
|
|
1207
|
+
return icon ? ` ${line}` : ` ${line}`;
|
|
1208
|
+
}).join("\n");
|
|
1200
1209
|
return GRIMOIRE_GRADIENT(lines);
|
|
1201
1210
|
} catch {
|
|
1202
|
-
return ` ${theme.bold(name)}`;
|
|
1211
|
+
return ` ${prefix}${theme.bold(name)}`;
|
|
1203
1212
|
}
|
|
1204
1213
|
}
|
|
1205
1214
|
|
|
@@ -1441,11 +1450,14 @@ function emitEvent(renderer, event, theme) {
|
|
|
1441
1450
|
function runPreFlightChecks(checks, theme, renderer) {
|
|
1442
1451
|
if (renderer) emitEvent(renderer, { type: "checks:start", checks }, theme);
|
|
1443
1452
|
for (const check of checks) {
|
|
1453
|
+
if (renderer) emitEvent(renderer, { type: "spinner:start", message: check.name }, theme);
|
|
1444
1454
|
try {
|
|
1445
1455
|
execSync(check.run, { stdio: "pipe" });
|
|
1456
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop", message: `${check.name}` }, theme);
|
|
1446
1457
|
console.log(` ${theme.success("\u2713")} ${check.name}`);
|
|
1447
1458
|
if (renderer) emitEvent(renderer, { type: "check:pass", name: check.name }, theme);
|
|
1448
1459
|
} catch {
|
|
1460
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop" }, theme);
|
|
1449
1461
|
console.log(` ${theme.error("\u2717")} ${check.name}: ${check.message}`);
|
|
1450
1462
|
if (renderer) emitEvent(renderer, { type: "check:fail", name: check.name, message: check.message }, theme);
|
|
1451
1463
|
throw new Error(`Pre-flight check failed: ${check.name} \u2014 ${check.message}`);
|
|
@@ -1565,8 +1577,17 @@ async function runWizard(config, options) {
|
|
|
1565
1577
|
const withTemplate = options?.templateAnswers ? applyTemplateDefaults(resolvedStep, options.templateAnswers) : resolvedStep;
|
|
1566
1578
|
const templatedStep = resolveStepTemplates(withTemplate, state.answers);
|
|
1567
1579
|
const mruStep = mruEnabled ? applyMruOrdering(templatedStep, config.meta.name) : templatedStep;
|
|
1580
|
+
let finalStep = mruStep;
|
|
1581
|
+
if (!isMock && options?.optionsProvider && isSelectLikeStep(currentStep.type)) {
|
|
1582
|
+
if (renderer) emitEvent(renderer, { type: "spinner:start", message: resolvedMessage }, theme);
|
|
1583
|
+
const dynamicOptions = await options.optionsProvider(currentStep.id, state.answers);
|
|
1584
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop", message: resolvedMessage }, theme);
|
|
1585
|
+
if (dynamicOptions) {
|
|
1586
|
+
finalStep = { ...mruStep, options: dynamicOptions };
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1568
1589
|
try {
|
|
1569
|
-
const value = isMock ? getMockValue(
|
|
1590
|
+
const value = isMock ? getMockValue(finalStep, mockAnswers) : pluginStep ? await pluginStep.render(toStepRecord(finalStep), state, theme) : await renderStep(renderer, finalStep, state, theme);
|
|
1570
1591
|
if (pluginStep?.validate) {
|
|
1571
1592
|
const pluginError = pluginStep.validate(value, toStepRecord(templatedStep));
|
|
1572
1593
|
if (pluginError) {
|
|
@@ -1905,6 +1926,7 @@ function resolveStepTemplates(step, answers) {
|
|
|
1905
1926
|
}
|
|
1906
1927
|
async function executeOnComplete(handlerPath, configFilePath, answers, config, theme, renderer) {
|
|
1907
1928
|
if (renderer) emitEvent(renderer, { type: "oncomplete:start" }, theme);
|
|
1929
|
+
if (renderer) emitEvent(renderer, { type: "spinner:start", message: `Running onComplete handler...` }, theme);
|
|
1908
1930
|
const resolvedPath = configFilePath ? resolve2(dirname2(configFilePath), handlerPath) : resolve2(handlerPath);
|
|
1909
1931
|
try {
|
|
1910
1932
|
const mod = await import(pathToFileURL(resolvedPath).href);
|
|
@@ -1912,9 +1934,11 @@ async function executeOnComplete(handlerPath, configFilePath, answers, config, t
|
|
|
1912
1934
|
throw new Error(`onComplete handler "${handlerPath}" must export a default function`);
|
|
1913
1935
|
}
|
|
1914
1936
|
await mod.default({ answers, config });
|
|
1937
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop", message: "Handler complete" }, theme);
|
|
1915
1938
|
if (renderer) emitEvent(renderer, { type: "oncomplete:pass" }, theme);
|
|
1916
1939
|
} catch (error) {
|
|
1917
1940
|
const message = error instanceof Error ? error.message : String(error);
|
|
1941
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop" }, theme);
|
|
1918
1942
|
if (renderer) emitEvent(renderer, { type: "oncomplete:fail", error: message }, theme);
|
|
1919
1943
|
console.log(`
|
|
1920
1944
|
${theme.error("\u2717")} onComplete handler failed: ${message}
|
|
@@ -1934,11 +1958,14 @@ async function executeActions(actions, answers, theme, renderer) {
|
|
|
1934
1958
|
const resolvedCommand = resolveTemplateStrict(action.run, answers);
|
|
1935
1959
|
const resolvedName = action.name ? resolveTemplateStrict(action.name, answers) : void 0;
|
|
1936
1960
|
const label = resolvedName ?? resolvedCommand;
|
|
1961
|
+
if (renderer) emitEvent(renderer, { type: "spinner:start", message: label }, theme);
|
|
1937
1962
|
try {
|
|
1938
1963
|
execSync(resolvedCommand, { stdio: "pipe" });
|
|
1964
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop", message: label }, theme);
|
|
1939
1965
|
console.log(` ${theme.success("\u2713")} ${label}`);
|
|
1940
1966
|
if (renderer) emitEvent(renderer, { type: "action:pass", name: label }, theme);
|
|
1941
1967
|
} catch {
|
|
1968
|
+
if (renderer) emitEvent(renderer, { type: "spinner:stop" }, theme);
|
|
1942
1969
|
console.log(` ${theme.error("\u2717")} ${label}`);
|
|
1943
1970
|
if (renderer) emitEvent(renderer, { type: "action:fail", name: label }, theme);
|
|
1944
1971
|
throw new Error(`Action failed: ${label}`);
|
|
@@ -1948,7 +1975,7 @@ async function executeActions(actions, answers, theme, renderer) {
|
|
|
1948
1975
|
}
|
|
1949
1976
|
function printWizardHeader(config, theme, plain) {
|
|
1950
1977
|
console.log();
|
|
1951
|
-
console.log(renderBanner(config.meta.name, theme, { plain }));
|
|
1978
|
+
console.log(renderBanner(config.meta.name, theme, { plain, icon: config.meta.icon }));
|
|
1952
1979
|
if (config.meta.description) {
|
|
1953
1980
|
console.log(` ${theme.muted(config.meta.description)}`);
|
|
1954
1981
|
}
|