@cloudwerk/cli 0.9.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 +124 -33
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -324,7 +324,8 @@ async function build(pathArg, options) {
324
324
  hydrationEndpoint: "/__cloudwerk",
325
325
  renderer,
326
326
  publicDir: cloudwerkConfig.publicDir ?? "public",
327
- root: cwd
327
+ root: cwd,
328
+ isProduction: true
328
329
  });
329
330
  const tempEntryPath = path2.join(tempDir, "_server-entry.ts");
330
331
  fs2.writeFileSync(tempEntryPath, serverEntryCode);
@@ -468,13 +469,102 @@ function formatSize(bytes) {
468
469
  return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
469
470
  }
470
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
+
471
561
  // src/commands/config.ts
472
562
  import * as readline from "readline";
473
563
  import pc2 from "picocolors";
474
564
 
475
565
  // src/utils/configWriter.ts
476
- import * as fs3 from "fs";
477
- import * as path3 from "path";
566
+ import * as fs4 from "fs";
567
+ import * as path4 from "path";
478
568
  import { loadConfig as loadConfig2 } from "@cloudwerk/core/build";
479
569
  var CONFIG_FILE_NAMES = [
480
570
  "cloudwerk.config.ts",
@@ -483,8 +573,8 @@ var CONFIG_FILE_NAMES = [
483
573
  ];
484
574
  function findConfigFile(cwd) {
485
575
  for (const filename of CONFIG_FILE_NAMES) {
486
- const configPath = path3.join(cwd, filename);
487
- if (fs3.existsSync(configPath)) {
576
+ const configPath = path4.join(cwd, filename);
577
+ if (fs4.existsSync(configPath)) {
488
578
  return configPath;
489
579
  }
490
580
  }
@@ -495,7 +585,7 @@ function readCloudwerkConfig(cwd) {
495
585
  if (!configPath) {
496
586
  return {};
497
587
  }
498
- const content = fs3.readFileSync(configPath, "utf-8");
588
+ const content = fs4.readFileSync(configPath, "utf-8");
499
589
  return parseConfigContent(content);
500
590
  }
501
591
  function parseConfigContent(content) {
@@ -516,16 +606,16 @@ function parseConfigContent(content) {
516
606
  function writeCloudwerkConfig(cwd, updates) {
517
607
  const configPath = findConfigFile(cwd);
518
608
  if (!configPath) {
519
- const newConfigPath = path3.join(cwd, "cloudwerk.config.ts");
609
+ const newConfigPath = path4.join(cwd, "cloudwerk.config.ts");
520
610
  const content2 = generateMinimalConfig(updates);
521
- fs3.writeFileSync(newConfigPath, content2, "utf-8");
611
+ fs4.writeFileSync(newConfigPath, content2, "utf-8");
522
612
  return true;
523
613
  }
524
- let content = fs3.readFileSync(configPath, "utf-8");
614
+ let content = fs4.readFileSync(configPath, "utf-8");
525
615
  if (updates.renderer !== void 0) {
526
616
  content = updateRenderer(content, updates.renderer);
527
617
  }
528
- fs3.writeFileSync(configPath, content, "utf-8");
618
+ fs4.writeFileSync(configPath, content, "utf-8");
529
619
  return true;
530
620
  }
531
621
  function updateRenderer(content, renderer) {
@@ -594,11 +684,11 @@ function generateMinimalConfig(updates) {
594
684
  }
595
685
 
596
686
  // src/utils/tsconfigWriter.ts
597
- import * as fs4 from "fs";
598
- import * as path4 from "path";
687
+ import * as fs5 from "fs";
688
+ import * as path5 from "path";
599
689
  function findTsConfig(cwd) {
600
- const tsconfigPath = path4.join(cwd, "tsconfig.json");
601
- if (fs4.existsSync(tsconfigPath)) {
690
+ const tsconfigPath = path5.join(cwd, "tsconfig.json");
691
+ if (fs5.existsSync(tsconfigPath)) {
602
692
  return tsconfigPath;
603
693
  }
604
694
  return null;
@@ -609,7 +699,7 @@ function readTsConfig(cwd) {
609
699
  return {};
610
700
  }
611
701
  try {
612
- const content = fs4.readFileSync(tsconfigPath, "utf-8");
702
+ const content = fs5.readFileSync(tsconfigPath, "utf-8");
613
703
  const config = JSON.parse(content);
614
704
  return {
615
705
  jsxImportSource: config.compilerOptions?.jsxImportSource,
@@ -625,7 +715,7 @@ function updateTsConfig(cwd, updates) {
625
715
  return false;
626
716
  }
627
717
  try {
628
- const content = fs4.readFileSync(tsconfigPath, "utf-8");
718
+ const content = fs5.readFileSync(tsconfigPath, "utf-8");
629
719
  const config = JSON.parse(content);
630
720
  if (!config.compilerOptions) {
631
721
  config.compilerOptions = {};
@@ -633,7 +723,7 @@ function updateTsConfig(cwd, updates) {
633
723
  if (updates.jsxImportSource !== void 0) {
634
724
  config.compilerOptions.jsxImportSource = updates.jsxImportSource;
635
725
  }
636
- fs4.writeFileSync(tsconfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
726
+ fs5.writeFileSync(tsconfigPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
637
727
  return true;
638
728
  } catch {
639
729
  return false;
@@ -641,8 +731,8 @@ function updateTsConfig(cwd, updates) {
641
731
  }
642
732
 
643
733
  // src/utils/dependencyManager.ts
644
- import * as fs5 from "fs";
645
- import * as path5 from "path";
734
+ import * as fs6 from "fs";
735
+ import * as path6 from "path";
646
736
  import { execFileSync } from "child_process";
647
737
  var REACT_SPECIFIC_LIBRARIES = [
648
738
  "@tanstack/react-query",
@@ -683,22 +773,22 @@ var REACT_SPECIFIC_LIBRARIES = [
683
773
  "@use-gesture/react"
684
774
  ];
685
775
  function detectPackageManager(cwd) {
686
- if (fs5.existsSync(path5.join(cwd, "pnpm-lock.yaml"))) {
776
+ if (fs6.existsSync(path6.join(cwd, "pnpm-lock.yaml"))) {
687
777
  return "pnpm";
688
778
  }
689
- if (fs5.existsSync(path5.join(cwd, "yarn.lock"))) {
779
+ if (fs6.existsSync(path6.join(cwd, "yarn.lock"))) {
690
780
  return "yarn";
691
781
  }
692
- if (fs5.existsSync(path5.join(cwd, "bun.lockb"))) {
782
+ if (fs6.existsSync(path6.join(cwd, "bun.lockb"))) {
693
783
  return "bun";
694
784
  }
695
- if (fs5.existsSync(path5.join(cwd, "package-lock.json"))) {
785
+ if (fs6.existsSync(path6.join(cwd, "package-lock.json"))) {
696
786
  return "npm";
697
787
  }
698
- const packageJsonPath = path5.join(cwd, "package.json");
699
- if (fs5.existsSync(packageJsonPath)) {
788
+ const packageJsonPath = path6.join(cwd, "package.json");
789
+ if (fs6.existsSync(packageJsonPath)) {
700
790
  try {
701
- const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
791
+ const packageJson = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
702
792
  const pm = packageJson.packageManager;
703
793
  if (pm) {
704
794
  if (pm.startsWith("pnpm")) return "pnpm";
@@ -712,15 +802,15 @@ function detectPackageManager(cwd) {
712
802
  return "npm";
713
803
  }
714
804
  function getInstalledDependencies(cwd) {
715
- const packageJsonPath = path5.join(cwd, "package.json");
716
- if (!fs5.existsSync(packageJsonPath)) {
805
+ const packageJsonPath = path6.join(cwd, "package.json");
806
+ if (!fs6.existsSync(packageJsonPath)) {
717
807
  return {
718
808
  dependencies: {},
719
809
  devDependencies: {}
720
810
  };
721
811
  }
722
812
  try {
723
- const content = fs5.readFileSync(packageJsonPath, "utf-8");
813
+ const content = fs6.readFileSync(packageJsonPath, "utf-8");
724
814
  const packageJson = JSON.parse(content);
725
815
  return {
726
816
  dependencies: packageJson.dependencies || {},
@@ -1043,16 +1133,16 @@ async function askConfirmation(question, defaultValue) {
1043
1133
  output: process.stdout
1044
1134
  });
1045
1135
  const hint = defaultValue ? "Y/n" : "y/N";
1046
- return new Promise((resolve3) => {
1136
+ return new Promise((resolve4) => {
1047
1137
  rl.question(pc2.cyan("? ") + question + pc2.dim(` (${hint}) `), (answer) => {
1048
1138
  rl.close();
1049
1139
  const normalized = answer.trim().toLowerCase();
1050
1140
  if (normalized === "") {
1051
- resolve3(defaultValue);
1141
+ resolve4(defaultValue);
1052
1142
  } else if (normalized === "y" || normalized === "yes") {
1053
- resolve3(true);
1143
+ resolve4(true);
1054
1144
  } else {
1055
- resolve3(false);
1145
+ resolve4(false);
1056
1146
  }
1057
1147
  });
1058
1148
  });
@@ -1062,6 +1152,7 @@ async function askConfirmation(question, defaultValue) {
1062
1152
  program.name("cloudwerk").description("Cloudwerk CLI - Build and deploy full-stack apps to Cloudflare").version(VERSION);
1063
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);
1064
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);
1065
1156
  var configCmd = program.command("config").description("Manage Cloudwerk configuration");
1066
1157
  configCmd.command("get <key>").description("Get a configuration value").action(configGet);
1067
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.9.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.9.0",
32
31
  "@cloudwerk/ui": "^0.9.0",
33
- "@cloudwerk/vite-plugin": "^0.3.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",