@cedarjs/cli 4.2.0 → 4.2.1-next.258

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 (153) hide show
  1. package/dist/cfw.js +8 -6
  2. package/dist/commands/build/buildHandler.js +43 -42
  3. package/dist/commands/build/buildPackagesTask.js +6 -6
  4. package/dist/commands/build.js +7 -1
  5. package/dist/commands/deploy/baremetal/SshExecutor.js +13 -4
  6. package/dist/commands/deploy/baremetal/baremetalHandler.js +117 -65
  7. package/dist/commands/deploy/baremetal.js +24 -3
  8. package/dist/commands/deploy/flightcontrolHandler.js +16 -14
  9. package/dist/commands/deploy/helpers/deployHandler.js +10 -5
  10. package/dist/commands/deploy/packing/nft.js +1 -2
  11. package/dist/commands/deploy/render.js +1 -1
  12. package/dist/commands/deploy/renderHandler.js +22 -12
  13. package/dist/commands/deploy/serverlessHandler.js +67 -25
  14. package/dist/commands/destroy/component/component.js +2 -3
  15. package/dist/commands/destroy/directive/directive.js +1 -3
  16. package/dist/commands/destroy/directive/directiveHandler.js +2 -4
  17. package/dist/commands/destroy/function/function.js +1 -3
  18. package/dist/commands/destroy/handlerHelpers.js +16 -16
  19. package/dist/commands/destroy/helpers.js +8 -2
  20. package/dist/commands/destroy/layout/layout.js +1 -2
  21. package/dist/commands/destroy/page/pageHandler.js +1 -1
  22. package/dist/commands/destroy/scaffold/scaffoldHandler.js +28 -9
  23. package/dist/commands/destroy/sdl/sdlHandler.js +1 -1
  24. package/dist/commands/dev/devHandler.js +25 -25
  25. package/dist/commands/dev.js +3 -0
  26. package/dist/commands/experimental/live-queries/liveQueriesHandler.js +110 -4
  27. package/dist/commands/experimental/setupInngest.js +1 -1
  28. package/dist/commands/experimental/setupInngestHandler.js +12 -11
  29. package/dist/commands/experimental/setupOpentelemetry.js +1 -1
  30. package/dist/commands/experimental/setupOpentelemetryHandler.js +11 -7
  31. package/dist/commands/experimental/setupReactCompiler.js +1 -1
  32. package/dist/commands/experimental/setupReactCompilerHandler.js +45 -30
  33. package/dist/commands/experimental/setupRscHandler.js +14 -11
  34. package/dist/commands/experimental/setupStreamingSsr.js +1 -1
  35. package/dist/commands/experimental/setupStreamingSsrHandler.js +46 -31
  36. package/dist/commands/experimental/templates/rsc/Document.tsx.template +1 -1
  37. package/dist/commands/experimental/templates/rsc/entry.client.tsx.template +8 -8
  38. package/dist/commands/experimental/templates/streamingSsr/Document.tsx.template +1 -1
  39. package/dist/commands/experimental/templates/streamingSsr/entry.client.tsx.template +6 -6
  40. package/dist/commands/experimental/util.js +3 -2
  41. package/dist/commands/generate/cell/cellHandler.js +22 -21
  42. package/dist/commands/generate/component/componentHandler.js +14 -16
  43. package/dist/commands/generate/dataMigration/dataMigration.js +24 -13
  44. package/dist/commands/generate/dbAuth/dbAuth.js +1 -0
  45. package/dist/commands/generate/dbAuth/dbAuthHandler.js +40 -30
  46. package/dist/commands/generate/directive/directiveHandler.js +12 -14
  47. package/dist/commands/generate/function/function.js +1 -0
  48. package/dist/commands/generate/function/functionHandler.js +12 -17
  49. package/dist/commands/generate/helpers.js +17 -17
  50. package/dist/commands/generate/job/job.js +1 -0
  51. package/dist/commands/generate/job/jobHandler.js +15 -17
  52. package/dist/commands/generate/layout/layoutHandler.js +13 -16
  53. package/dist/commands/generate/model/model.js +1 -0
  54. package/dist/commands/generate/model/modelHandler.js +9 -3
  55. package/dist/commands/generate/ogImage/ogImage.js +1 -0
  56. package/dist/commands/generate/ogImage/ogImageHandler.js +16 -9
  57. package/dist/commands/generate/package/packageHandler.js +32 -49
  58. package/dist/commands/generate/page/pageHandler.js +25 -22
  59. package/dist/commands/generate/realtime/realtime.js +1 -1
  60. package/dist/commands/generate/realtime/realtimeHandler.js +46 -20
  61. package/dist/commands/generate/scaffold/scaffold.js +1 -0
  62. package/dist/commands/generate/scaffold/scaffoldHandler.js +35 -27
  63. package/dist/commands/generate/script/script.js +1 -0
  64. package/dist/commands/generate/script/templates/tsconfig.json.template +14 -0
  65. package/dist/commands/generate/sdl/sdl.js +4 -3
  66. package/dist/commands/generate/sdl/sdlHandler.js +38 -18
  67. package/dist/commands/generate/secret/secret.js +19 -19
  68. package/dist/commands/generate/service/service.js +5 -5
  69. package/dist/commands/generate/service/serviceHandler.js +59 -22
  70. package/dist/commands/generate/yargsCommandHelpers.js +6 -1
  71. package/dist/commands/generate/yargsHandlerHelpers.js +18 -10
  72. package/dist/commands/generate.js +3 -10
  73. package/dist/commands/jobsHandler.js +3 -2
  74. package/dist/commands/prismaHandler.js +10 -9
  75. package/dist/commands/serve.js +84 -137
  76. package/dist/commands/serveApiHandler.js +5 -5
  77. package/dist/commands/serveBothHandler.js +10 -7
  78. package/dist/commands/serveWebHandler.js +2 -2
  79. package/dist/commands/setup/auth/auth.js +12 -6
  80. package/dist/commands/setup/cache/cacheHandler.js +11 -6
  81. package/dist/commands/setup/deploy/deploy.js +4 -3
  82. package/dist/commands/setup/deploy/helpers/helpers.js +5 -1
  83. package/dist/commands/setup/deploy/helpers/index.js +157 -5
  84. package/dist/commands/setup/deploy/providers/baremetalHandler.js +26 -4
  85. package/dist/commands/setup/deploy/providers/coherenceHandler.js +53 -25
  86. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +33 -23
  87. package/dist/commands/setup/deploy/providers/netlify.js +6 -0
  88. package/dist/commands/setup/deploy/providers/netlifyHandler.js +112 -11
  89. package/dist/commands/setup/deploy/providers/renderHandler.js +10 -5
  90. package/dist/commands/setup/deploy/providers/serverlessHandler.js +5 -3
  91. package/dist/commands/setup/deploy/providers/universal-deploy.js +11 -0
  92. package/dist/commands/setup/deploy/providers/universalDeployHandler.js +188 -0
  93. package/dist/commands/setup/deploy/providers/vercel.js +6 -0
  94. package/dist/commands/setup/deploy/providers/vercelHandler.js +113 -12
  95. package/dist/commands/setup/deploy/templates/baremetal.js +3 -2
  96. package/dist/commands/setup/deploy/templates/flightcontrol.js +60 -49
  97. package/dist/commands/setup/deploy/templates/netlify.js +2 -1
  98. package/dist/commands/setup/deploy/templates/netlifyUD.js +31 -0
  99. package/dist/commands/setup/docker/docker.js +1 -1
  100. package/dist/commands/setup/docker/dockerHandler.js +72 -37
  101. package/dist/commands/setup/docker/templates/Dockerfile.npm +119 -0
  102. package/dist/commands/setup/docker/templates/Dockerfile.pnpm +112 -0
  103. package/dist/commands/setup/docker/templates/{Dockerfile → Dockerfile.yarn} +1 -1
  104. package/dist/commands/setup/docker/templates/docker-compose.dev.yml +2 -2
  105. package/dist/commands/setup/generator/generatorHandler.js +4 -3
  106. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +2 -2
  107. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +2 -2
  108. package/dist/commands/setup/i18n/i18nHandler.js +18 -15
  109. package/dist/commands/setup/jobs/jobsHandler.js +10 -5
  110. package/dist/commands/setup/mailer/mailerHandler.js +11 -9
  111. package/dist/commands/setup/package/packageHandler.js +14 -10
  112. package/dist/commands/setup/realtime/realtimeHandler.js +22 -20
  113. package/dist/commands/setup/server-file/serverFileHandler.js +16 -8
  114. package/dist/commands/setup/tsconfig/tsconfigHandler.js +5 -3
  115. package/dist/commands/setup/ui/helpers/helpers.js +5 -1
  116. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +11 -5
  117. package/dist/commands/setup/ui/libraries/mantineHandler.js +21 -13
  118. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +38 -26
  119. package/dist/commands/setup/uploads/uploadsHandler.js +7 -4
  120. package/dist/commands/setup.js +1 -2
  121. package/dist/commands/test/testHandler.js +2 -1
  122. package/dist/commands/test/testHandlerEsm.js +2 -2
  123. package/dist/commands/type-checkHandler.js +4 -6
  124. package/dist/commands/upgrade/upgradeHandler.js +2 -4
  125. package/dist/index.js +10 -4
  126. package/dist/lib/configureStorybook.js +2 -2
  127. package/dist/lib/exec.js +36 -24
  128. package/dist/lib/exit.js +19 -4
  129. package/dist/lib/extendFile.js +22 -12
  130. package/dist/lib/index.js +119 -85
  131. package/dist/lib/merge/algorithms.js +4 -1
  132. package/dist/lib/merge/index.js +76 -41
  133. package/dist/lib/merge/semanticIdentity.js +18 -6
  134. package/dist/lib/merge/strategy.js +86 -36
  135. package/dist/lib/packages.js +23 -13
  136. package/dist/lib/plugin.js +12 -5
  137. package/dist/lib/pluralHelpers.js +1 -1
  138. package/dist/lib/project.js +3 -1
  139. package/dist/lib/rollback.js +7 -7
  140. package/dist/lib/schemaHelpers.js +12 -12
  141. package/dist/lib/test.js +4 -0
  142. package/dist/lib/updateCheck.js +6 -4
  143. package/dist/middleware/checkNodeVersion.js +5 -0
  144. package/dist/plugin.js +18 -12
  145. package/dist/telemetry/exporter.js +12 -5
  146. package/dist/telemetry/index.js +4 -3
  147. package/dist/telemetry/resource.js +9 -5
  148. package/dist/telemetry/send.js +14 -10
  149. package/package.json +15 -12
  150. package/dist/commands/setup/vite/templates/vite.config.ts.template +0 -19
  151. package/dist/commands/setup/vite/vite.js +0 -38
  152. package/dist/commands/setup/vite/viteHandler.js +0 -82
  153. /package/dist/{index.d.js → global.d.js} +0 -0
