@cmj/juice 0.0.1

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -0
  3. package/dist/cli/commands.d.ts +29 -0
  4. package/dist/cli/commands.d.ts.map +1 -0
  5. package/dist/cli/commands.js +102 -0
  6. package/dist/cli/commands.js.map +1 -0
  7. package/dist/cli/create.d.ts +35 -0
  8. package/dist/cli/create.d.ts.map +1 -0
  9. package/dist/cli/create.js +108 -0
  10. package/dist/cli/create.js.map +1 -0
  11. package/dist/cli/index.d.ts +3 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +97 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/templates.d.ts +14 -0
  16. package/dist/cli/templates.d.ts.map +1 -0
  17. package/dist/cli/templates.js +154 -0
  18. package/dist/cli/templates.js.map +1 -0
  19. package/dist/compiler/errors.d.ts +91 -0
  20. package/dist/compiler/errors.d.ts.map +1 -0
  21. package/dist/compiler/errors.js +110 -0
  22. package/dist/compiler/errors.js.map +1 -0
  23. package/dist/compiler/manifest.d.ts +39 -0
  24. package/dist/compiler/manifest.d.ts.map +1 -0
  25. package/dist/compiler/manifest.js +78 -0
  26. package/dist/compiler/manifest.js.map +1 -0
  27. package/dist/compiler/parse.d.ts +126 -0
  28. package/dist/compiler/parse.d.ts.map +1 -0
  29. package/dist/compiler/parse.js +246 -0
  30. package/dist/compiler/parse.js.map +1 -0
  31. package/dist/compiler/plugin.d.ts +43 -0
  32. package/dist/compiler/plugin.d.ts.map +1 -0
  33. package/dist/compiler/plugin.js +281 -0
  34. package/dist/compiler/plugin.js.map +1 -0
  35. package/dist/compiler/proxy.d.ts +42 -0
  36. package/dist/compiler/proxy.d.ts.map +1 -0
  37. package/dist/compiler/proxy.js +80 -0
  38. package/dist/compiler/proxy.js.map +1 -0
  39. package/dist/compiler/registry.d.ts +58 -0
  40. package/dist/compiler/registry.d.ts.map +1 -0
  41. package/dist/compiler/registry.js +79 -0
  42. package/dist/compiler/registry.js.map +1 -0
  43. package/dist/compiler/server-action-registry.d.ts +57 -0
  44. package/dist/compiler/server-action-registry.d.ts.map +1 -0
  45. package/dist/compiler/server-action-registry.js +76 -0
  46. package/dist/compiler/server-action-registry.js.map +1 -0
  47. package/dist/compiler/server-actions.d.ts +49 -0
  48. package/dist/compiler/server-actions.d.ts.map +1 -0
  49. package/dist/compiler/server-actions.js +89 -0
  50. package/dist/compiler/server-actions.js.map +1 -0
  51. package/dist/compiler/types.d.ts +188 -0
  52. package/dist/compiler/types.d.ts.map +1 -0
  53. package/dist/compiler/types.js +9 -0
  54. package/dist/compiler/types.js.map +1 -0
  55. package/dist/runtime/actions.d.ts +37 -0
  56. package/dist/runtime/actions.d.ts.map +1 -0
  57. package/dist/runtime/actions.js +167 -0
  58. package/dist/runtime/actions.js.map +1 -0
  59. package/dist/runtime/dev.d.ts +43 -0
  60. package/dist/runtime/dev.d.ts.map +1 -0
  61. package/dist/runtime/dev.js +260 -0
  62. package/dist/runtime/dev.js.map +1 -0
  63. package/dist/runtime/errors.d.ts +98 -0
  64. package/dist/runtime/errors.d.ts.map +1 -0
  65. package/dist/runtime/errors.js +124 -0
  66. package/dist/runtime/errors.js.map +1 -0
  67. package/dist/runtime/index.d.ts +3 -0
  68. package/dist/runtime/index.d.ts.map +1 -0
  69. package/dist/runtime/index.js +5 -0
  70. package/dist/runtime/index.js.map +1 -0
  71. package/dist/runtime/matcher.d.ts +44 -0
  72. package/dist/runtime/matcher.d.ts.map +1 -0
  73. package/dist/runtime/matcher.js +83 -0
  74. package/dist/runtime/matcher.js.map +1 -0
  75. package/dist/runtime/render.d.ts +25 -0
  76. package/dist/runtime/render.d.ts.map +1 -0
  77. package/dist/runtime/render.js +141 -0
  78. package/dist/runtime/render.js.map +1 -0
  79. package/dist/runtime/resolve.d.ts +24 -0
  80. package/dist/runtime/resolve.d.ts.map +1 -0
  81. package/dist/runtime/resolve.js +41 -0
  82. package/dist/runtime/resolve.js.map +1 -0
  83. package/dist/runtime/router.d.ts +74 -0
  84. package/dist/runtime/router.d.ts.map +1 -0
  85. package/dist/runtime/router.js +367 -0
  86. package/dist/runtime/router.js.map +1 -0
  87. package/dist/runtime/types.d.ts +245 -0
  88. package/dist/runtime/types.d.ts.map +1 -0
  89. package/dist/runtime/types.js +5 -0
  90. package/dist/runtime/types.js.map +1 -0
  91. package/package.json +92 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 cmj
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.
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # 🧃 Juice
2
+
3
+ Zero-bloat React 19 RSC framework.
4
+ Streaming SSR. Server Actions. Zero config.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ npm install @cmj/juice react@^19 react-dom@^19 vite@^6
10
+ ```
11
+
12
+ ## Quickstart
13
+
14
+ ```bash
15
+ npx juice create my-app
16
+ cd my-app
17
+ npm install
18
+ npm run dev
19
+ ```
20
+
21
+ Or scaffold for a specific target:
22
+
23
+ ```bash
24
+ npx juice create my-app --target cloudflare
25
+ ```
26
+
27
+ **Targets:** `bun` (default), `node`, `cloudflare`, `deno`
28
+
29
+ ## CLI
30
+
31
+ | Command | Description |
32
+ |---------|-------------|
33
+ | `juice create <name>` | Scaffold a new Juice app |
34
+ | `juice dev` | Start the Vite dev server |
35
+ | `juice build` | Production build (client + SSR) |
36
+
37
+ ## API
38
+
39
+ ### `juice/plugin`
40
+
41
+ The Vite plugin. Zero config.
42
+
43
+ ```ts
44
+ // vite.config.ts
45
+ import { defineConfig } from 'vite';
46
+ import juice from '@cmj/juice/plugin';
47
+
48
+ export default defineConfig({
49
+ plugins: [juice()],
50
+ });
51
+ ```
52
+
53
+ ### `juice/runtime`
54
+
55
+ The WinterCG-compliant edge runtime.
56
+
57
+ ```ts
58
+ // server.ts
59
+ import { createRouter } from '@cmj/juice/runtime';
60
+ import manifest from './dist/flight-manifest.json' with { type: 'json' };
61
+
62
+ const handler = createRouter(manifest);
63
+ // handler: (Request) => Promise<Response>
64
+ ```
65
+
66
+ ## How It Works
67
+
68
+ ```
69
+ Source (.tsx) → Vite Plugin → flight-manifest.json → Runtime → Response
70
+ ```
71
+
72
+ 1. **Compile:** The Vite plugin detects `'use client'` and `'use server'` directives, generates proxy modules, and emits a `flight-manifest.json`.
73
+ 2. **Serve:** The runtime reads the manifest and streams RSC responses using React 19's `renderToReadableStream`.
74
+ 3. **Deploy:** The `Request → Response` signature works on any WinterCG platform.
75
+
76
+ ## Features
77
+
78
+ - **React 19 RSC** — Server Components, Suspense, streaming SSR
79
+ - **Server Actions** — `'use server'` with FormData support
80
+ - **Zero config** — One plugin call, no magic files
81
+ - **Zero runtime deps** — Pure ESM, nothing to install at runtime
82
+ - **Multi-platform** — Bun, Node.js, Cloudflare Workers, Deno
83
+ - **Empathic errors** — "What-Why-How" error messages for fast debugging
84
+ - **HMR** — Full hot module replacement in development
85
+
86
+ ## License
87
+
88
+ MIT
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `juice dev` — starts the Vite dev server.
3
+ *
4
+ * Passes through any additional args to `vite dev`.
5
+ *
6
+ * @example
7
+ * ```
8
+ * juice dev
9
+ * juice dev --port 4000
10
+ * juice dev --host 0.0.0.0
11
+ * ```
12
+ */
13
+ export declare function runDev(extraArgs?: string[], cwd?: string): Promise<number>;
14
+ /**
15
+ * `juice build` — runs the Vite dual build.
16
+ *
17
+ * 1. Client build: `vite build` (produces client chunks + flight-manifest.json)
18
+ * 2. SSR build: `vite build --ssr server.ts` (produces server bundle)
19
+ *
20
+ * Passes through any additional args to both builds.
21
+ *
22
+ * @example
23
+ * ```
24
+ * juice build
25
+ * juice build --outDir dist/production
26
+ * ```
27
+ */
28
+ export declare function runBuild(extraArgs?: string[], cwd?: string): Promise<number>;
29
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AA6CA;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAC1B,SAAS,GAAE,MAAM,EAAO,EACxB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAC5B,SAAS,GAAE,MAAM,EAAO,EACxB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
@@ -0,0 +1,102 @@
1
+ // ─────────────────────────────────────────────────────────────────
2
+ // @cmj/juice — CLI Commands (dev / build)
3
+ // Thin wrappers around Vite's CLI. Zero overhead — stdio passthrough.
4
+ // ─────────────────────────────────────────────────────────────────
5
+ import { spawn } from 'node:child_process';
6
+ import { resolve } from 'node:path';
7
+ import { existsSync } from 'node:fs';
8
+ /**
9
+ * Find the local `vite` binary. Prefers the project's node_modules/.bin,
10
+ * falls back to `npx vite` if not found.
11
+ */
12
+ function findViteBin(cwd) {
13
+ const local = resolve(cwd, 'node_modules', '.bin', 'vite');
14
+ if (existsSync(local)) {
15
+ return { command: local, prefix: [] };
16
+ }
17
+ // Fallback: use npx to resolve vite
18
+ return { command: 'npx', prefix: ['vite'] };
19
+ }
20
+ /**
21
+ * Spawn a child process and return its exit code.
22
+ * Stdio is fully inherited — the user sees Vite's output directly.
23
+ */
24
+ function run(command, args, cwd) {
25
+ return new Promise((resolve, reject) => {
26
+ const child = spawn(command, args, {
27
+ cwd,
28
+ stdio: 'inherit',
29
+ shell: process.platform === 'win32',
30
+ });
31
+ child.on('error', reject);
32
+ child.on('close', (code) => resolve(code ?? 1));
33
+ });
34
+ }
35
+ // ── Public API ──────────────────────────────────────────────────
36
+ /**
37
+ * `juice dev` — starts the Vite dev server.
38
+ *
39
+ * Passes through any additional args to `vite dev`.
40
+ *
41
+ * @example
42
+ * ```
43
+ * juice dev
44
+ * juice dev --port 4000
45
+ * juice dev --host 0.0.0.0
46
+ * ```
47
+ */
48
+ export async function runDev(extraArgs = [], cwd = process.cwd()) {
49
+ const { command, prefix } = findViteBin(cwd);
50
+ const args = [...prefix, 'dev', ...extraArgs];
51
+ console.log('🧃 Starting dev server...\n');
52
+ return run(command, args, cwd);
53
+ }
54
+ /**
55
+ * `juice build` — runs the Vite dual build.
56
+ *
57
+ * 1. Client build: `vite build` (produces client chunks + flight-manifest.json)
58
+ * 2. SSR build: `vite build --ssr server.ts` (produces server bundle)
59
+ *
60
+ * Passes through any additional args to both builds.
61
+ *
62
+ * @example
63
+ * ```
64
+ * juice build
65
+ * juice build --outDir dist/production
66
+ * ```
67
+ */
68
+ export async function runBuild(extraArgs = [], cwd = process.cwd()) {
69
+ const { command, prefix } = findViteBin(cwd);
70
+ // Step 1: Client build
71
+ console.log('🧃 Building client...\n');
72
+ const clientCode = await run(command, [...prefix, 'build', ...extraArgs], cwd);
73
+ if (clientCode !== 0) {
74
+ console.error('\n🧃 Client build failed.\n');
75
+ return clientCode;
76
+ }
77
+ // Step 2: SSR build
78
+ console.log('\n🧃 Building server (SSR)...\n');
79
+ // Determine SSR entry — check common locations
80
+ const ssrEntry = findSSREntry(cwd);
81
+ const ssrCode = await run(command, [...prefix, 'build', '--ssr', ssrEntry, ...extraArgs], cwd);
82
+ if (ssrCode !== 0) {
83
+ console.error('\n🧃 SSR build failed.\n');
84
+ return ssrCode;
85
+ }
86
+ console.log('\n🧃 Build complete.\n');
87
+ return 0;
88
+ }
89
+ /**
90
+ * Find the SSR entry point. Checks common locations in order.
91
+ */
92
+ function findSSREntry(cwd) {
93
+ const candidates = ['server.ts', 'server.tsx', 'src/server.ts', 'src/entry-server.ts'];
94
+ for (const candidate of candidates) {
95
+ if (existsSync(resolve(cwd, candidate))) {
96
+ return candidate;
97
+ }
98
+ }
99
+ // Default — let Vite resolve it (will error with a clear message if missing)
100
+ return 'server.ts';
101
+ }
102
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { DeployTarget } from './templates.js';
2
+ export { DEPLOY_TARGETS, TARGET_LABELS, type DeployTarget } from './templates.js';
3
+ export declare class JuiceCreateError extends Error {
4
+ name: string;
5
+ }
6
+ /**
7
+ * Prompts the user to select a deployment target.
8
+ * Zero dependencies — raw readline.
9
+ */
10
+ export declare function promptTarget(): Promise<DeployTarget>;
11
+ export interface CreateAppOptions {
12
+ /** Working directory to create the project in. Defaults to `process.cwd()`. */
13
+ cwd?: string;
14
+ /** Deployment target. Defaults to `'bun'`. */
15
+ target?: DeployTarget;
16
+ }
17
+ export interface CreateAppResult {
18
+ /** Absolute path to the created directory. */
19
+ dir: string;
20
+ /** List of files created (relative to dir). */
21
+ files: string[];
22
+ /** Selected deployment target. */
23
+ target: DeployTarget;
24
+ }
25
+ /**
26
+ * Creates a new Juice app.
27
+ *
28
+ * ```ts
29
+ * import { createApp } from '@cmj/juice/create';
30
+ * const result = createApp('my-app', { target: 'bun' });
31
+ * // → result.files = ['package.json', 'tsconfig.json', ...]
32
+ * ```
33
+ */
34
+ export declare function createApp(name: string, options?: CreateAppOptions): CreateAppResult;
35
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAUlF,qBAAa,gBAAiB,SAAQ,KAAK;IAChC,IAAI,SAAsB;CACpC;AAkBD;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC,CA0C1D;AAID,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,kCAAkC;IAClC,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,GACzB,eAAe,CAmCjB"}
@@ -0,0 +1,108 @@
1
+ // ─────────────────────────────────────────────────────────────────
2
+ // @cmj/juice — CLI Scaffolder
3
+ // Creates a new Juice app directory with 5 minimal, typed files.
4
+ // Zero external dependencies — Node.js fs/path only.
5
+ // ─────────────────────────────────────────────────────────────────
6
+ import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
7
+ import { join, resolve } from 'node:path';
8
+ import { createInterface } from 'node:readline';
9
+ import { packageJson, tsconfig, viteConfig, serverEntry, homeRoute, DEPLOY_TARGETS, TARGET_LABELS, } from './templates.js';
10
+ export { DEPLOY_TARGETS, TARGET_LABELS } from './templates.js';
11
+ // ── Validation ──────────────────────────────────────────────────
12
+ /**
13
+ * Valid npm package name: lowercase, may include hyphens, dots,
14
+ * underscores, and scoped prefixes. No spaces, no uppercase.
15
+ */
16
+ const VALID_NAME = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
17
+ export class JuiceCreateError extends Error {
18
+ name = 'JuiceCreateError';
19
+ }
20
+ function validateName(name) {
21
+ if (!name || typeof name !== 'string') {
22
+ throw new JuiceCreateError('Project name is required.\n\n Usage: npx juice create <name>\n');
23
+ }
24
+ if (!VALID_NAME.test(name)) {
25
+ throw new JuiceCreateError(`Invalid project name "${name}".\n` +
26
+ ' Use lowercase letters, hyphens, and dots (e.g. my-app).\n');
27
+ }
28
+ }
29
+ // ── Interactive prompt ──────────────────────────────────────────
30
+ /**
31
+ * Prompts the user to select a deployment target.
32
+ * Zero dependencies — raw readline.
33
+ */
34
+ export async function promptTarget() {
35
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
36
+ console.log('\n 🧃 Where are you deploying?\n');
37
+ for (let i = 0; i < DEPLOY_TARGETS.length; i++) {
38
+ const target = DEPLOY_TARGETS[i];
39
+ const marker = i === 0 ? '●' : '○';
40
+ const label = TARGET_LABELS[target];
41
+ const suffix = i === 0 ? ' (default)' : '';
42
+ console.log(` ${marker} ${i + 1}. ${label}${suffix}`);
43
+ }
44
+ console.log();
45
+ return new Promise((resolve) => {
46
+ rl.question(' Enter 1–4 (or press Enter for Bun): ', (answer) => {
47
+ rl.close();
48
+ const trimmed = answer.trim();
49
+ if (!trimmed) {
50
+ resolve('bun');
51
+ return;
52
+ }
53
+ const index = parseInt(trimmed, 10) - 1;
54
+ if (index >= 0 && index < DEPLOY_TARGETS.length) {
55
+ resolve(DEPLOY_TARGETS[index]);
56
+ return;
57
+ }
58
+ // Try matching by name
59
+ const lower = trimmed.toLowerCase();
60
+ const match = DEPLOY_TARGETS.find((t) => t === lower);
61
+ if (match) {
62
+ resolve(match);
63
+ return;
64
+ }
65
+ // Default to bun on invalid input
66
+ console.log(` Unknown target "${trimmed}", using Bun.\n`);
67
+ resolve('bun');
68
+ });
69
+ });
70
+ }
71
+ /**
72
+ * Creates a new Juice app.
73
+ *
74
+ * ```ts
75
+ * import { createApp } from '@cmj/juice/create';
76
+ * const result = createApp('my-app', { target: 'bun' });
77
+ * // → result.files = ['package.json', 'tsconfig.json', ...]
78
+ * ```
79
+ */
80
+ export function createApp(name, options) {
81
+ validateName(name);
82
+ const cwd = options?.cwd ?? process.cwd();
83
+ const target = options?.target ?? 'bun';
84
+ const dir = resolve(cwd, name);
85
+ if (existsSync(dir)) {
86
+ throw new JuiceCreateError(`Directory "${name}" already exists.\n` +
87
+ ' Choose a different name or remove the existing directory.\n');
88
+ }
89
+ // Create directory structure
90
+ mkdirSync(join(dir, 'app', 'routes'), { recursive: true });
91
+ // Write files
92
+ const files = [
93
+ ['package.json', packageJson({ name, target })],
94
+ ['tsconfig.json', tsconfig()],
95
+ ['vite.config.ts', viteConfig()],
96
+ ['server.ts', serverEntry(target)],
97
+ ['app/routes/home.tsx', homeRoute()],
98
+ ];
99
+ for (const [path, content] of files) {
100
+ writeFileSync(join(dir, path), content, 'utf-8');
101
+ }
102
+ return {
103
+ dir,
104
+ files: files.map(([path]) => path),
105
+ target,
106
+ };
107
+ }
108
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ // ─────────────────────────────────────────────────────────────────
3
+ // @cmj/juice — CLI Entry Point
4
+ // Usage:
5
+ // juice create <name> [--target bun|node|cloudflare|deno]
6
+ // juice dev [--port N] [--host]
7
+ // juice build
8
+ // ─────────────────────────────────────────────────────────────────
9
+ import { createApp, promptTarget, JuiceCreateError, TARGET_LABELS, DEPLOY_TARGETS } from './create.js';
10
+ import { runDev, runBuild } from './commands.js';
11
+ const args = process.argv.slice(2);
12
+ const command = args[0];
13
+ /**
14
+ * Parse `--target <value>` from args.
15
+ * Returns undefined if not provided (will prompt interactively).
16
+ */
17
+ function parseTarget(argv) {
18
+ const idx = argv.indexOf('--target');
19
+ if (idx === -1)
20
+ return undefined;
21
+ const value = argv[idx + 1]?.toLowerCase();
22
+ if (!value || !DEPLOY_TARGETS.includes(value)) {
23
+ console.error(`\n 🧃 Invalid target "${value ?? '(empty)'}".` +
24
+ `\n Valid targets: ${DEPLOY_TARGETS.join(', ')}\n`);
25
+ process.exit(1);
26
+ }
27
+ return value;
28
+ }
29
+ // ── Command: create ─────────────────────────────────────────────
30
+ if (command === 'create') {
31
+ // Filter out --target and its value to find the project name
32
+ const positional = args.slice(1).filter((a, i, arr) => a !== '--target' && arr[i - 1] !== '--target');
33
+ const name = positional[0];
34
+ if (!name) {
35
+ console.error('\n 🧃 Project name is required.\n\n Usage: npx juice create <name>\n');
36
+ process.exit(1);
37
+ }
38
+ try {
39
+ // Use --target flag if provided, otherwise prompt interactively
40
+ const flagTarget = parseTarget(args);
41
+ const target = flagTarget ?? await promptTarget();
42
+ const result = createApp(name, { target });
43
+ console.log(`\n 🧃 Created ${result.files.length} files in ./${name}/ (${TARGET_LABELS[result.target]})\n`);
44
+ for (const file of result.files) {
45
+ console.log(` ${file}`);
46
+ }
47
+ const install = result.target === 'bun' ? 'bun install' : 'npm install';
48
+ const dev = result.target === 'bun' ? 'bun run dev' : 'npm run dev';
49
+ console.log(`\n Next steps:\n`);
50
+ console.log(` cd ${name}`);
51
+ console.log(` ${install}`);
52
+ console.log(` ${dev}\n`);
53
+ }
54
+ catch (error) {
55
+ if (error instanceof JuiceCreateError) {
56
+ console.error(`\n 🧃 ${error.message}`);
57
+ process.exit(1);
58
+ }
59
+ throw error;
60
+ }
61
+ // ── Command: dev ──────────────────────────────────────────────
62
+ }
63
+ else if (command === 'dev') {
64
+ const extraArgs = args.slice(1);
65
+ const code = await runDev(extraArgs);
66
+ process.exit(code);
67
+ // ── Command: build ────────────────────────────────────────────
68
+ }
69
+ else if (command === 'build') {
70
+ const extraArgs = args.slice(1);
71
+ const code = await runBuild(extraArgs);
72
+ process.exit(code);
73
+ // ── Help / unknown ────────────────────────────────────────────
74
+ }
75
+ else {
76
+ console.log(`
77
+ 🧃 Juice CLI
78
+
79
+ Commands:
80
+ juice create <name> Scaffold a new Juice app
81
+ juice create <name> --target T Skip prompt (T: bun|node|cloudflare|deno)
82
+ juice dev [vite-args...] Start the dev server
83
+ juice build [vite-args...] Build for production (client + SSR)
84
+
85
+ Examples:
86
+ npx juice create my-app
87
+ npx juice create my-app --target cloudflare
88
+ juice dev
89
+ juice dev --port 4000
90
+ juice build
91
+ `);
92
+ if (command && command !== '--help' && command !== '-h') {
93
+ console.error(` Unknown command: "${command}"\n`);
94
+ process.exit(1);
95
+ }
96
+ }
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export type DeployTarget = 'bun' | 'node' | 'cloudflare' | 'deno';
2
+ export declare const DEPLOY_TARGETS: readonly DeployTarget[];
3
+ export declare const TARGET_LABELS: Record<DeployTarget, string>;
4
+ interface TemplateContext {
5
+ name: string;
6
+ target: DeployTarget;
7
+ }
8
+ export declare function packageJson({ name, target }: TemplateContext): string;
9
+ export declare function tsconfig(): string;
10
+ export declare function viteConfig(): string;
11
+ export declare function serverEntry(target: DeployTarget): string;
12
+ export declare function homeRoute(): string;
13
+ export {};
14
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;AAElE,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAAmD,CAAC;AAEtG,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAKtD,CAAC;AAEF,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,eAAe,GAAG,MAAM,CAqCrE;AAED,wBAAgB,QAAQ,IAAI,MAAM,CAiBjC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AA8DD,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAExD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAmBlC"}