@cloudwerk/cli 0.8.0 → 0.10.0

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 (2) hide show
  1. package/dist/index.js +127 -33
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -323,7 +323,9 @@ async function build(pathArg, options) {
323
323
  verbose,
324
324
  hydrationEndpoint: "/__cloudwerk",
325
325
  renderer,
326
- root: cwd
326
+ publicDir: cloudwerkConfig.publicDir ?? "public",
327
+ root: cwd,
328
+ isProduction: true
327
329
  });
328
330
  const tempEntryPath = path2.join(tempDir, "_server-entry.ts");
329
331
  fs2.writeFileSync(tempEntryPath, serverEntryCode);
@@ -364,6 +366,8 @@ async function build(pathArg, options) {
364
366
  root: cwd,
365
367
  mode: "production",
366
368
  logLevel: verbose ? "info" : "warn",
369
+ // Disable publicDir for server build - static assets are already in dist/static/ from client build
370
+ publicDir: false,
367
371
  plugins: [
368
372
  cloudwerk2({ verbose })
369
373
  ],
@@ -465,13 +469,102 @@ function formatSize(bytes) {
465
469
  return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
466
470
  }
467
471
 
472
+ // src/commands/deploy.ts
473
+ import * as path3 from "path";
474
+ import * as fs3 from "fs";
475
+ import { spawn } from "child_process";
476
+ async function deploy(pathArg, options) {
477
+ const verbose = options.verbose ?? false;
478
+ const logger = createLogger(verbose);
479
+ try {
480
+ const cwd = pathArg ? path3.resolve(process.cwd(), pathArg) : process.cwd();
481
+ if (!fs3.existsSync(cwd)) {
482
+ throw new CliError(
483
+ `Directory does not exist: ${cwd}`,
484
+ "ENOENT",
485
+ `Make sure the path exists and try again.`
486
+ );
487
+ }
488
+ logger.debug(`Working directory: ${cwd}`);
489
+ const wranglerPath = path3.join(cwd, "wrangler.toml");
490
+ if (!fs3.existsSync(wranglerPath)) {
491
+ throw new CliError(
492
+ `wrangler.toml not found in ${cwd}`,
493
+ "ENOENT",
494
+ `Create a wrangler.toml file or run this command from a directory containing one.`
495
+ );
496
+ }
497
+ logger.debug(`Found wrangler.toml: ${wranglerPath}`);
498
+ if (!options.skipBuild) {
499
+ logger.info("Building project...");
500
+ await build(pathArg, {
501
+ config: options.config,
502
+ verbose: options.verbose
503
+ });
504
+ console.log();
505
+ }
506
+ const args = ["wrangler", "deploy"];
507
+ if (options.env) {
508
+ args.push("--env", options.env);
509
+ }
510
+ if (options.dryRun) {
511
+ args.push("--dry-run");
512
+ }
513
+ const envLabel = options.env ? ` to ${options.env}` : "";
514
+ const dryRunLabel = options.dryRun ? " (dry run)" : "";
515
+ logger.info(`Deploying${envLabel}${dryRunLabel}...`);
516
+ logger.debug(`Running: npx ${args.join(" ")}`);
517
+ const exitCode = await runCommand(args, cwd);
518
+ if (exitCode !== 0) {
519
+ throw new CliError(
520
+ `Deployment failed with exit code ${exitCode}`,
521
+ "EDEPLOY",
522
+ `Check the wrangler output above for details.`
523
+ );
524
+ }
525
+ if (!options.dryRun) {
526
+ logger.success("Deployment complete!");
527
+ } else {
528
+ logger.success("Dry run complete!");
529
+ }
530
+ } catch (error) {
531
+ if (error instanceof CliError) {
532
+ printError(error.message, error.suggestion);
533
+ process.exit(1);
534
+ }
535
+ if (error instanceof Error) {
536
+ printError(error.message);
537
+ if (verbose && error.stack) {
538
+ console.log(error.stack);
539
+ }
540
+ process.exit(1);
541
+ }
542
+ printError(String(error));
543
+ process.exit(1);
544
+ }
545
+ }
546
+ function runCommand(args, cwd) {
547
+ return new Promise((resolve4, reject) => {
548
+ const child = spawn("npx", args, {
549
+ cwd,
550
+ stdio: "inherit"
551
+ });
552
+ child.on("error", (error) => {
553
+ reject(error);
554
+ });
555
+ child.on("close", (code) => {
556
+ resolve4(code ?? 0);
557
+ });
558
+ });
559
+ }
560
+
468
561
  // src/commands/config.ts
469
562
  import * as readline from "readline";
470
563
  import pc2 from "picocolors";
471
564
 
472
565
  // src/utils/configWriter.ts
473
- import * as fs3 from "fs";
474
- import * as path3 from "path";
566
+ import * as fs4 from "fs";
567
+ import * as path4 from "path";
475
568
  import { loadConfig as loadConfig2 } from "@cloudwerk/core/build";
476
569
  var CONFIG_FILE_NAMES = [
477
570
  "cloudwerk.config.ts",
@@ -480,8 +573,8 @@ var CONFIG_FILE_NAMES = [
480
573
  ];
481
574
  function findConfigFile(cwd) {
482
575
  for (const filename of CONFIG_FILE_NAMES) {
483
- const configPath = path3.join(cwd, filename);
484
- if (fs3.existsSync(configPath)) {
576
+ const configPath = path4.join(cwd, filename);
577
+ if (fs4.existsSync(configPath)) {
485
578
  return configPath;
486
579
  }
487
580
  }
@@ -492,7 +585,7 @@ function readCloudwerkConfig(cwd) {
492
585
  if (!configPath) {
493
586
  return {};
494
587
  }
495
- const content = fs3.readFileSync(configPath, "utf-8");
588
+ const content = fs4.readFileSync(configPath, "utf-8");
496
589
  return parseConfigContent(content);
497
590
  }
498
591
  function parseConfigContent(content) {
@@ -513,16 +606,16 @@ function parseConfigContent(content) {
513
606
  function writeCloudwerkConfig(cwd, updates) {
514
607
  const configPath = findConfigFile(cwd);
515
608
  if (!configPath) {
516
- const newConfigPath = path3.join(cwd, "cloudwerk.config.ts");
609
+ const newConfigPath = path4.join(cwd, "cloudwerk.config.ts");
517
610
  const content2 = generateMinimalConfig(updates);
518
- fs3.writeFileSync(newConfigPath, content2, "utf-8");
611
+ fs4.writeFileSync(newConfigPath, content2, "utf-8");
519
612
  return true;
520
613
  }
521
- let content = fs3.readFileSync(configPath, "utf-8");
614
+ let content = fs4.readFileSync(configPath, "utf-8");
522
615
  if (updates.renderer !== void 0) {
523
616
  content = updateRenderer(content, updates.renderer);
524
617
  }
525
- fs3.writeFileSync(configPath, content, "utf-8");
618
+ fs4.writeFileSync(configPath, content, "utf-8");
526
619
  return true;
527
620
  }
528
621
  function updateRenderer(content, renderer) {
@@ -591,11 +684,11 @@ function generateMinimalConfig(updates) {
591
684
  }
592
685
 
593
686
  // src/utils/tsconfigWriter.ts
594
- import * as fs4 from "fs";
595
- import * as path4 from "path";
687
+ import * as fs5 from "fs";
688
+ import * as path5 from "path";
596
689
  function findTsConfig(cwd) {
597
- const tsconfigPath = path4.join(cwd, "tsconfig.json");
598
- if (fs4.existsSync(tsconfigPath)) {
690
+ const tsconfigPath = path5.join(cwd, "tsconfig.json");
691
+ if (fs5.existsSync(tsconfigPath)) {
599
692
  return tsconfigPath;
600
693
  }
601
694
  return null;
@@ -606,7 +699,7 @@ function readTsConfig(cwd) {
606
699
  return {};
607
700
  }
608
701
  try {
609
- const content = fs4.readFileSync(tsconfigPath, "utf-8");
702
+ const content = fs5.readFileSync(tsconfigPath, "utf-8");
610
703
  const config = JSON.parse(content);
611
704
  return {
612
705
  jsxImportSource: config.compilerOptions?.jsxImportSource,
@@ -622,7 +715,7 @@ function updateTsConfig(cwd, updates) {
622
715
  return false;
623
716
  }
624
717
  try {
625
- const content = fs4.readFileSync(tsconfigPath, "utf-8");
718
+ const content = fs5.readFileSync(tsconfigPath, "utf-8");
626
719
  const config = JSON.parse(content);
627
720
  if (!config.compilerOptions) {
628
721
  config.compilerOptions = {};
@@ -630,7 +723,7 @@ function updateTsConfig(cwd, updates) {
630
723
  if (updates.jsxImportSource !== void 0) {
631
724
  config.compilerOptions.jsxImportSource = updates.jsxImportSource;
632
725
  }
633
- fs4.writeFileSync(tsconfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
726
+ fs5.writeFileSync(tsconfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
634
727
  return true;
635
728
  } catch {
636
729
  return false;
@@ -638,8 +731,8 @@ function updateTsConfig(cwd, updates) {
638
731
  }
639
732
 
640
733
  // src/utils/dependencyManager.ts
641
- import * as fs5 from "fs";
642
- import * as path5 from "path";
734
+ import * as fs6 from "fs";
735
+ import * as path6 from "path";
643
736
  import { execFileSync } from "child_process";
644
737
  var REACT_SPECIFIC_LIBRARIES = [
645
738
  "@tanstack/react-query",
@@ -680,22 +773,22 @@ var REACT_SPECIFIC_LIBRARIES = [
680
773
  "@use-gesture/react"
681
774
  ];
682
775
  function detectPackageManager(cwd) {
683
- if (fs5.existsSync(path5.join(cwd, "pnpm-lock.yaml"))) {
776
+ if (fs6.existsSync(path6.join(cwd, "pnpm-lock.yaml"))) {
684
777
  return "pnpm";
685
778
  }
686
- if (fs5.existsSync(path5.join(cwd, "yarn.lock"))) {
779
+ if (fs6.existsSync(path6.join(cwd, "yarn.lock"))) {
687
780
  return "yarn";
688
781
  }
689
- if (fs5.existsSync(path5.join(cwd, "bun.lockb"))) {
782
+ if (fs6.existsSync(path6.join(cwd, "bun.lockb"))) {
690
783
  return "bun";
691
784
  }
692
- if (fs5.existsSync(path5.join(cwd, "package-lock.json"))) {
785
+ if (fs6.existsSync(path6.join(cwd, "package-lock.json"))) {
693
786
  return "npm";
694
787
  }
695
- const packageJsonPath = path5.join(cwd, "package.json");
696
- if (fs5.existsSync(packageJsonPath)) {
788
+ const packageJsonPath = path6.join(cwd, "package.json");
789
+ if (fs6.existsSync(packageJsonPath)) {
697
790
  try {
698
- const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
791
+ const packageJson = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
699
792
  const pm = packageJson.packageManager;
700
793
  if (pm) {
701
794
  if (pm.startsWith("pnpm")) return "pnpm";
@@ -709,15 +802,15 @@ function detectPackageManager(cwd) {
709
802
  return "npm";
710
803
  }
711
804
  function getInstalledDependencies(cwd) {
712
- const packageJsonPath = path5.join(cwd, "package.json");
713
- if (!fs5.existsSync(packageJsonPath)) {
805
+ const packageJsonPath = path6.join(cwd, "package.json");
806
+ if (!fs6.existsSync(packageJsonPath)) {
714
807
  return {
715
808
  dependencies: {},
716
809
  devDependencies: {}
717
810
  };
718
811
  }
719
812
  try {
720
- const content = fs5.readFileSync(packageJsonPath, "utf-8");
813
+ const content = fs6.readFileSync(packageJsonPath, "utf-8");
721
814
  const packageJson = JSON.parse(content);
722
815
  return {
723
816
  dependencies: packageJson.dependencies || {},
@@ -1040,16 +1133,16 @@ async function askConfirmation(question, defaultValue) {
1040
1133
  output: process.stdout
1041
1134
  });
1042
1135
  const hint = defaultValue ? "Y/n" : "y/N";
1043
- return new Promise((resolve3) => {
1136
+ return new Promise((resolve4) => {
1044
1137
  rl.question(pc2.cyan("? ") + question + pc2.dim(` (${hint}) `), (answer) => {
1045
1138
  rl.close();
1046
1139
  const normalized = answer.trim().toLowerCase();
1047
1140
  if (normalized === "") {
1048
- resolve3(defaultValue);
1141
+ resolve4(defaultValue);
1049
1142
  } else if (normalized === "y" || normalized === "yes") {
1050
- resolve3(true);
1143
+ resolve4(true);
1051
1144
  } else {
1052
- resolve3(false);
1145
+ resolve4(false);
1053
1146
  }
1054
1147
  });
1055
1148
  });
@@ -1059,6 +1152,7 @@ async function askConfirmation(question, defaultValue) {
1059
1152
  program.name("cloudwerk").description("Cloudwerk CLI - Build and deploy full-stack apps to Cloudflare").version(VERSION);
1060
1153
  program.command("dev [path]").description("Start development server").option("-p, --port <number>", "Port to listen on", String(DEFAULT_PORT)).option("-H, --host <host>", "Host to bind", DEFAULT_HOST).option("-c, --config <path>", "Path to config file").option("--verbose", "Enable verbose logging").action(dev);
1061
1154
  program.command("build [path]").description("Build project for production deployment to Cloudflare Workers").option("-o, --output <dir>", "Output directory", "./dist").option("--ssg", "Generate static pages for routes with rendering: static").option("--minify", "Minify bundles (default: true)").option("--no-minify", "Disable minification").option("--sourcemap", "Generate source maps").option("-c, --config <path>", "Path to config file").option("--verbose", "Enable verbose logging").action(build);
1155
+ program.command("deploy [path]").description("Deploy to Cloudflare Workers").option("-e, --env <environment>", "Environment to deploy to").option("--dry-run", "Preview deployment without executing").option("--skip-build", "Skip the build step").option("-c, --config <path>", "Path to config file").option("--verbose", "Enable verbose logging").action(deploy);
1062
1156
  var configCmd = program.command("config").description("Manage Cloudwerk configuration");
1063
1157
  configCmd.command("get <key>").description("Get a configuration value").action(configGet);
1064
1158
  configCmd.command("set <key> <value>").description("Set a configuration value").action(configSet);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudwerk/cli",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Dev server, build, deploy commands for Cloudwerk",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,9 +28,9 @@
28
28
  "esbuild": "^0.25.0",
29
29
  "picocolors": "^1.1.0",
30
30
  "vite": "^6.0.0",
31
- "@cloudwerk/core": "^0.8.0",
32
- "@cloudwerk/ui": "^0.8.0",
33
- "@cloudwerk/vite-plugin": "^0.2.0"
31
+ "@cloudwerk/ui": "^0.9.0",
32
+ "@cloudwerk/vite-plugin": "^0.4.0",
33
+ "@cloudwerk/core": "^0.9.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^20.0.0",