@@ -1,39 +1,140 @@
1
+ import fs from "node:fs";
1
2
  import path from "path";
2
3
  import { Listr } from "listr2";
3
4
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
4
6
  import { errorTelemetry } from "@cedarjs/telemetry";
5
- import { getPaths, printSetupNotes } from "../../../../lib/index.js";
6
- import { addFilesTask, updateApiURLTask } from "../helpers/index.js";
7
+ import {
8
+ addPackagesTask,
9
+ getPaths,
10
+ printSetupNotes
11
+ } from "../../../../lib/index.js";
12
+ import {
13
+ addFilesTask,
14
+ insertPluginsBeforeCedar,
15
+ updateApiURLTask,
16
+ verifyUDSetupTask
17
+ } from "../helpers/index.js";
7
18
  import { NETLIFY_TOML } from "../templates/netlify.js";
19
+ import { NETLIFY_UD_TOML } from "../templates/netlifyUD.js";
8
20
  const files = [
9
21
  {
10
22
  path: path.join(getPaths().base, "netlify.toml"),
11
23
  content: NETLIFY_TOML
12
24
  }
13
25
  ];
26
+ const filesUd = [
27
+ {
28
+ path: path.join(getPaths().base, "netlify.toml"),
29
+ content: NETLIFY_UD_TOML
30
+ }
31
+ ];
14
32
  const notes = [
15
33
  "You are ready to deploy to Netlify!",
16
34
  "See: https://cedarjs.com/docs/deploy/netlify"
17
35
  ];
