@zenithbuild/cli 0.4.10 → 0.5.0-beta.2.12

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.
@@ -0,0 +1,146 @@
1
+ // server-contract.js — Zenith CLI V0
2
+ // ---------------------------------------------------------------------------
3
+ // Shared validation and payload resolution logic for <script server> blocks.
4
+
5
+ const NEW_KEYS = new Set(['data', 'load', 'prerender']);
6
+ const LEGACY_KEYS = new Set(['ssr_data', 'props', 'ssr', 'prerender']);
7
+ const ALLOWED_KEYS = new Set(['data', 'load', 'prerender', 'ssr_data', 'props', 'ssr']);
8
+
9
+ export function validateServerExports({ exports, filePath }) {
10
+ const exportKeys = Object.keys(exports);
11
+ const illegalKeys = exportKeys.filter(k => !ALLOWED_KEYS.has(k));
12
+
13
+ if (illegalKeys.length > 0) {
14
+ throw new Error(`[Zenith] ${filePath}: illegal export(s): ${illegalKeys.join(', ')}`);
15
+ }
16
+
17
+ const hasData = 'data' in exports;
18
+ const hasLoad = 'load' in exports;
19
+
20
+ const hasNew = hasData || hasLoad;
21
+ const hasLegacy = ('ssr_data' in exports) || ('props' in exports) || ('ssr' in exports);
22
+
23
+ if (hasData && hasLoad) {
24
+ throw new Error(`[Zenith] ${filePath}: cannot export both "data" and "load". Choose one.`);
25
+ }
26
+
27
+ if (hasNew && hasLegacy) {
28
+ throw new Error(
29
+ `[Zenith] ${filePath}: cannot mix new ("data"/"load") with legacy ("ssr_data"/"props"/"ssr") exports.`
30
+ );
31
+ }
32
+
33
+ if ('prerender' in exports && typeof exports.prerender !== 'boolean') {
34
+ throw new Error(`[Zenith] ${filePath}: "prerender" must be a boolean.`);
35
+ }
36
+
37
+ if (hasLoad && typeof exports.load !== 'function') {
38
+ throw new Error(`[Zenith] ${filePath}: "load" must be a function.`);
39
+ }
40
+ if (hasLoad) {
41
+ if (exports.load.length !== 1) {
42
+ throw new Error(`[Zenith] ${filePath}: "load(ctx)" must take exactly 1 argument.`);
43
+ }
44
+ const fnStr = exports.load.toString();
45
+ const paramsMatch = fnStr.match(/^[^{=]+\(([^)]*)\)/);
46
+ if (paramsMatch && paramsMatch[1].includes('...')) {
47
+ throw new Error(`[Zenith] ${filePath}: "load(ctx)" must not contain rest parameters.`);
48
+ }
49
+ }
50
+ }
51
+
52
+ export function assertJsonSerializable(value, where = 'payload') {
53
+ const seen = new Set();
54
+
55
+ function walk(v, path) {
56
+ const t = typeof v;
57
+
58
+ if (v === null) return;
59
+ if (t === 'string' || t === 'number' || t === 'boolean') return;
60
+
61
+ if (t === 'bigint' || t === 'function' || t === 'symbol') {
62
+ throw new Error(`[Zenith] ${where}: non-serializable ${t} at ${path}`);
63
+ }
64
+
65
+ if (t === 'undefined') {
66
+ throw new Error(`[Zenith] ${where}: undefined is not allowed at ${path}`);
67
+ }
68
+
69
+ if (v instanceof Date) {
70
+ throw new Error(`[Zenith] ${where}: Date is not allowed at ${path} (convert to ISO string)`);
71
+ }
72
+
73
+ if (v instanceof Map || v instanceof Set) {
74
+ throw new Error(`[Zenith] ${where}: Map/Set not allowed at ${path}`);
75
+ }
76
+
77
+ if (t === 'object') {
78
+ if (seen.has(v)) throw new Error(`[Zenith] ${where}: circular reference at ${path}`);
79
+ seen.add(v);
80
+
81
+ if (Array.isArray(v)) {
82
+ if (path === '$') {
83
+ throw new Error(`[Zenith] ${where}: top-level payload must be a plain object, not an array at ${path}`);
84
+ }
85
+ for (let i = 0; i < v.length; i++) walk(v[i], `${path}[${i}]`);
86
+ return;
87
+ }
88
+
89
+ const proto = Object.getPrototypeOf(v);
90
+ const isPlainObject = proto === null ||
91
+ proto === Object.prototype ||
92
+ (proto && proto.constructor && proto.constructor.name === 'Object');
93
+
94
+ if (!isPlainObject) {
95
+ throw new Error(`[Zenith] ${where}: non-plain object at ${path}`);
96
+ }
97
+
98
+ for (const k of Object.keys(v)) {
99
+ if (k === '__proto__' || k === 'constructor' || k === 'prototype') {
100
+ throw new Error(`[Zenith] ${where}: forbidden prototype pollution key "${k}" at ${path}.${k}`);
101
+ }
102
+ walk(v[k], `${path}.${k}`);
103
+ }
104
+ return;
105
+ }
106
+
107
+ throw new Error(`[Zenith] ${where}: unsupported type at ${path}`);
108
+ }
109
+
110
+ walk(value, '$');
111
+ }
112
+
113
+ export async function resolveServerPayload({ exports, ctx, filePath }) {
114
+ validateServerExports({ exports, filePath });
115
+
116
+ let payload;
117
+ if ('load' in exports) {
118
+ payload = await exports.load(ctx);
119
+ assertJsonSerializable(payload, `${filePath}: load(ctx) return`);
120
+ return payload;
121
+ }
122
+ if ('data' in exports) {
123
+ payload = exports.data;
124
+ assertJsonSerializable(payload, `${filePath}: data export`);
125
+ return payload;
126
+ }
127
+
128
+ // legacy fallback
129
+ if ('ssr_data' in exports) {
130
+ payload = exports.ssr_data;
131
+ assertJsonSerializable(payload, `${filePath}: ssr_data export`);
132
+ return payload;
133
+ }
134
+ if ('props' in exports) {
135
+ payload = exports.props;
136
+ assertJsonSerializable(payload, `${filePath}: props export`);
137
+ return payload;
138
+ }
139
+ if ('ssr' in exports) {
140
+ payload = exports.ssr;
141
+ assertJsonSerializable(payload, `${filePath}: ssr export`);
142
+ return payload;
143
+ }
144
+
145
+ return {};
146
+ }
@@ -0,0 +1,52 @@
1
+ import { writeFile, mkdir } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+
4
+ export async function generateEnvDts(projectRoot) {
5
+ const content = `// .zenith/zenith-env.d.ts
6
+ // Auto-generated by Zenith. Do not edit.
7
+
8
+ export {};
9
+
10
+ declare global {
11
+ namespace Zenith {
12
+ type Params = Record<string, string>;
13
+
14
+ interface LoadContext {
15
+ params: Params;
16
+ url: URL;
17
+ request: Request;
18
+ route: {
19
+ id: string;
20
+ file: string;
21
+ pattern: string;
22
+ };
23
+ }
24
+
25
+ interface ErrorState {
26
+ status?: number;
27
+ code?: string;
28
+ message: string;
29
+ }
30
+
31
+ type PageData = Record<string, unknown> & {
32
+ __zenith_error?: ErrorState;
33
+ };
34
+
35
+ type Load<T extends PageData = PageData> = (ctx: LoadContext) => Promise<T> | T;
36
+
37
+ type Renderable =
38
+ | string
39
+ | number
40
+ | boolean
41
+ | null
42
+ | undefined
43
+ | Renderable[]
44
+ | { __zenith_fragment: true };
45
+ }
46
+ }
47
+ `;
48
+
49
+ const outPath = join(projectRoot, '.zenith', 'zenith-env.d.ts');
50
+ await mkdir(dirname(outPath), { recursive: true });
51
+ await writeFile(outPath, content, 'utf8');
52
+ }
@@ -0,0 +1,22 @@
1
+ import { writeFile, mkdir } from 'node:fs/promises';
2
+ import { join, dirname } from 'node:path';
3
+
4
+ export async function generateRoutesDts(projectRoot, manifest) {
5
+ const routes = (manifest || []).map(r => r.path).filter(Boolean);
6
+ const typeDef = routes.length > 0
7
+ ? routes.map(r => '"' + r + '"').join(' | ')
8
+ : 'string';
9
+
10
+ const content = '// .zenith/zenith-routes.d.ts\\n' +
11
+ '// Auto-generated by Zenith. Do not edit.\\n\\n' +
12
+ 'export {};\\n\\n' +
13
+ 'declare global {\\n' +
14
+ ' namespace Zenith {\\n' +
15
+ ' type RoutePattern = ' + typeDef + ';\\n' +
16
+ ' }\\n' +
17
+ '}\\n';
18
+
19
+ const outPath = join(projectRoot, '.zenith', 'zenith-routes.d.ts');
20
+ await mkdir(dirname(outPath), { recursive: true });
21
+ await writeFile(outPath, content, 'utf8');
22
+ }
@@ -0,0 +1,34 @@
1
+ import { generateEnvDts } from './generate-env-dts.js';
2
+ import { generateRoutesDts } from './generate-routes-dts.js';
3
+ import { join } from 'node:path';
4
+ import { access, constants } from 'node:fs/promises';
5
+
6
+ export async function ensureZenithTypes(projectRoot, manifest) {
7
+ try {
8
+ await generateEnvDts(projectRoot);
9
+ if (manifest) {
10
+ await generateRoutesDts(projectRoot, manifest);
11
+ }
12
+
13
+ // Check if tsconfig.json exists, if it does, check if .zenith is included
14
+ const tsconfigPath = join(projectRoot, 'tsconfig.json');
15
+ let hasTsConfig = false;
16
+ try {
17
+ await access(tsconfigPath, constants.F_OK);
18
+ hasTsConfig = true;
19
+ } catch {
20
+ hasTsConfig = false;
21
+ }
22
+
23
+ if (hasTsConfig) {
24
+ // In a real implementation this would parse the JSON and check "include".
25
+ // For now, we simply inform the user to include it if they haven't.
26
+ if (!globalThis.__zenithTypesWarned) {
27
+ console.warn('\\x1b[33m[zenith]\\x1b[0m For the best TypeScript experience, ensure ".zenith/**/*.d.ts" is in your tsconfig.json "include" array.');
28
+ globalThis.__zenithTypesWarned = true;
29
+ }
30
+ }
31
+ } catch (err) {
32
+ console.error('[zenith] Failed to generate type definitions:', err);
33
+ }
34
+ }
package/dist/ui/env.js ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * UI environment mode detection for deterministic CLI output.
3
+ */
4
+
5
+ function flagEnabled(value) {
6
+ if (value === undefined || value === null) {
7
+ return false;
8
+ }
9
+ const normalized = String(value).trim().toLowerCase();
10
+ return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
11
+ }
12
+
13
+ /**
14
+ * @param {{ env?: Record<string, string | undefined>, stdout?: { isTTY?: boolean } }} runtime
15
+ */
16
+ export function getUiMode(runtime = process) {
17
+ const env = runtime.env || {};
18
+ const tty = Boolean(runtime.stdout?.isTTY);
19
+ const ci = flagEnabled(env.CI);
20
+ const noUi = flagEnabled(env.ZENITH_NO_UI);
21
+ const noColor = env.NO_COLOR !== undefined && String(env.NO_COLOR).length >= 0;
22
+ const forceColor = flagEnabled(env.FORCE_COLOR);
23
+ const debug = flagEnabled(env.ZENITH_DEBUG);
24
+
25
+ const plain = noUi || ci || !tty;
26
+ const color = !plain && !noColor && (forceColor || tty);
27
+ const spinner = tty && !plain && !ci;
28
+
29
+ return {
30
+ plain,
31
+ color,
32
+ tty,
33
+ ci,
34
+ spinner,
35
+ debug
36
+ };
37
+ }
38
+
39
+ export function isUiPlain(runtime = process) {
40
+ return getUiMode(runtime).plain;
41
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Deterministic text formatters for CLI UX.
3
+ */
4
+
5
+ import { relative, sep } from 'node:path';
6
+
7
+ const ANSI = {
8
+ reset: '\x1b[0m',
9
+ bold: '\x1b[1m',
10
+ dim: '\x1b[2m',
11
+ red: '\x1b[31m',
12
+ yellow: '\x1b[33m',
13
+ green: '\x1b[32m',
14
+ cyan: '\x1b[36m'
15
+ };
16
+ const DEFAULT_PHASE = 'cli';
17
+ const DEFAULT_FILE = '.';
18
+ const DEFAULT_HINT_BASE = 'https://github.com/zenithbuild/zenith/blob/main/zenith-cli/CLI_CONTRACT.md';
19
+
20
+ function colorize(mode, token, text) {
21
+ if (!mode.color) {
22
+ return text;
23
+ }
24
+ return `${ANSI[token]}${text}${ANSI.reset}`;
25
+ }
26
+
27
+ export function formatHeading(mode, text) {
28
+ const label = mode.plain ? 'ZENITH CLI' : colorize(mode, 'bold', 'Zenith CLI');
29
+ return `${label} ${text}`.trim();
30
+ }
31
+
32
+ export function formatStep(mode, text) {
33
+ if (mode.plain) {
34
+ return `[zenith] INFO: ${text}`;
35
+ }
36
+ const bullet = colorize(mode, 'cyan', '•');
37
+ return `[zenith] ${bullet} ${text}`;
38
+ }
39
+
40
+ export function formatSummaryTable(mode, rows) {
41
+ if (!Array.isArray(rows) || rows.length === 0) {
42
+ return '';
43
+ }
44
+ const maxLabel = rows.reduce((acc, row) => Math.max(acc, String(row.label || '').length), 0);
45
+ return rows
46
+ .map((row) => {
47
+ const label = String(row.label || '').padEnd(maxLabel, ' ');
48
+ const value = String(row.value || '');
49
+ return `[zenith] ${label} : ${value}`;
50
+ })
51
+ .join('\n');
52
+ }
53
+
54
+ export function sanitizeErrorMessage(input) {
55
+ return String(input ?? '')
56
+ .replace(/\r/g, '')
57
+ .trim();
58
+ }
59
+
60
+ function normalizeFileLinePath(line) {
61
+ const match = line.match(/^(\s*File:\s+)(.+)$/);
62
+ if (!match) {
63
+ return line;
64
+ }
65
+
66
+ const prefix = match[1];
67
+ const filePath = match[2].trim();
68
+ const normalized = normalizePathForDisplay(filePath);
69
+ return `${prefix}${normalized}`;
70
+ }
71
+
72
+ function normalizePathForDisplay(filePath) {
73
+ const value = String(filePath || '').trim();
74
+ if (!value) {
75
+ return DEFAULT_FILE;
76
+ }
77
+ if (!value.startsWith('/') && !/^[A-Za-z]:\\/.test(value)) {
78
+ return value;
79
+ }
80
+
81
+ const cwd = process.cwd();
82
+ const cwdWithSep = cwd.endsWith(sep) ? cwd : `${cwd}${sep}`;
83
+ if (value === cwd) {
84
+ return DEFAULT_FILE;
85
+ }
86
+ if (value.startsWith(cwdWithSep)) {
87
+ const relativePath = relative(cwd, value).replaceAll('\\', '/');
88
+ return relativePath || DEFAULT_FILE;
89
+ }
90
+
91
+ return value;
92
+ }
93
+
94
+ function inferPhaseFromArgv() {
95
+ const knownPhases = new Set(['build', 'dev', 'preview']);
96
+ for (const arg of process.argv.slice(2)) {
97
+ if (knownPhases.has(arg)) {
98
+ return arg;
99
+ }
100
+ }
101
+ return DEFAULT_PHASE;
102
+ }
103
+
104
+ function extractFileFromMessage(message) {
105
+ const match = String(message || '').match(/\bFile:\s+([^\n]+)/);
106
+ return match ? match[1].trim() : '';
107
+ }
108
+
109
+ function formatHintUrl(code) {
110
+ const slug = String(code || 'CLI_ERROR')
111
+ .toLowerCase()
112
+ .replace(/[^a-z0-9]+/g, '-')
113
+ .replace(/^-+|-+$/g, '');
114
+ return `${DEFAULT_HINT_BASE}#${slug || 'cli-error'}`;
115
+ }
116
+
117
+ export function normalizeErrorMessagePaths(message) {
118
+ return String(message || '')
119
+ .split('\n')
120
+ .map((line) => normalizeFileLinePath(line))
121
+ .join('\n');
122
+ }
123
+
124
+ /**
125
+ * @param {unknown} err
126
+ */
127
+ export function normalizeError(err) {
128
+ if (err instanceof Error) {
129
+ return err;
130
+ }
131
+ return new Error(sanitizeErrorMessage(err));
132
+ }
133
+
134
+ /**
135
+ * @param {unknown} err
136
+ * @param {{ plain: boolean, color: boolean, debug: boolean }} mode
137
+ */
138
+ export function formatErrorBlock(err, mode) {
139
+ const normalized = normalizeError(err);
140
+ const maybe = /** @type {{ code?: unknown, phase?: unknown, kind?: unknown, file?: unknown, hint?: unknown }} */ (normalized);
141
+ const kind = sanitizeErrorMessage(maybe.kind || maybe.code || 'CLI_ERROR');
142
+ const phase = maybe.phase ? sanitizeErrorMessage(maybe.phase) : inferPhaseFromArgv();
143
+ const code = maybe.code
144
+ ? sanitizeErrorMessage(maybe.code)
145
+ : `${phase.toUpperCase().replace(/[^A-Z0-9]+/g, '_') || 'CLI'}_FAILED`;
146
+ const rawMessage = sanitizeErrorMessage(normalized.message || String(normalized));
147
+ const message = normalizeErrorMessagePaths(rawMessage);
148
+ const file = normalizePathForDisplay(
149
+ sanitizeErrorMessage(maybe.file || extractFileFromMessage(message) || DEFAULT_FILE)
150
+ );
151
+ const hint = sanitizeErrorMessage(maybe.hint || formatHintUrl(code));
152
+
153
+ const lines = [];
154
+ lines.push('[zenith] ERROR: Command failed');
155
+ lines.push(`[zenith] Error Kind: ${kind}`);
156
+ lines.push(`[zenith] Phase: ${phase || DEFAULT_PHASE}`);
157
+ lines.push(`[zenith] Code: ${code || 'CLI_FAILED'}`);
158
+ lines.push(`[zenith] File: ${file || DEFAULT_FILE}`);
159
+ lines.push(`[zenith] Hint: ${hint || formatHintUrl(code)}`);
160
+ lines.push(`[zenith] Message: ${message}`);
161
+
162
+ if (mode.debug && normalized.stack) {
163
+ lines.push('[zenith] Stack:');
164
+ lines.push(...String(normalized.stack).split('\n').slice(0, 20));
165
+ }
166
+
167
+ return lines.join('\n');
168
+ }
169
+
170
+ export function containsAnsi(value) {
171
+ return /\x1b\[[0-9;]*m/.test(String(value || ''));
172
+ }
@@ -0,0 +1,105 @@
1
+ import { formatErrorBlock, formatHeading, formatStep, formatSummaryTable } from './format.js';
2
+ import { getUiMode } from './env.js';
3
+
4
+ const SPINNER_FRAMES = ['-', '\\', '|', '/'];
5
+
6
+ function write(out, text) {
7
+ out.write(`${text}\n`);
8
+ }
9
+
10
+ function createSpinner(mode, stderr) {
11
+ if (!mode.spinner) {
12
+ return {
13
+ start() { },
14
+ update() { },
15
+ stop() { },
16
+ succeed() { },
17
+ fail() { }
18
+ };
19
+ }
20
+
21
+ let interval = null;
22
+ let frame = 0;
23
+ let message = '';
24
+
25
+ const paint = () => {
26
+ const current = SPINNER_FRAMES[frame % SPINNER_FRAMES.length];
27
+ stderr.write(`\r[zenith] ${current} ${message}`);
28
+ frame += 1;
29
+ };
30
+
31
+ const clear = () => {
32
+ stderr.write('\r');
33
+ stderr.write(' '.repeat(message.length + 12));
34
+ stderr.write('\r');
35
+ };
36
+
37
+ return {
38
+ start(nextMessage) {
39
+ message = String(nextMessage || '');
40
+ clearInterval(interval);
41
+ frame = 0;
42
+ paint();
43
+ interval = setInterval(paint, 80);
44
+ },
45
+ update(nextMessage) {
46
+ message = String(nextMessage || '');
47
+ },
48
+ stop() {
49
+ clearInterval(interval);
50
+ interval = null;
51
+ clear();
52
+ },
53
+ succeed(nextMessage) {
54
+ this.stop();
55
+ write(stderr, `[zenith] OK: ${nextMessage}`);
56
+ },
57
+ fail(nextMessage) {
58
+ this.stop();
59
+ write(stderr, `[zenith] ERROR: ${nextMessage}`);
60
+ }
61
+ };
62
+ }
63
+
64
+ /**
65
+ * @param {NodeJS.Process} runtime
66
+ */
67
+ export function createLogger(runtime = process) {
68
+ const mode = getUiMode(runtime);
69
+ const stdout = runtime.stdout;
70
+ const stderr = runtime.stderr;
71
+ const spinner = createSpinner(mode, stderr);
72
+
73
+ return {
74
+ mode,
75
+ spinner,
76
+ heading(text) {
77
+ write(stdout, formatHeading(mode, text));
78
+ },
79
+ info(text) {
80
+ if (mode.plain) {
81
+ write(stdout, `[zenith] INFO: ${text}`);
82
+ return;
83
+ }
84
+ write(stdout, formatStep(mode, text));
85
+ },
86
+ success(text) {
87
+ write(stdout, `[zenith] OK: ${text}`);
88
+ },
89
+ warn(text) {
90
+ write(stderr, `[zenith] WARN: ${text}`);
91
+ },
92
+ error(err) {
93
+ write(stderr, formatErrorBlock(err, mode));
94
+ },
95
+ summary(rows) {
96
+ const table = formatSummaryTable(mode, rows);
97
+ if (table) {
98
+ write(stdout, table);
99
+ }
100
+ },
101
+ print(text) {
102
+ write(stdout, String(text));
103
+ }
104
+ };
105
+ }
package/package.json CHANGED
@@ -1,63 +1,35 @@
1
1
  {
2
2
  "name": "@zenithbuild/cli",
3
- "version": "0.4.10",
4
- "description": "CLI for Zenith framework - dev server, build tools, and plugin management",
3
+ "version": "0.5.0-beta.2.12",
4
+ "description": "Deterministic project orchestrator for Zenith framework",
5
+ "license": "MIT",
5
6
  "type": "module",
6
- "bin": {
7
- "zenith": "./dist/zenith.js",
8
- "zen-dev": "./dist/zen-dev.js",
9
- "zen-build": "./dist/zen-build.js",
10
- "zen-preview": "./dist/zen-preview.js"
11
- },
12
- "main": "./src/index.ts",
13
- "types": "./src/index.ts",
7
+ "main": "./dist/index.js",
14
8
  "exports": {
15
- ".": {
16
- "types": "./src/index.ts",
17
- "import": "./src/index.ts"
18
- }
9
+ ".": "./dist/index.js"
19
10
  },
20
11
  "files": [
21
- "bin",
22
- "src"
23
- ],
24
- "scripts": {
25
- "dev": "bun run build && bin/zenith.ts dev",
26
- "build": "bun build bin/zenith.ts bin/zen-dev.ts bin/zen-build.ts bin/zen-preview.ts --outdir dist --target bun --bundle && for f in dist/*.js; do echo '#!/usr/bin/env bun' | cat - \"$f\" > \"$f.tmp\" && mv \"$f.tmp\" \"$f\" && chmod +x \"$f\"; done",
27
- "start": "bun run build && bun run dev",
28
- "test": "bun test",
29
- "release": "bun run scripts/release.ts",
30
- "release:dry": "bun run scripts/release.ts --dry-run",
31
- "release:patch": "bun run scripts/release.ts --bump=patch",
32
- "release:minor": "bun run scripts/release.ts --bump=minor",
33
- "release:major": "bun run scripts/release.ts --bump=major"
34
- },
35
- "keywords": [
36
- "zenith",
37
- "cli",
38
- "framework",
39
- "ssg",
40
- "ssr"
12
+ "dist",
13
+ "README.md",
14
+ "LICENSE",
15
+ "dist/**",
16
+ "package.json"
41
17
  ],
42
- "author": "Zenith Team",
43
- "license": "MIT",
44
- "repository": {
45
- "type": "git",
46
- "url": "git@github.com:zenithbuild/zenith-cli.git"
47
- },
48
18
  "publishConfig": {
49
19
  "access": "public"
50
20
  },
51
- "private": false,
52
- "peerDependencies": {
53
- "@zenithbuild/core": "^1.2.14"
21
+ "scripts": {
22
+ "build": "mkdir -p dist && cp -a src/* dist/",
23
+ "test": "node --experimental-vm-modules $(node -e \"const path=require('node:path');const pkg=require.resolve('jest/package.json');process.stdout.write(path.join(path.dirname(pkg),'bin/jest.js'))\") --config jest.config.js --forceExit --runInBand",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "dependencies": {
27
+ "@zenithbuild/compiler": "0.5.0-beta.2.12"
54
28
  },
55
29
  "devDependencies": {
56
- "@types/bun": "latest"
30
+ "@jest/globals": "^30.2.0",
31
+ "jest": "^30.2.0",
32
+ "jest-environment-jsdom": "^30.2.0"
57
33
  },
58
- "dependencies": {
59
- "@zenithbuild/compiler": "^1.0.15",
60
- "@zenithbuild/router": "^1.0.7",
61
- "picocolors": "^1.0.0"
62
- }
63
- }
34
+ "private": false
35
+ }
package/bin/zen-build.ts DELETED
@@ -1,2 +0,0 @@
1
- import { runCLI } from '../src/main'
2
- runCLI({ defaultCommand: 'build' })
package/bin/zen-dev.ts DELETED
@@ -1,2 +0,0 @@
1
- import { runCLI } from '../src/main'
2
- runCLI({ defaultCommand: 'dev' })
@@ -1,2 +0,0 @@
1
- import { runCLI } from '../src/main'
2
- runCLI({ defaultCommand: 'preview' })
package/bin/zenith.ts DELETED
@@ -1,2 +0,0 @@
1
- import { runCLI } from '../src/main'
2
- runCLI()