create-zenith 1.3.19 → 1.3.20
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 +7 -0
- package/dist/cli.js +178 -18
- package/dist/index.js +178 -18
- package/package.json +4 -4
- package/templates/basic/LICENSE +21 -0
- package/templates/basic/README.md +11 -0
- package/templates/basic/package.json +18 -0
- package/templates/basic/src/layouts/DefaultLayout.zen +20 -0
- package/templates/basic/src/pages/index.zen +24 -0
- package/templates/basic/src/public/logo.svg +601 -0
- package/templates/basic/src/styles/global.css +61 -0
- package/templates/basic/tsconfig.json +30 -0
- package/templates/basic/zenith.config.js +5 -0
- package/templates/css/LICENSE +21 -0
- package/templates/css/README.md +11 -0
- package/templates/css/package.json +18 -0
- package/templates/css/src/layouts/DefaultLayout.zen +26 -0
- package/templates/css/src/pages/about.zen +19 -0
- package/templates/css/src/pages/blog.zen +19 -0
- package/templates/css/src/pages/docs.zen +19 -0
- package/templates/css/src/pages/index.zen +26 -0
- package/templates/css/src/public/logo.svg +601 -0
- package/templates/css/src/styles/global.css +66 -0
- package/templates/css/tsconfig.json +30 -0
- package/templates/css/zenith.config.js +4 -0
- package/templates/features/eslint/eslint.config.js +30 -0
- package/templates/features/prettier/.prettierignore +3 -0
- package/templates/features/prettier/.prettierrc +7 -0
- package/templates/tailwind/LICENSE +21 -0
- package/templates/tailwind/README.md +11 -0
- package/templates/tailwind/package.json +20 -0
- package/templates/tailwind/src/layouts/DefaultLayout.zen +28 -0
- package/templates/tailwind/src/pages/about.zen +20 -0
- package/templates/tailwind/src/pages/blog.zen +19 -0
- package/templates/tailwind/src/pages/docs.zen +19 -0
- package/templates/tailwind/src/pages/index.zen +31 -0
- package/templates/tailwind/src/public/logo.svg +601 -0
- package/templates/tailwind/src/styles/globals.css +3 -0
- package/templates/tailwind/tsconfig.json +30 -0
- package/templates/tailwind/zenith.config.js +4 -0
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ The official CLI for scaffolding new Zenith applications. Fast, animated, and de
|
|
|
17
17
|
- **Interactive UX**: Built with `@clack/prompts` for intuitive arrow-key navigation and clear visual indicators.
|
|
18
18
|
- **Reliable Fallbacks**: Automatically detects CI environments and non-TTY pipes to provide clean, static output.
|
|
19
19
|
- **Smart Detection**: automatically detects your preferred package manager (Bun, pnpm, Yarn, or npm).
|
|
20
|
+
- **Template Authority**: Scaffold generation now reads only from `templates/` (`basic`, `css`, `tailwind`), which is the single source of truth for starter projects.
|
|
20
21
|
- **Tool-Agnostic Output**: ESLint, Prettier, and TypeScript path aliases are opt-in. If you answer `No`, the generated project contains no scripts, dependencies, config files, or ignore files for that tool.
|
|
21
22
|
|
|
22
23
|
## Quick Start
|
|
@@ -65,9 +66,15 @@ If you see version mismatches after install, delete `node_modules` and `package-
|
|
|
65
66
|
|
|
66
67
|
- Generated apps now depend on `@zenithbuild/core@latest` so new installs track the current stable framework release.
|
|
67
68
|
- Template downloads now resolve from `zenithbuild/framework`, which is the active monorepo source of truth.
|
|
69
|
+
- Starter templates now live under `templates/`, and the scaffolder no longer depends on `examples/`.
|
|
68
70
|
- ESLint and Prettier are now feature overlays, so opting out leaves no stray config or dependency references in the scaffolded app.
|
|
69
71
|
- Verified scaffold → install → build coverage lives in `tests/template-regression.spec.mjs`.
|
|
70
72
|
|
|
73
|
+
## Templates vs Examples
|
|
74
|
+
|
|
75
|
+
- `templates/` is authoritative for scaffolding.
|
|
76
|
+
- `examples/` is demo-only when present and is not part of the scaffold source of truth.
|
|
77
|
+
|
|
71
78
|
## Development
|
|
72
79
|
|
|
73
80
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -2553,6 +2553,33 @@ class dD extends x {
|
|
|
2553
2553
|
}
|
|
2554
2554
|
var A;
|
|
2555
2555
|
A = new WeakMap;
|
|
2556
|
+
var OD = Object.defineProperty;
|
|
2557
|
+
var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
2558
|
+
var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
2559
|
+
|
|
2560
|
+
class LD extends x {
|
|
2561
|
+
constructor(u) {
|
|
2562
|
+
super(u, false), J(this, "options"), J(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: t }) => t === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (t) => {
|
|
2563
|
+
switch (t) {
|
|
2564
|
+
case "left":
|
|
2565
|
+
case "up":
|
|
2566
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
2567
|
+
break;
|
|
2568
|
+
case "down":
|
|
2569
|
+
case "right":
|
|
2570
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
2571
|
+
break;
|
|
2572
|
+
}
|
|
2573
|
+
this.changeValue();
|
|
2574
|
+
});
|
|
2575
|
+
}
|
|
2576
|
+
get _value() {
|
|
2577
|
+
return this.options[this.cursor];
|
|
2578
|
+
}
|
|
2579
|
+
changeValue() {
|
|
2580
|
+
this.value = this._value.value;
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2556
2583
|
class RD extends x {
|
|
2557
2584
|
get valueWithCursor() {
|
|
2558
2585
|
if (this.state === "submit")
|
|
@@ -2615,6 +2642,16 @@ var b2 = (t) => {
|
|
|
2615
2642
|
return import_picocolors3.default.green(C);
|
|
2616
2643
|
}
|
|
2617
2644
|
};
|
|
2645
|
+
var G2 = (t) => {
|
|
2646
|
+
const { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
|
|
2647
|
+
let l2 = 0;
|
|
2648
|
+
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
2649
|
+
const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
2650
|
+
return r2.slice(l2, l2 + a).map((p2, v2, f) => {
|
|
2651
|
+
const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
|
|
2652
|
+
return j2 || E ? import_picocolors3.default.dim("...") : i(p2, v2 + l2 === n);
|
|
2653
|
+
});
|
|
2654
|
+
};
|
|
2618
2655
|
var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
2619
2656
|
const n = `${import_picocolors3.default.gray(o)}
|
|
2620
2657
|
${b2(this.state)} ${t.message}
|
|
@@ -2655,6 +2692,38 @@ ${import_picocolors3.default.cyan(d2)}
|
|
|
2655
2692
|
}
|
|
2656
2693
|
} }).prompt();
|
|
2657
2694
|
};
|
|
2695
|
+
var ve = (t) => {
|
|
2696
|
+
const n = (r2, i) => {
|
|
2697
|
+
const s = r2.label ?? String(r2.value);
|
|
2698
|
+
switch (i) {
|
|
2699
|
+
case "selected":
|
|
2700
|
+
return `${import_picocolors3.default.dim(s)}`;
|
|
2701
|
+
case "active":
|
|
2702
|
+
return `${import_picocolors3.default.green(k2)} ${s} ${r2.hint ? import_picocolors3.default.dim(`(${r2.hint})`) : ""}`;
|
|
2703
|
+
case "cancelled":
|
|
2704
|
+
return `${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}`;
|
|
2705
|
+
default:
|
|
2706
|
+
return `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(s)}`;
|
|
2707
|
+
}
|
|
2708
|
+
};
|
|
2709
|
+
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
2710
|
+
const r2 = `${import_picocolors3.default.gray(o)}
|
|
2711
|
+
${b2(this.state)} ${t.message}
|
|
2712
|
+
`;
|
|
2713
|
+
switch (this.state) {
|
|
2714
|
+
case "submit":
|
|
2715
|
+
return `${r2}${import_picocolors3.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
2716
|
+
case "cancel":
|
|
2717
|
+
return `${r2}${import_picocolors3.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
2718
|
+
${import_picocolors3.default.gray(o)}`;
|
|
2719
|
+
default:
|
|
2720
|
+
return `${r2}${import_picocolors3.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
|
|
2721
|
+
${import_picocolors3.default.cyan(o)} `)}
|
|
2722
|
+
${import_picocolors3.default.cyan(d2)}
|
|
2723
|
+
`;
|
|
2724
|
+
}
|
|
2725
|
+
} }).prompt();
|
|
2726
|
+
};
|
|
2658
2727
|
var xe = (t = "") => {
|
|
2659
2728
|
process.stdout.write(`${import_picocolors3.default.gray(d2)} ${import_picocolors3.default.red(t)}
|
|
2660
2729
|
|
|
@@ -2687,7 +2756,7 @@ var M2 = { message: (t = "", { symbol: n = import_picocolors3.default.gray(o) }
|
|
|
2687
2756
|
}, error: (t) => {
|
|
2688
2757
|
M2.message(t, { symbol: import_picocolors3.default.red(K2) });
|
|
2689
2758
|
} };
|
|
2690
|
-
var
|
|
2759
|
+
var J2 = `${import_picocolors3.default.gray(o)} `;
|
|
2691
2760
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
2692
2761
|
const n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
|
|
2693
2762
|
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
@@ -2777,6 +2846,12 @@ async function confirm(opts) {
|
|
|
2777
2846
|
initialValue: opts.initialValue ?? true
|
|
2778
2847
|
});
|
|
2779
2848
|
}
|
|
2849
|
+
async function select(opts) {
|
|
2850
|
+
if (!isTTY()) {
|
|
2851
|
+
return opts.initialValue || opts.options[0]?.value;
|
|
2852
|
+
}
|
|
2853
|
+
return await ve(opts);
|
|
2854
|
+
}
|
|
2780
2855
|
function isCancel(value) {
|
|
2781
2856
|
return pD(value);
|
|
2782
2857
|
}
|
|
@@ -2885,10 +2960,58 @@ function applyPackageFeatures(manifest, options) {
|
|
|
2885
2960
|
return nextManifest;
|
|
2886
2961
|
}
|
|
2887
2962
|
|
|
2963
|
+
// src/templates.ts
|
|
2964
|
+
var DEFAULT_TEMPLATE = "css";
|
|
2965
|
+
var TEMPLATE_DEFINITIONS = {
|
|
2966
|
+
basic: {
|
|
2967
|
+
name: "basic",
|
|
2968
|
+
label: "Basic",
|
|
2969
|
+
hint: "Blank starter with a single page and minimal CSS",
|
|
2970
|
+
templatePath: "templates/basic",
|
|
2971
|
+
usesTailwind: false
|
|
2972
|
+
},
|
|
2973
|
+
css: {
|
|
2974
|
+
name: "css",
|
|
2975
|
+
label: "CSS",
|
|
2976
|
+
hint: "Multi-page starter with a small curated CSS setup",
|
|
2977
|
+
templatePath: "templates/css",
|
|
2978
|
+
usesTailwind: false
|
|
2979
|
+
},
|
|
2980
|
+
tailwind: {
|
|
2981
|
+
name: "tailwind",
|
|
2982
|
+
label: "Tailwind",
|
|
2983
|
+
hint: "Multi-page starter with Tailwind enabled",
|
|
2984
|
+
templatePath: "templates/tailwind",
|
|
2985
|
+
usesTailwind: true
|
|
2986
|
+
}
|
|
2987
|
+
};
|
|
2988
|
+
var TEMPLATE_ALIASES = {
|
|
2989
|
+
starter: "css",
|
|
2990
|
+
"starter-tailwindcss": "tailwind"
|
|
2991
|
+
};
|
|
2992
|
+
function resolveTemplateName(value) {
|
|
2993
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
2994
|
+
if (!normalized) {
|
|
2995
|
+
return null;
|
|
2996
|
+
}
|
|
2997
|
+
if (normalized in TEMPLATE_DEFINITIONS) {
|
|
2998
|
+
return normalized;
|
|
2999
|
+
}
|
|
3000
|
+
return TEMPLATE_ALIASES[normalized] || null;
|
|
3001
|
+
}
|
|
3002
|
+
function getTemplateDefinition(templateName) {
|
|
3003
|
+
return TEMPLATE_DEFINITIONS[templateName];
|
|
3004
|
+
}
|
|
3005
|
+
function templateSelectOptions() {
|
|
3006
|
+
return Object.values(TEMPLATE_DEFINITIONS).map((definition) => ({
|
|
3007
|
+
value: definition.name,
|
|
3008
|
+
label: definition.label,
|
|
3009
|
+
hint: definition.hint
|
|
3010
|
+
}));
|
|
3011
|
+
}
|
|
3012
|
+
|
|
2888
3013
|
// src/index.ts
|
|
2889
3014
|
var GITHUB_REPO = "zenithbuild/framework";
|
|
2890
|
-
var DEFAULT_TEMPLATE = "examples/starter";
|
|
2891
|
-
var TAILWIND_TEMPLATE = "examples/starter-tailwindcss";
|
|
2892
3015
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
2893
3016
|
var __dirname2 = path.dirname(__filename2);
|
|
2894
3017
|
function getCliVersion() {
|
|
@@ -3011,10 +3134,23 @@ function readOptionOverride(name) {
|
|
|
3011
3134
|
}
|
|
3012
3135
|
return flagEnabled2(value);
|
|
3013
3136
|
}
|
|
3014
|
-
|
|
3137
|
+
function readTemplateOverride(name) {
|
|
3138
|
+
const value = process.env[name];
|
|
3139
|
+
if (value == null || value.trim() === "") {
|
|
3140
|
+
return;
|
|
3141
|
+
}
|
|
3142
|
+
const templateName = resolveTemplateName(value);
|
|
3143
|
+
if (!templateName) {
|
|
3144
|
+
throw new Error(`Unsupported template "${value}". Use basic, css, or tailwind.`);
|
|
3145
|
+
}
|
|
3146
|
+
return templateName;
|
|
3147
|
+
}
|
|
3148
|
+
async function gatherOptions(providedName, requestedTemplate) {
|
|
3015
3149
|
const eslintOverride = readOptionOverride("CREATE_ZENITH_ESLINT");
|
|
3016
3150
|
const prettierOverride = readOptionOverride("CREATE_ZENITH_PRETTIER");
|
|
3017
3151
|
const pathAliasOverride = readOptionOverride("CREATE_ZENITH_PATH_ALIAS");
|
|
3152
|
+
const templateOverride = readTemplateOverride("CREATE_ZENITH_TEMPLATE");
|
|
3153
|
+
const selectedTemplate = requestedTemplate || templateOverride || DEFAULT_TEMPLATE;
|
|
3018
3154
|
let name = providedName;
|
|
3019
3155
|
if (!name) {
|
|
3020
3156
|
const nameResult = await text({
|
|
@@ -3055,15 +3191,17 @@ async function gatherOptions(providedName, withTailwind) {
|
|
|
3055
3191
|
eslint: eslintOverride ?? true,
|
|
3056
3192
|
prettier: prettierOverride ?? true,
|
|
3057
3193
|
pathAlias: pathAliasOverride ?? true,
|
|
3058
|
-
|
|
3194
|
+
template: selectedTemplate
|
|
3059
3195
|
};
|
|
3060
3196
|
}
|
|
3061
|
-
const
|
|
3062
|
-
message: "
|
|
3063
|
-
|
|
3197
|
+
const templateResult = requestedTemplate ?? templateOverride ?? await select({
|
|
3198
|
+
message: "Choose a starter template",
|
|
3199
|
+
options: templateSelectOptions(),
|
|
3200
|
+
initialValue: DEFAULT_TEMPLATE
|
|
3064
3201
|
});
|
|
3065
|
-
if (isCancel(
|
|
3202
|
+
if (requestedTemplate === undefined && templateOverride === undefined && isCancel(templateResult)) {
|
|
3066
3203
|
handleCancel();
|
|
3204
|
+
}
|
|
3067
3205
|
const eslintResult = eslintOverride ?? await confirm({
|
|
3068
3206
|
message: "Add ESLint for code linting?",
|
|
3069
3207
|
initialValue: true
|
|
@@ -3087,12 +3225,12 @@ async function gatherOptions(providedName, withTailwind) {
|
|
|
3087
3225
|
eslint: eslintResult,
|
|
3088
3226
|
prettier: prettierResult,
|
|
3089
3227
|
pathAlias: pathAliasResult,
|
|
3090
|
-
|
|
3228
|
+
template: templateResult
|
|
3091
3229
|
};
|
|
3092
3230
|
}
|
|
3093
3231
|
async function createProject(options) {
|
|
3094
3232
|
const targetDir = path.resolve(process.cwd(), options.name);
|
|
3095
|
-
const templatePath = options.
|
|
3233
|
+
const templatePath = getTemplateDefinition(options.template).templatePath;
|
|
3096
3234
|
const templateFeaturePaths = selectedTemplateFeaturePaths(options);
|
|
3097
3235
|
await downloadTemplate(targetDir, [templatePath, ...templateFeaturePaths]);
|
|
3098
3236
|
const pkgPath = path.join(targetDir, "package.json");
|
|
@@ -3117,10 +3255,10 @@ async function createProject(options) {
|
|
|
3117
3255
|
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 4));
|
|
3118
3256
|
}
|
|
3119
3257
|
}
|
|
3120
|
-
async function create(appName,
|
|
3258
|
+
async function create(appName, requestedTemplate) {
|
|
3121
3259
|
await intro();
|
|
3122
|
-
const options = await gatherOptions(appName,
|
|
3123
|
-
const templateLabel = options.
|
|
3260
|
+
const options = await gatherOptions(appName, requestedTemplate);
|
|
3261
|
+
const templateLabel = getTemplateDefinition(options.template).name;
|
|
3124
3262
|
showScaffoldSummary(options.name, templateLabel);
|
|
3125
3263
|
console.log("");
|
|
3126
3264
|
log.step(`Creating ${bold(options.name)}...`);
|
|
@@ -3165,7 +3303,8 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
3165
3303
|
console.log("Options:");
|
|
3166
3304
|
console.log(" -h, --help Show this help message");
|
|
3167
3305
|
console.log(" -v, --version Show version number");
|
|
3168
|
-
console.log(" --
|
|
3306
|
+
console.log(" --template <name> Choose template: basic, css, or tailwind");
|
|
3307
|
+
console.log(" --with-tailwind Alias for --template tailwind");
|
|
3169
3308
|
console.log("");
|
|
3170
3309
|
console.log("Examples:");
|
|
3171
3310
|
console.log(" npx create-zenith my-app");
|
|
@@ -3178,9 +3317,30 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
3178
3317
|
console.log(`create-zenith ${VERSION}`);
|
|
3179
3318
|
process.exit(0);
|
|
3180
3319
|
}
|
|
3181
|
-
var projectName
|
|
3182
|
-
var
|
|
3183
|
-
|
|
3320
|
+
var projectName;
|
|
3321
|
+
var requestedTemplate;
|
|
3322
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
3323
|
+
const arg = args[index];
|
|
3324
|
+
if (arg === "--with-tailwind") {
|
|
3325
|
+
requestedTemplate = "tailwind";
|
|
3326
|
+
continue;
|
|
3327
|
+
}
|
|
3328
|
+
if (arg === "--template") {
|
|
3329
|
+
const templateValue = args[index + 1];
|
|
3330
|
+
const templateName = resolveTemplateName(templateValue);
|
|
3331
|
+
if (!templateName) {
|
|
3332
|
+
error(`Unsupported template "${templateValue || ""}". Use basic, css, or tailwind.`);
|
|
3333
|
+
process.exit(1);
|
|
3334
|
+
}
|
|
3335
|
+
requestedTemplate = templateName;
|
|
3336
|
+
index += 1;
|
|
3337
|
+
continue;
|
|
3338
|
+
}
|
|
3339
|
+
if (!arg.startsWith("-") && !projectName) {
|
|
3340
|
+
projectName = arg;
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
create(projectName, requestedTemplate).catch((err) => {
|
|
3184
3344
|
const mode = getUiMode(process);
|
|
3185
3345
|
if (mode.plain) {
|
|
3186
3346
|
console.log("ERROR: SCAFFOLD_ERROR");
|
package/dist/index.js
CHANGED
|
@@ -2552,6 +2552,33 @@ class dD extends x {
|
|
|
2552
2552
|
}
|
|
2553
2553
|
var A;
|
|
2554
2554
|
A = new WeakMap;
|
|
2555
|
+
var OD = Object.defineProperty;
|
|
2556
|
+
var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
2557
|
+
var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
2558
|
+
|
|
2559
|
+
class LD extends x {
|
|
2560
|
+
constructor(u) {
|
|
2561
|
+
super(u, false), J(this, "options"), J(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: t }) => t === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (t) => {
|
|
2562
|
+
switch (t) {
|
|
2563
|
+
case "left":
|
|
2564
|
+
case "up":
|
|
2565
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
2566
|
+
break;
|
|
2567
|
+
case "down":
|
|
2568
|
+
case "right":
|
|
2569
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
2570
|
+
break;
|
|
2571
|
+
}
|
|
2572
|
+
this.changeValue();
|
|
2573
|
+
});
|
|
2574
|
+
}
|
|
2575
|
+
get _value() {
|
|
2576
|
+
return this.options[this.cursor];
|
|
2577
|
+
}
|
|
2578
|
+
changeValue() {
|
|
2579
|
+
this.value = this._value.value;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2555
2582
|
class RD extends x {
|
|
2556
2583
|
get valueWithCursor() {
|
|
2557
2584
|
if (this.state === "submit")
|
|
@@ -2614,6 +2641,16 @@ var b2 = (t) => {
|
|
|
2614
2641
|
return import_picocolors3.default.green(C);
|
|
2615
2642
|
}
|
|
2616
2643
|
};
|
|
2644
|
+
var G2 = (t) => {
|
|
2645
|
+
const { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
|
|
2646
|
+
let l2 = 0;
|
|
2647
|
+
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
2648
|
+
const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
2649
|
+
return r2.slice(l2, l2 + a).map((p2, v2, f) => {
|
|
2650
|
+
const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
|
|
2651
|
+
return j2 || E ? import_picocolors3.default.dim("...") : i(p2, v2 + l2 === n);
|
|
2652
|
+
});
|
|
2653
|
+
};
|
|
2617
2654
|
var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
2618
2655
|
const n = `${import_picocolors3.default.gray(o)}
|
|
2619
2656
|
${b2(this.state)} ${t.message}
|
|
@@ -2654,6 +2691,38 @@ ${import_picocolors3.default.cyan(d2)}
|
|
|
2654
2691
|
}
|
|
2655
2692
|
} }).prompt();
|
|
2656
2693
|
};
|
|
2694
|
+
var ve = (t) => {
|
|
2695
|
+
const n = (r2, i) => {
|
|
2696
|
+
const s = r2.label ?? String(r2.value);
|
|
2697
|
+
switch (i) {
|
|
2698
|
+
case "selected":
|
|
2699
|
+
return `${import_picocolors3.default.dim(s)}`;
|
|
2700
|
+
case "active":
|
|
2701
|
+
return `${import_picocolors3.default.green(k2)} ${s} ${r2.hint ? import_picocolors3.default.dim(`(${r2.hint})`) : ""}`;
|
|
2702
|
+
case "cancelled":
|
|
2703
|
+
return `${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}`;
|
|
2704
|
+
default:
|
|
2705
|
+
return `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(s)}`;
|
|
2706
|
+
}
|
|
2707
|
+
};
|
|
2708
|
+
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
2709
|
+
const r2 = `${import_picocolors3.default.gray(o)}
|
|
2710
|
+
${b2(this.state)} ${t.message}
|
|
2711
|
+
`;
|
|
2712
|
+
switch (this.state) {
|
|
2713
|
+
case "submit":
|
|
2714
|
+
return `${r2}${import_picocolors3.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
2715
|
+
case "cancel":
|
|
2716
|
+
return `${r2}${import_picocolors3.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
2717
|
+
${import_picocolors3.default.gray(o)}`;
|
|
2718
|
+
default:
|
|
2719
|
+
return `${r2}${import_picocolors3.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
|
|
2720
|
+
${import_picocolors3.default.cyan(o)} `)}
|
|
2721
|
+
${import_picocolors3.default.cyan(d2)}
|
|
2722
|
+
`;
|
|
2723
|
+
}
|
|
2724
|
+
} }).prompt();
|
|
2725
|
+
};
|
|
2657
2726
|
var xe = (t = "") => {
|
|
2658
2727
|
process.stdout.write(`${import_picocolors3.default.gray(d2)} ${import_picocolors3.default.red(t)}
|
|
2659
2728
|
|
|
@@ -2686,7 +2755,7 @@ var M2 = { message: (t = "", { symbol: n = import_picocolors3.default.gray(o) }
|
|
|
2686
2755
|
}, error: (t) => {
|
|
2687
2756
|
M2.message(t, { symbol: import_picocolors3.default.red(K2) });
|
|
2688
2757
|
} };
|
|
2689
|
-
var
|
|
2758
|
+
var J2 = `${import_picocolors3.default.gray(o)} `;
|
|
2690
2759
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
2691
2760
|
const n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
|
|
2692
2761
|
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
@@ -2776,6 +2845,12 @@ async function confirm(opts) {
|
|
|
2776
2845
|
initialValue: opts.initialValue ?? true
|
|
2777
2846
|
});
|
|
2778
2847
|
}
|
|
2848
|
+
async function select(opts) {
|
|
2849
|
+
if (!isTTY()) {
|
|
2850
|
+
return opts.initialValue || opts.options[0]?.value;
|
|
2851
|
+
}
|
|
2852
|
+
return await ve(opts);
|
|
2853
|
+
}
|
|
2779
2854
|
function isCancel(value) {
|
|
2780
2855
|
return pD(value);
|
|
2781
2856
|
}
|
|
@@ -2884,10 +2959,58 @@ function applyPackageFeatures(manifest, options) {
|
|
|
2884
2959
|
return nextManifest;
|
|
2885
2960
|
}
|
|
2886
2961
|
|
|
2962
|
+
// src/templates.ts
|
|
2963
|
+
var DEFAULT_TEMPLATE = "css";
|
|
2964
|
+
var TEMPLATE_DEFINITIONS = {
|
|
2965
|
+
basic: {
|
|
2966
|
+
name: "basic",
|
|
2967
|
+
label: "Basic",
|
|
2968
|
+
hint: "Blank starter with a single page and minimal CSS",
|
|
2969
|
+
templatePath: "templates/basic",
|
|
2970
|
+
usesTailwind: false
|
|
2971
|
+
},
|
|
2972
|
+
css: {
|
|
2973
|
+
name: "css",
|
|
2974
|
+
label: "CSS",
|
|
2975
|
+
hint: "Multi-page starter with a small curated CSS setup",
|
|
2976
|
+
templatePath: "templates/css",
|
|
2977
|
+
usesTailwind: false
|
|
2978
|
+
},
|
|
2979
|
+
tailwind: {
|
|
2980
|
+
name: "tailwind",
|
|
2981
|
+
label: "Tailwind",
|
|
2982
|
+
hint: "Multi-page starter with Tailwind enabled",
|
|
2983
|
+
templatePath: "templates/tailwind",
|
|
2984
|
+
usesTailwind: true
|
|
2985
|
+
}
|
|
2986
|
+
};
|
|
2987
|
+
var TEMPLATE_ALIASES = {
|
|
2988
|
+
starter: "css",
|
|
2989
|
+
"starter-tailwindcss": "tailwind"
|
|
2990
|
+
};
|
|
2991
|
+
function resolveTemplateName(value) {
|
|
2992
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
2993
|
+
if (!normalized) {
|
|
2994
|
+
return null;
|
|
2995
|
+
}
|
|
2996
|
+
if (normalized in TEMPLATE_DEFINITIONS) {
|
|
2997
|
+
return normalized;
|
|
2998
|
+
}
|
|
2999
|
+
return TEMPLATE_ALIASES[normalized] || null;
|
|
3000
|
+
}
|
|
3001
|
+
function getTemplateDefinition(templateName) {
|
|
3002
|
+
return TEMPLATE_DEFINITIONS[templateName];
|
|
3003
|
+
}
|
|
3004
|
+
function templateSelectOptions() {
|
|
3005
|
+
return Object.values(TEMPLATE_DEFINITIONS).map((definition) => ({
|
|
3006
|
+
value: definition.name,
|
|
3007
|
+
label: definition.label,
|
|
3008
|
+
hint: definition.hint
|
|
3009
|
+
}));
|
|
3010
|
+
}
|
|
3011
|
+
|
|
2887
3012
|
// src/index.ts
|
|
2888
3013
|
var GITHUB_REPO = "zenithbuild/framework";
|
|
2889
|
-
var DEFAULT_TEMPLATE = "examples/starter";
|
|
2890
|
-
var TAILWIND_TEMPLATE = "examples/starter-tailwindcss";
|
|
2891
3014
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
2892
3015
|
var __dirname2 = path.dirname(__filename2);
|
|
2893
3016
|
function getCliVersion() {
|
|
@@ -3010,10 +3133,23 @@ function readOptionOverride(name) {
|
|
|
3010
3133
|
}
|
|
3011
3134
|
return flagEnabled2(value);
|
|
3012
3135
|
}
|
|
3013
|
-
|
|
3136
|
+
function readTemplateOverride(name) {
|
|
3137
|
+
const value = process.env[name];
|
|
3138
|
+
if (value == null || value.trim() === "") {
|
|
3139
|
+
return;
|
|
3140
|
+
}
|
|
3141
|
+
const templateName = resolveTemplateName(value);
|
|
3142
|
+
if (!templateName) {
|
|
3143
|
+
throw new Error(`Unsupported template "${value}". Use basic, css, or tailwind.`);
|
|
3144
|
+
}
|
|
3145
|
+
return templateName;
|
|
3146
|
+
}
|
|
3147
|
+
async function gatherOptions(providedName, requestedTemplate) {
|
|
3014
3148
|
const eslintOverride = readOptionOverride("CREATE_ZENITH_ESLINT");
|
|
3015
3149
|
const prettierOverride = readOptionOverride("CREATE_ZENITH_PRETTIER");
|
|
3016
3150
|
const pathAliasOverride = readOptionOverride("CREATE_ZENITH_PATH_ALIAS");
|
|
3151
|
+
const templateOverride = readTemplateOverride("CREATE_ZENITH_TEMPLATE");
|
|
3152
|
+
const selectedTemplate = requestedTemplate || templateOverride || DEFAULT_TEMPLATE;
|
|
3017
3153
|
let name = providedName;
|
|
3018
3154
|
if (!name) {
|
|
3019
3155
|
const nameResult = await text({
|
|
@@ -3054,15 +3190,17 @@ async function gatherOptions(providedName, withTailwind) {
|
|
|
3054
3190
|
eslint: eslintOverride ?? true,
|
|
3055
3191
|
prettier: prettierOverride ?? true,
|
|
3056
3192
|
pathAlias: pathAliasOverride ?? true,
|
|
3057
|
-
|
|
3193
|
+
template: selectedTemplate
|
|
3058
3194
|
};
|
|
3059
3195
|
}
|
|
3060
|
-
const
|
|
3061
|
-
message: "
|
|
3062
|
-
|
|
3196
|
+
const templateResult = requestedTemplate ?? templateOverride ?? await select({
|
|
3197
|
+
message: "Choose a starter template",
|
|
3198
|
+
options: templateSelectOptions(),
|
|
3199
|
+
initialValue: DEFAULT_TEMPLATE
|
|
3063
3200
|
});
|
|
3064
|
-
if (isCancel(
|
|
3201
|
+
if (requestedTemplate === undefined && templateOverride === undefined && isCancel(templateResult)) {
|
|
3065
3202
|
handleCancel();
|
|
3203
|
+
}
|
|
3066
3204
|
const eslintResult = eslintOverride ?? await confirm({
|
|
3067
3205
|
message: "Add ESLint for code linting?",
|
|
3068
3206
|
initialValue: true
|
|
@@ -3086,12 +3224,12 @@ async function gatherOptions(providedName, withTailwind) {
|
|
|
3086
3224
|
eslint: eslintResult,
|
|
3087
3225
|
prettier: prettierResult,
|
|
3088
3226
|
pathAlias: pathAliasResult,
|
|
3089
|
-
|
|
3227
|
+
template: templateResult
|
|
3090
3228
|
};
|
|
3091
3229
|
}
|
|
3092
3230
|
async function createProject(options) {
|
|
3093
3231
|
const targetDir = path.resolve(process.cwd(), options.name);
|
|
3094
|
-
const templatePath = options.
|
|
3232
|
+
const templatePath = getTemplateDefinition(options.template).templatePath;
|
|
3095
3233
|
const templateFeaturePaths = selectedTemplateFeaturePaths(options);
|
|
3096
3234
|
await downloadTemplate(targetDir, [templatePath, ...templateFeaturePaths]);
|
|
3097
3235
|
const pkgPath = path.join(targetDir, "package.json");
|
|
@@ -3116,10 +3254,10 @@ async function createProject(options) {
|
|
|
3116
3254
|
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 4));
|
|
3117
3255
|
}
|
|
3118
3256
|
}
|
|
3119
|
-
async function create(appName,
|
|
3257
|
+
async function create(appName, requestedTemplate) {
|
|
3120
3258
|
await intro();
|
|
3121
|
-
const options = await gatherOptions(appName,
|
|
3122
|
-
const templateLabel = options.
|
|
3259
|
+
const options = await gatherOptions(appName, requestedTemplate);
|
|
3260
|
+
const templateLabel = getTemplateDefinition(options.template).name;
|
|
3123
3261
|
showScaffoldSummary(options.name, templateLabel);
|
|
3124
3262
|
console.log("");
|
|
3125
3263
|
log.step(`Creating ${bold(options.name)}...`);
|
|
@@ -3164,7 +3302,8 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
3164
3302
|
console.log("Options:");
|
|
3165
3303
|
console.log(" -h, --help Show this help message");
|
|
3166
3304
|
console.log(" -v, --version Show version number");
|
|
3167
|
-
console.log(" --
|
|
3305
|
+
console.log(" --template <name> Choose template: basic, css, or tailwind");
|
|
3306
|
+
console.log(" --with-tailwind Alias for --template tailwind");
|
|
3168
3307
|
console.log("");
|
|
3169
3308
|
console.log("Examples:");
|
|
3170
3309
|
console.log(" npx create-zenith my-app");
|
|
@@ -3177,9 +3316,30 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
3177
3316
|
console.log(`create-zenith ${VERSION}`);
|
|
3178
3317
|
process.exit(0);
|
|
3179
3318
|
}
|
|
3180
|
-
var projectName
|
|
3181
|
-
var
|
|
3182
|
-
|
|
3319
|
+
var projectName;
|
|
3320
|
+
var requestedTemplate;
|
|
3321
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
3322
|
+
const arg = args[index];
|
|
3323
|
+
if (arg === "--with-tailwind") {
|
|
3324
|
+
requestedTemplate = "tailwind";
|
|
3325
|
+
continue;
|
|
3326
|
+
}
|
|
3327
|
+
if (arg === "--template") {
|
|
3328
|
+
const templateValue = args[index + 1];
|
|
3329
|
+
const templateName = resolveTemplateName(templateValue);
|
|
3330
|
+
if (!templateName) {
|
|
3331
|
+
error(`Unsupported template "${templateValue || ""}". Use basic, css, or tailwind.`);
|
|
3332
|
+
process.exit(1);
|
|
3333
|
+
}
|
|
3334
|
+
requestedTemplate = templateName;
|
|
3335
|
+
index += 1;
|
|
3336
|
+
continue;
|
|
3337
|
+
}
|
|
3338
|
+
if (!arg.startsWith("-") && !projectName) {
|
|
3339
|
+
projectName = arg;
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
create(projectName, requestedTemplate).catch((err) => {
|
|
3183
3343
|
const mode = getUiMode(process);
|
|
3184
3344
|
if (mode.plain) {
|
|
3185
3345
|
console.log("ERROR: SCAFFOLD_ERROR");
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-zenith",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.20",
|
|
4
4
|
"description": "Create a new Zenith application - the modern reactive web framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-zenith": "dist/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist/**"
|
|
10
|
+
"dist/**",
|
|
11
|
+
"templates/**"
|
|
11
12
|
],
|
|
12
13
|
"scripts": {
|
|
13
14
|
"build": "bun build src/index.ts --outdir dist --target node --format esm && node -e \"const fs=require('fs');const c=fs.readFileSync('dist/index.js','utf8');fs.writeFileSync('dist/cli.js','#!/usr/bin/env node\\n'+c);fs.chmodSync('dist/cli.js','755')\"",
|
|
14
15
|
"prepublishOnly": "npm run build",
|
|
15
16
|
"create": "bun src/index.ts",
|
|
16
|
-
"
|
|
17
|
-
"test": "node --test tests/*.spec.mjs",
|
|
17
|
+
"test": "bun run build && node --test tests/*.spec.mjs",
|
|
18
18
|
"release": "bun run scripts/release.ts",
|
|
19
19
|
"release:dry": "bun run scripts/release.ts --dry-run",
|
|
20
20
|
"release:patch": "bun run scripts/release.ts --bump=patch",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zenith Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|