18
- const handler = async ({ force }) => {
36
+ const udNotes = [
37
+ "You are ready to deploy to Netlify with Universal Deploy!",
38
+ `Build with: ${formatCedarCommand(["build", "--ud"])}`,
39
+ "See: https://cedarjs.com/docs/deploy/netlify"
40
+ ];
41
+ function addNetlifyPluginsToViteConfigTask() {
42
+ return {
43
+ title: "Adding Netlify plugins to vite config...",
44
+ task: async (_ctx, task) => {
45
+ const paths = getPaths();
46
+ const viteConfigTs = path.join(paths.web.base, "vite.config.ts");
47
+ const viteConfigJs = path.join(paths.web.base, "vite.config.js");
48
+ const viteConfigPath = fs.existsSync(viteConfigTs) ? viteConfigTs : viteConfigJs;
49
+ if (!fs.existsSync(viteConfigPath)) {
50
+ task.skip(`${viteConfigPath} not found`);
51
+ return;
52
+ }
53
+ let content = fs.readFileSync(viteConfigPath, "utf-8");
54
+ const hasNetlifyPlugin = content.includes("@netlify/vite-plugin");
55
+ const hasNetlifyCompat = content.includes(
56
+ "@universal-deploy/netlify/vite"
57
+ );
58
+ if (hasNetlifyPlugin && hasNetlifyCompat && content.includes("netlifyCompat(")) {
59
+ task.skip("Netlify plugins are already configured.");
60
+ return;
61
+ }
62
+ if (!hasNetlifyPlugin || !hasNetlifyCompat) {
63
+ const newContent = content.replace(
64
+ /(import\s+\{[^}]*\}\s+from\s+['"]vite['"];?)/,
65
+ (match) => {
66
+ let result = match;
67
+ if (!hasNetlifyPlugin) {
68
+ result = `import netlify from '@netlify/vite-plugin'
69
+ ${result}`;
70
+ }
71
+ if (!hasNetlifyCompat) {
72
+ result = `import netlifyCompat from '@universal-deploy/netlify/vite'
73
+ ${result}`;
74
+ }
75
+ return result;
76
+ }
77
+ );
78
+ if (newContent === content) {
79
+ let prepend = "";
80
+ if (!hasNetlifyPlugin) {
81
+ prepend += "import netlify from '@netlify/vite-plugin'\n";
82
+ }
83
+ if (!hasNetlifyCompat) {
84
+ prepend += "import netlifyCompat from '@universal-deploy/netlify/vite'\n";
85
+ }
86
+ content = prepend + content;
87
+ } else {
88
+ content = newContent;
89
+ }
90
+ }
91
+ if (!content.includes("netlifyCompat(")) {
92
+ const result = insertPluginsBeforeCedar({
93
+ content,
94
+ pluginCodes: [
95
+ "netlify({ build: { enabled: true } })",
96
+ "netlifyCompat()"
97
+ ]
98
+ });
99
+ if (result) {
100
+ content = result;
101
+ }
102
+ }
103
+ fs.writeFileSync(viteConfigPath, content);
104
+ }
105
+ };
106
+ }
107
+ function installNetlifyPackagesTask() {
108
+ return addPackagesTask({
109
+ packages: ["@netlify/vite-plugin", "@universal-deploy/netlify"],
110
+ devDependency: true
111
+ });
112
+ }
113
+ const handler = async ({ force, ud }) => {
19
114
  recordTelemetryAttributes({
20
115
  command: "setup deploy netlify",
21
- force
116
+ force,
117
+ ud
22
118
  });
23
119
  const tasks = new Listr(
24
120
  [
25
- updateApiURLTask("/.netlify/functions"),
26
- addFilesTask({ files, force }),
27
- printSetupNotes(notes)
28
- ],
121
+ ud && verifyUDSetupTask(),
122
+ ud && await installNetlifyPackagesTask(),
123
+ ud && addNetlifyPluginsToViteConfigTask(),
124
+ !ud && updateApiURLTask("/.netlify/functions"),
125
+ addFilesTask({ files: ud ? filesUd : files, force }),
126
+ printSetupNotes(ud ? udNotes : notes)
127
+ ].filter((task) => Boolean(task)),
29
128
  { rendererOptions: { collapseSubtasks: false } }
30
129
  );
31
130
  try {
32
131
  await tasks.run();
33
132
  } catch (e) {
34
- errorTelemetry(process.argv, e.message);
35
- console.error(c.error(e.message));
36
- process.exit(e?.exitCode || 1);
133
+ const message = e instanceof Error ? e.message : String(e);
134
+ errorTelemetry(process.argv, message);
135
+ console.error(c.error(message));
136
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
137
+ process.exit(exitCode);
37
138
  }
38
139
  };
39
140
  export {
@@ -63,7 +63,10 @@ const additionalFiles = [
63
63
  content: RENDER_HEALTH_CHECK
64
64
  }
65
65
  ];
66
- const handler = async ({ force, database }) => {
66
+ const handler = async ({
67
+ force,
68
+ database
69
+ }) => {
67
70
  recordTelemetryAttributes({
68
71
  command: "setup deploy render",
69
72
  force,
@@ -75,7 +78,7 @@ const handler = async ({ force, database }) => {
75
78
  title: "Adding render.yaml",
76
79
  task: async () => {
77
80
  const fileData = await getRenderYamlContent(database);
78
- let files = {};
81
+ const files = {};
79
82
  files[fileData.path] = fileData.content;
80
83
  return writeFilesTask(files, { overwriteExisting: force });
81
84
  }
@@ -92,9 +95,11 @@ const handler = async ({ force, database }) => {
92
95
  try {
93
96
  await tasks.run();
94
97
  } catch (e) {
95
- errorTelemetry(process.argv, e.message);
96
- console.error(c.error(e.message));
97
- process.exit(e?.exitCode || 1);
98
+ const message = e instanceof Error ? e.message : String(e);
99
+ errorTelemetry(process.argv, message);
100
+ console.error(c.error(message));
101
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
102
+ process.exit(exitCode);
98
103
  }
99
104
  };
100
105
  export {
@@ -132,9 +132,11 @@ const handler = async ({ force }) => {
132
132
  try {
133
133
  await tasks.run();
134
134
  } catch (e) {
135
- errorTelemetry(process.argv, e.message);
136
- console.error(c.error(e.message));
137
- process.exit(e?.exitCode || 1);
135
+ const message = e instanceof Error ? e.message : String(e);
136
+ errorTelemetry(process.argv, message);
137
+ console.error(c.error(message));
138
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
139
+ process.exit(exitCode);
138
140
  }
139
141
  };
140
142
  export {
@@ -0,0 +1,11 @@
1
+ const command = "universal-deploy";
2
+ const description = "Setup Universal Deploy";
3
+ async function handler() {
4
+ const { handler: handler2 } = await import("./universalDeployHandler.js");
5
+ return handler2();
6
+ }
7
+ export {
8
+ command,
9
+ description,
10
+ handler
11
+ };
@@ -0,0 +1,188 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { Listr } from "listr2";
4
+ import {
5
+ colors as c,
6
+ getPaths,
7
+ isTypeScriptProject,
8
+ recordTelemetryAttributes
9
+ } from "@cedarjs/cli-helpers";
10
+ import { errorTelemetry } from "@cedarjs/telemetry";
11
+ import { printSetupNotes } from "../../../../lib/index.js";
12
+ const notes = [
13
+ "Universal Deploy is set up!",
14
+ "",
15
+ "Next steps:",
16
+ ` ${c.highlight("yarn cedar build --ud")} \u2014 build the Universal Deploy server entry`,
17
+ ` ${c.highlight("yarn cedar serve --ud")} \u2014 serve it locally`,
18
+ "",
19
+ "To deploy, pick a deployment target, for example:",
20
+ ` ${c.highlight("yarn cedar setup deploy netlify --ud")}`,
21
+ ` ${c.highlight("yarn cedar setup deploy vercel --ud")}`,
22
+ "",
23
+ "See: https://cedarjs.com/docs/deploy/universal-deploy"
24
+ ];
25
+ async function handler() {
26
+ recordTelemetryAttributes({
27
+ command: "setup deploy universal-deploy"
28
+ });
29
+ const tasks = new Listr(
30
+ [addUniversalDeployPluginToViteConfig(), printSetupNotes(notes)],
31
+ { rendererOptions: { collapseSubtasks: false } }
32
+ );
33
+ try {
34
+ await tasks.run();
35
+ } catch (e) {
36
+ errorTelemetry(process.argv, e.message);
37
+ console.error(c.error(e.message));
38
+ process.exit(e.exitCode || 1);
39
+ }
40
+ }
41
+ function addUniversalDeployPluginToViteConfig() {
42
+ return {
43
+ title: "Adding cedarUniversalDeployPlugin to vite config...",
44
+ task: async (_ctx, task) => {
45
+ const projectIsTS = isTypeScriptProject();
46
+ const viteConfigPath = path.join(
47
+ getPaths().web.base,
48
+ `vite.config.${projectIsTS ? "ts" : "js"}`
49
+ );
50
+ if (!fs.existsSync(viteConfigPath)) {
51
+ task.skip(`${viteConfigPath} not found`);
52
+ return;
53
+ }
54
+ let content = fs.readFileSync(viteConfigPath, "utf-8");
55
+ if (content.includes("cedarUniversalDeployPlugin")) {
56
+ task.skip("cedarUniversalDeployPlugin is already configured.");
57
+ return;
58
+ }
59
+ content = mergeImport(content);
60
+ content = addPluginToConfig(content);
61
+ fs.writeFileSync(viteConfigPath, content);
62
+ }
63
+ };
64
+ }
65
+ function findCedarViteImportLine(lines) {
66
+ for (let i = 0; i < lines.length; i++) {
67
+ if (/^import\b/.test(lines[i]) && /from\s+['"]@cedarjs\/vite['"]/.test(lines[i])) {
68
+ return i;
69
+ }
70
+ }
71
+ for (let i = 0; i < lines.length; i++) {
72
+ if (/from\s+['"]@cedarjs\/vite['"]/.test(lines[i])) {
73
+ for (let j = i; j >= 0; j--) {
74
+ if (/^import\b/.test(lines[j])) {
75
+ return j;
76
+ }
77
+ }
78
+ return i;
79
+ }
80
+ }
81
+ return -1;
82
+ }
83
+ function mergeImport(content) {
84
+ const lines = content.split("\n");
85
+ const importIndex = findCedarViteImportLine(lines);
86
+ if (importIndex === -1) {
87
+ throw new Error("No import from @cedarjs/vite found");
88
+ }
89
+ const importLine = lines[importIndex];
90
+ const singleLineNamed = importLine.match(
91
+ /^(import\s*\{\s*)([^}]*?)(\s*\}\s*from\s+['"]@cedarjs\/vite['"];?)$/
92
+ );
93
+ if (singleLineNamed) {
94
+ const specifiers = singleLineNamed[2].trim();
95
+ if (specifiers.includes("cedarUniversalDeployPlugin")) {
96
+ return content;
97
+ }
98
+ lines[importIndex] = specifiers ? `${singleLineNamed[1]}${specifiers}, cedarUniversalDeployPlugin${singleLineNamed[3]}` : `${singleLineNamed[1]}cedarUniversalDeployPlugin${singleLineNamed[3]}`;
99
+ return lines.join("\n");
100
+ }
101
+ let closeIndex = importIndex;
102
+ for (let i = importIndex + 1; i < lines.length; i++) {
103
+ if (/}\s*from\s+['"]@cedarjs\/vite['"]/.test(lines[i])) {
104
+ closeIndex = i;
105
+ break;
106
+ }
107
+ }
108
+ if (closeIndex > importIndex) {
109
+ const specifiersLines = lines.slice(importIndex + 1, closeIndex);
110
+ const allSpecifiers = specifiersLines.join(" ");
111
+ if (allSpecifiers.includes("cedarUniversalDeployPlugin")) {
112
+ return content;
113
+ }
114
+ const indentMatch = specifiersLines[0]?.match(/^(\s+)/);
115
+ const indent = indentMatch?.[1] || " ";
116
+ lines.splice(closeIndex, 0, `${indent}cedarUniversalDeployPlugin,`);
117
+ return lines.join("\n");
118
+ }
119
+ const defaultMatch = importLine.match(
120
+ /^import\s+(\w+)\s+from\s+['"]@cedarjs\/vite['"];?\s*$/
121
+ );
122
+ if (defaultMatch) {
123
+ lines[importIndex] = importLine.replace(
124
+ /(import\s+\w+)(\s+from\s+['"]@cedarjs\/vite['"];?)/,
125
+ "$1, { cedarUniversalDeployPlugin }$2"
126
+ );
127
+ return lines.join("\n");
128
+ }
129
+ return content;
130
+ }
131
+ function addPluginToConfig(content) {
132
+ const lines = content.split("\n");
133
+ const pluginsLineIndex = lines.findIndex(
134
+ (line) => /plugins\s*:\s*\[/.test(line)
135
+ );
136
+ if (pluginsLineIndex === -1) {
137
+ return content;
138
+ }
139
+ const pluginsLine = lines[pluginsLineIndex];
140
+ const inlineMatch = pluginsLine.trim().match(/^plugins\s*:\s*\[([\s\S]*?)\]\s*,?\s*$/);
141
+ if (inlineMatch) {
142
+ const inner = inlineMatch[1].trimEnd();
143
+ const indentation = pluginsLine.match(/^\s*/)?.[0] || " ";
144
+ lines[pluginsLineIndex] = inner ? `${indentation}plugins: [${inner}, cedarUniversalDeployPlugin()],` : `${indentation}plugins: [cedarUniversalDeployPlugin()],`;
145
+ return lines.join("\n");
146
+ }
147
+ let closeIndex = -1;
148
+ for (let i = pluginsLineIndex + 1; i < lines.length; i++) {
149
+ const trimmed = lines[i].trim();
150
+ if (trimmed === "]" || trimmed === "],") {
151
+ closeIndex = i;
152
+ break;
153
+ }
154
+ }
155
+ if (closeIndex === -1) {
156
+ return content;
157
+ }
158
+ const pluginsLineIndent = pluginsLine.match(/^\s*/)?.[0] || "";
159
+ const firstEntryIndent = (() => {
160
+ for (let i = pluginsLineIndex + 1; i < closeIndex; i++) {
161
+ const trimmed = lines[i].trim();
162
+ if (trimmed) {
163
+ return lines[i].match(/^\s*/)?.[0] || " ";
164
+ }
165
+ }
166
+ return pluginsLineIndent + " ";
167
+ })();
168
+ const prevLine = lines[closeIndex - 1]?.trimEnd();
169
+ if (prevLine && !prevLine.endsWith(",") && prevLine !== "[" && !prevLine.endsWith("[")) {
170
+ const commentIdx = prevLine.search(/\s+\/\/|(?<!\\)\/\*/);
171
+ if (commentIdx !== -1) {
172
+ lines[closeIndex - 1] = prevLine.slice(0, commentIdx) + "," + prevLine.slice(commentIdx);
173
+ } else {
174
+ lines[closeIndex - 1] = prevLine + ",";
175
+ }
176
+ }
177
+ lines.splice(
178
+ closeIndex,
179
+ 0,
180
+ `${firstEntryIndent}cedarUniversalDeployPlugin(),`
181
+ );
182
+ return lines.join("\n");
183
+ }
184
+ export {
185
+ addPluginToConfig,
186
+ handler,
187
+ mergeImport
188
+ };
@@ -1,8 +1,14 @@
1
1
  import { createHandler } from "../helpers/helpers.js";
2
2
  const command = "vercel";
3
3
  const description = "Setup Vercel deploy";
4
+ const builder = (yargs) => yargs.option("ud", {
5
+ description: "Setup for use with Universal Deploy",
6
+ type: "boolean",
7
+ default: false
8
+ });
4
9
  const handler = createHandler("vercel");
5
10
  export {
11
+ builder,
6
12
  command,
7
13
  description,
8
14
  handler
@@ -1,19 +1,35 @@
1
+ import fs from "node:fs";
1
2
  import path from "path";
2
3
  import { Listr } from "listr2";
3
4
  import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
4
6
  import { errorTelemetry } from "@cedarjs/telemetry";
5
- import { getPaths, printSetupNotes, writeFile } from "../../../../lib/index.js";
6
- import { updateApiURLTask } from "../helpers/index.js";
7
- async function handler(options) {
7
+ import {
8
+ addPackagesTask,
9
+ getPaths,
10
+ printSetupNotes,
11
+ writeFile
12
+ } from "../../../../lib/index.js";
13
+ import {
14
+ insertPluginsBeforeCedar,
15
+ updateApiURLTask,
16
+ verifyUDSetupTask
17
+ } from "../helpers/index.js";
18
+ async function handler({ force, ud }) {
8
19
  recordTelemetryAttributes({
9
- command: "setup deploy vercel"
20
+ command: "setup deploy vercel",
21
+ force,
22
+ ud
10
23
  });
11
24
  const tasks = new Listr(
12
25
  [
13
- updateApiURLTask("/api"),
14
- writeVercelConfigTask({ overwriteExisting: options.force }),
15
- printSetupNotes(notes)
16
- ],
26
+ ud && verifyUDSetupTask(),
27
+ ud && await installVercelPackagesTask(),
28
+ ud && addVercelPluginToViteConfigTask(),
29
+ !ud && updateApiURLTask("/api"),
30
+ ud ? writeVercelUDConfigTask({ overwriteExisting: force }) : writeVercelConfigTask({ overwriteExisting: force }),
31
+ printSetupNotes(ud ? udNotes : notes)
32
+ ].filter((task) => Boolean(task)),
17
33
  {
18
34
  rendererOptions: { collapseSubtasks: false }
19
35
  }
@@ -21,12 +37,64 @@ async function handler(options) {
21
37
  try {
22
38
  await tasks.run();
23
39
  } catch (e) {
24
- errorTelemetry(process.argv, e.message);
25
- console.error(c.error(e.message));
26
- process.exit(e?.exitCode || 1);
40
+ const message = e instanceof Error ? e.message : String(e);
41
+ errorTelemetry(process.argv, message);
42
+ console.error(c.error(message));
43
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
44
+ process.exit(exitCode);
27
45
  }
28
46
  }
29
- function writeVercelConfigTask({ overwriteExisting = false } = {}) {
47
+ function addVercelPluginToViteConfigTask() {
48
+ return {
49
+ title: "Adding Vercel plugin to vite config...",
50
+ task: async (_ctx, task) => {
51
+ const paths = getPaths();
52
+ const viteConfigTs = path.join(paths.web.base, "vite.config.ts");
53
+ const viteConfigJs = path.join(paths.web.base, "vite.config.js");
54
+ const viteConfigPath = fs.existsSync(viteConfigTs) ? viteConfigTs : viteConfigJs;
55
+ if (!fs.existsSync(viteConfigPath)) {
56
+ task.skip(`${viteConfigPath} not found`);
57
+ return;
58
+ }
59
+ let content = fs.readFileSync(viteConfigPath, "utf-8");
60
+ const hasVercelPlugin = content.includes("vite-plugin-vercel");
61
+ if (hasVercelPlugin && content.includes("vercel(")) {
62
+ task.skip("Vercel plugin is already configured.");
63
+ return;
64
+ }
65
+ if (!hasVercelPlugin) {
66
+ const newContent = content.replace(
67
+ /(import\s+\{[^}]*\}\s+from\s+['"]vite['"];?)/,
68
+ "import { vercel } from 'vite-plugin-vercel/vite'\n$1"
69
+ );
70
+ if (newContent === content) {
71
+ content = "import { vercel } from 'vite-plugin-vercel/vite'\n" + content;
72
+ } else {
73
+ content = newContent;
74
+ }
75
+ }
76
+ if (!content.includes("vercel(")) {
77
+ const result = insertPluginsBeforeCedar({
78
+ content,
79
+ pluginCodes: ["vercel({ outDir: '../.vercel/output' })"]
80
+ });
81
+ if (result) {
82
+ content = result;
83
+ }
84
+ }
85
+ fs.writeFileSync(viteConfigPath, content);
86
+ }
87
+ };
88
+ }
89
+ function installVercelPackagesTask() {
90
+ return addPackagesTask({
91
+ packages: ["vite-plugin-vercel"],
92
+ devDependency: true
93
+ });
94
+ }
95
+ function writeVercelConfigTask({
96
+ overwriteExisting = false
97
+ } = {}) {
30
98
  return {
31
99
  title: "Writing vercel.json...",
32
100
  task: (_ctx, task) => {
@@ -50,6 +118,39 @@ const notes = [
50
118
  "You are ready to deploy to Vercel!",
51
119
  "See: https://cedarjs.com/docs/deploy#vercel-deploy"
52
120
  ];
121
+ const udNotes = [
122
+ "You are ready to deploy to Vercel with Universal Deploy!",
123
+ `Build with: ${formatCedarCommand(["build", "--ud"])}`,
124
+ "See: https://cedarjs.com/docs/deploy#vercel-deploy"
125
+ ];
126
+ function writeVercelUDConfigTask({
127
+ overwriteExisting = false
128
+ } = {}) {
129
+ const config = {
130
+ build: {
131
+ command: formatCedarCommand([
132
+ "build",
133
+ "--ud",
134
+ "--verbose",
135
+ "--apiRootPath=/.api/functions"
136
+ ]),
137
+ env: {
138
+ ENABLE_EXPERIMENTAL_COREPACK: "1"
139
+ }
140
+ }
141
+ };
142
+ return {
143
+ title: "Writing vercel.json for Universal Deploy...",
144
+ task: (_ctx, task) => {
145
+ writeFile(
146
+ path.join(getPaths().base, "vercel.json"),
147
+ JSON.stringify(config, null, 2),
148
+ { overwriteExisting },
149
+ task
150
+ );
151
+ }
152
+ };
153
+ }
53
154
  export {
54
155
  handler
55
156
  };
@@ -1,9 +1,10 @@
1
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
1
2
  const ECOSYSTEM = `module.exports = {
2
3
  apps: [
3
4
  {
4
5
  name: 'serve',
5
6
  cwd: 'current',
6
- script: 'node_modules/.bin/rw',
7
+ script: 'node_modules/.bin/cedar',
7
8
  args: 'serve',
8
9
  instances: 'max',
9
10
  exec_mode: 'cluster',
@@ -32,7 +33,7 @@ host = "server.com"
32
33
  username = "user"
33
34
  agentForward = true
34
35
  sides = ["api","web"]
35
- packageManagerCommand = "yarn"
36
+ packageManagerCommand = "${getPackageManager()}"
36
37
  monitorCommand = "pm2"
37
38
  path = "/var/www/app"
38
39
  processNames = ["serve"]