@cedarjs/cli 5.0.0-canary.2375 → 5.0.0-canary.2377
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.
- package/dist/commands/setup/deploy/deploy.js +2 -1
- package/dist/commands/setup/deploy/helpers/index.js +22 -1
- package/dist/commands/setup/deploy/providers/netlify.js +6 -0
- package/dist/commands/setup/deploy/providers/netlifyHandler.js +106 -8
- package/dist/commands/setup/deploy/providers/universal-deploy.js +11 -0
- package/dist/commands/setup/deploy/providers/universalDeployHandler.js +188 -0
- package/dist/commands/setup/deploy/providers/vercel.js +6 -0
- package/dist/commands/setup/deploy/providers/vercelHandler.js +91 -8
- package/dist/commands/setup/deploy/templates/netlifyUD.js +30 -0
- package/package.json +12 -12
|
@@ -7,8 +7,9 @@ import * as setupDeployFlightcontrol from "./providers/flightcontrol.js";
|
|
|
7
7
|
import * as setupDeployNetlify from "./providers/netlify.js";
|
|
8
8
|
import * as setupDeployRender from "./providers/render.js";
|
|
9
9
|
import * as setupDeployServerless from "./providers/serverless.js";
|
|
10
|
+
import * as setupDeployUniversalDeploy from "./providers/universal-deploy.js";
|
|
10
11
|
import * as setupDeployVercel from "./providers/vercel.js";
|
|
11
|
-
const builder = (yargs) => yargs.command(setupDeployBaremetal).command(setupDeployCoherence).command(setupDeployFlightcontrol).command(setupDeployNetlify).command(setupDeployRender).command(setupDeployServerless).command(setupDeployVercel).demandCommand().option("force", {
|
|
12
|
+
const builder = (yargs) => yargs.command(setupDeployBaremetal).command(setupDeployCoherence).command(setupDeployFlightcontrol).command(setupDeployNetlify).command(setupDeployRender).command(setupDeployServerless).command(setupDeployUniversalDeploy).command(setupDeployVercel).demandCommand().option("force", {
|
|
12
13
|
alias: "f",
|
|
13
14
|
default: false,
|
|
14
15
|
description: "Overwrite existing configuration",
|
|
@@ -64,6 +64,26 @@ const addFilesTask = ({
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
};
|
|
67
|
+
const verifyUDSetupTask = () => {
|
|
68
|
+
return {
|
|
69
|
+
title: "Checking if Universal Deploy is set up...",
|
|
70
|
+
task: () => {
|
|
71
|
+
const paths = getPaths();
|
|
72
|
+
const viteConfigTs = path.join(paths.web.base, "vite.config.ts");
|
|
73
|
+
const viteConfigJs = path.join(paths.web.base, "vite.config.js");
|
|
74
|
+
const viteConfigPath = fs.existsSync(viteConfigTs) ? viteConfigTs : viteConfigJs;
|
|
75
|
+
if (!fs.existsSync(viteConfigPath)) {
|
|
76
|
+
throw new Error("Vite config file not found");
|
|
77
|
+
}
|
|
78
|
+
const content = fs.readFileSync(viteConfigPath, "utf-8");
|
|
79
|
+
if (!content.includes("cedarUniversalDeployPlugin")) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
"Universal Deploy is not set up. Please run `yarn cedar setup deploy universal-deploy` first."
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
};
|
|
67
87
|
const addToGitIgnoreTask = ({ paths }) => {
|
|
68
88
|
return {
|
|
69
89
|
title: "Updating .gitignore...",
|
|
@@ -106,5 +126,6 @@ export {
|
|
|
106
126
|
addToGitIgnoreTask,
|
|
107
127
|
getUserApiUrl,
|
|
108
128
|
preRequisiteCheckTask,
|
|
109
|
-
updateApiURLTask
|
|
129
|
+
updateApiURLTask,
|
|
130
|
+
verifyUDSetupTask
|
|
110
131
|
};
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { createHandler } from "../helpers/helpers.js";
|
|
2
2
|
const command = "netlify";
|
|
3
3
|
const description = "Setup Netlify 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("netlify");
|
|
5
10
|
export {
|
|
11
|
+
builder,
|
|
6
12
|
command,
|
|
7
13
|
description,
|
|
8
14
|
handler
|
|
@@ -1,31 +1,129 @@
|
|
|
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";
|
|
4
5
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
5
|
-
import {
|
|
6
|
-
|
|
6
|
+
import {
|
|
7
|
+
addPackagesTask,
|
|
8
|
+
getPaths,
|
|
9
|
+
printSetupNotes
|
|
10
|
+
} from "../../../../lib/index.js";
|
|
11
|
+
import {
|
|
12
|
+
addFilesTask,
|
|
13
|
+
updateApiURLTask,
|
|
14
|
+
verifyUDSetupTask
|
|
15
|
+
} from "../helpers/index.js";
|
|
7
16
|
import { NETLIFY_TOML } from "../templates/netlify.js";
|
|
17
|
+
import { NETLIFY_UD_TOML } from "../templates/netlifyUD.js";
|
|
8
18
|
const files = [
|
|
9
19
|
{
|
|
10
20
|
path: path.join(getPaths().base, "netlify.toml"),
|
|
11
21
|
content: NETLIFY_TOML
|
|
12
22
|
}
|
|
13
23
|
];
|
|
24
|
+
const filesUd = [
|
|
25
|
+
{
|
|
26
|
+
path: path.join(getPaths().base, "netlify.toml"),
|
|
27
|
+
content: NETLIFY_UD_TOML
|
|
28
|
+
}
|
|
29
|
+
];
|
|
14
30
|
const notes = [
|
|
15
31
|
"You are ready to deploy to Netlify!",
|
|
16
32
|
"See: https://cedarjs.com/docs/deploy/netlify"
|
|
17
33
|
];
|
|
18
|
-
const
|
|
34
|
+
const udNotes = [
|
|
35
|
+
"You are ready to deploy to Netlify with Universal Deploy!",
|
|
36
|
+
"Build with: yarn cedar build --ud",
|
|
37
|
+
"See: https://cedarjs.com/docs/deploy/netlify"
|
|
38
|
+
];
|
|
39
|
+
function addNetlifyPluginsToViteConfigTask() {
|
|
40
|
+
return {
|
|
41
|
+
title: "Adding Netlify plugins to vite config...",
|
|
42
|
+
task: async (_ctx, task) => {
|
|
43
|
+
const paths = getPaths();
|
|
44
|
+
const viteConfigTs = path.join(paths.web.base, "vite.config.ts");
|
|
45
|
+
const viteConfigJs = path.join(paths.web.base, "vite.config.js");
|
|
46
|
+
const viteConfigPath = fs.existsSync(viteConfigTs) ? viteConfigTs : viteConfigJs;
|
|
47
|
+
if (!fs.existsSync(viteConfigPath)) {
|
|
48
|
+
task.skip(`${viteConfigPath} not found`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
let content = fs.readFileSync(viteConfigPath, "utf-8");
|
|
52
|
+
const hasNetlifyPlugin = content.includes("@netlify/vite-plugin");
|
|
53
|
+
const hasNetlifyCompat = content.includes(
|
|
54
|
+
"@universal-deploy/netlify/vite"
|
|
55
|
+
);
|
|
56
|
+
if (hasNetlifyPlugin && hasNetlifyCompat && content.includes("netlifyCompat(")) {
|
|
57
|
+
task.skip("Netlify plugins are already configured.");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!hasNetlifyPlugin || !hasNetlifyCompat) {
|
|
61
|
+
const newContent = content.replace(
|
|
62
|
+
/(import\s+\{[^}]*\}\s+from\s+['"]vite['"];?)/,
|
|
63
|
+
(match) => {
|
|
64
|
+
let result = match;
|
|
65
|
+
if (!hasNetlifyPlugin) {
|
|
66
|
+
result = `import netlify from '@netlify/vite-plugin'
|
|
67
|
+
${result}`;
|
|
68
|
+
}
|
|
69
|
+
if (!hasNetlifyCompat) {
|
|
70
|
+
result = `import netlifyCompat from '@universal-deploy/netlify/vite'
|
|
71
|
+
${result}`;
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
if (newContent === content) {
|
|
77
|
+
let prepend = "";
|
|
78
|
+
if (!hasNetlifyPlugin) {
|
|
79
|
+
prepend += "import netlify from '@netlify/vite-plugin'\n";
|
|
80
|
+
}
|
|
81
|
+
if (!hasNetlifyCompat) {
|
|
82
|
+
prepend += "import netlifyCompat from '@universal-deploy/netlify/vite'\n";
|
|
83
|
+
}
|
|
84
|
+
content = prepend + content;
|
|
85
|
+
} else {
|
|
86
|
+
content = newContent;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!content.includes("netlifyCompat(")) {
|
|
90
|
+
content = content.replace(
|
|
91
|
+
/(\s*)(plugins:\s*\[)([\s\S]*?)(cedar\s*\()/,
|
|
92
|
+
(_match, leadingWs, prefix, beforeCedar, cedarCall) => {
|
|
93
|
+
const indent = beforeCedar.includes("\n") ? beforeCedar.match(/\n(\s*)$/)?.[1] || leadingWs + " " : leadingWs + " ";
|
|
94
|
+
const before = beforeCedar.replace(/\s*$/, "");
|
|
95
|
+
return `${leadingWs}${prefix}
|
|
96
|
+
${indent}netlify({ build: { enabled: true } }),
|
|
97
|
+
${indent}netlifyCompat(),${before}
|
|
98
|
+
${indent}${cedarCall}`;
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
fs.writeFileSync(viteConfigPath, content);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function installNetlifyPackagesTask() {
|
|
107
|
+
return addPackagesTask({
|
|
108
|
+
packages: ["@netlify/vite-plugin", "@universal-deploy/netlify"],
|
|
109
|
+
devDependency: true
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const handler = async ({ force, ud }) => {
|
|
19
113
|
recordTelemetryAttributes({
|
|
20
114
|
command: "setup deploy netlify",
|
|
21
|
-
force
|
|
115
|
+
force,
|
|
116
|
+
ud
|
|
22
117
|
});
|
|
23
118
|
const tasks = new Listr(
|
|
24
119
|
[
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
120
|
+
ud && verifyUDSetupTask(),
|
|
121
|
+
ud && installNetlifyPackagesTask(),
|
|
122
|
+
ud && addNetlifyPluginsToViteConfigTask(),
|
|
123
|
+
!ud && updateApiURLTask("/.netlify/functions"),
|
|
124
|
+
addFilesTask({ files: ud ? filesUd : files, force }),
|
|
125
|
+
printSetupNotes(ud ? udNotes : notes)
|
|
126
|
+
].filter(Boolean),
|
|
29
127
|
{ rendererOptions: { collapseSubtasks: false } }
|
|
30
128
|
);
|
|
31
129
|
try {
|
|
@@ -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,30 @@
|
|
|
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";
|
|
4
5
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
addPackagesTask,
|
|
8
|
+
getPaths,
|
|
9
|
+
printSetupNotes,
|
|
10
|
+
writeFile
|
|
11
|
+
} from "../../../../lib/index.js";
|
|
12
|
+
import { updateApiURLTask, verifyUDSetupTask } from "../helpers/index.js";
|
|
13
|
+
async function handler({ force, ud }) {
|
|
8
14
|
recordTelemetryAttributes({
|
|
9
|
-
command: "setup deploy vercel"
|
|
15
|
+
command: "setup deploy vercel",
|
|
16
|
+
force,
|
|
17
|
+
ud
|
|
10
18
|
});
|
|
11
19
|
const tasks = new Listr(
|
|
12
20
|
[
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
ud && verifyUDSetupTask(),
|
|
22
|
+
ud && installVercelPackagesTask(),
|
|
23
|
+
ud && addVercelPluginToViteConfigTask(),
|
|
24
|
+
!ud && updateApiURLTask("/api"),
|
|
25
|
+
ud ? writeVercelUDConfigTask({ overwriteExisting: force }) : writeVercelConfigTask({ overwriteExisting: force }),
|
|
26
|
+
printSetupNotes(ud ? udNotes : notes)
|
|
27
|
+
].filter(Boolean),
|
|
17
28
|
{
|
|
18
29
|
rendererOptions: { collapseSubtasks: false }
|
|
19
30
|
}
|
|
@@ -26,6 +37,52 @@ async function handler(options) {
|
|
|
26
37
|
process.exit(e?.exitCode || 1);
|
|
27
38
|
}
|
|
28
39
|
}
|
|
40
|
+
function addVercelPluginToViteConfigTask() {
|
|
41
|
+
return {
|
|
42
|
+
title: "Adding Vercel plugin to vite config...",
|
|
43
|
+
task: async (_ctx, task) => {
|
|
44
|
+
const paths = getPaths();
|
|
45
|
+
const viteConfigTs = path.join(paths.web.base, "vite.config.ts");
|
|
46
|
+
const viteConfigJs = path.join(paths.web.base, "vite.config.js");
|
|
47
|
+
const viteConfigPath = fs.existsSync(viteConfigTs) ? viteConfigTs : viteConfigJs;
|
|
48
|
+
if (!fs.existsSync(viteConfigPath)) {
|
|
49
|
+
task.skip(`${viteConfigPath} not found`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let content = fs.readFileSync(viteConfigPath, "utf-8");
|
|
53
|
+
if (content.includes("vite-plugin-vercel") && content.includes("vercel(")) {
|
|
54
|
+
task.skip("Vercel plugin is already configured.");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const newContent = content.replace(
|
|
58
|
+
/(import\s+\{[^}]*\}\s+from\s+['"]vite['"];?)/,
|
|
59
|
+
"import { vercel } from 'vite-plugin-vercel/vite'\n$1"
|
|
60
|
+
);
|
|
61
|
+
if (newContent === content) {
|
|
62
|
+
content = "import { vercel } from 'vite-plugin-vercel/vite'\n" + content;
|
|
63
|
+
} else {
|
|
64
|
+
content = newContent;
|
|
65
|
+
}
|
|
66
|
+
content = content.replace(
|
|
67
|
+
/(\s*)(plugins:\s*\[)([\s\S]*?)(cedar\s*\()/,
|
|
68
|
+
(_match, leadingWs, prefix, beforeCedar, cedarCall) => {
|
|
69
|
+
const indent = beforeCedar.includes("\n") ? beforeCedar.match(/\n(\s*)$/)?.[1] || leadingWs + " " : leadingWs + " ";
|
|
70
|
+
const before = beforeCedar.replace(/\s*$/, "");
|
|
71
|
+
return `${leadingWs}${prefix}
|
|
72
|
+
${indent}vercel(),${before}
|
|
73
|
+
${indent}${cedarCall}`;
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
fs.writeFileSync(viteConfigPath, content);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function installVercelPackagesTask() {
|
|
81
|
+
return addPackagesTask({
|
|
82
|
+
packages: ["vite-plugin-vercel"],
|
|
83
|
+
devDependency: true
|
|
84
|
+
});
|
|
85
|
+
}
|
|
29
86
|
function writeVercelConfigTask({ overwriteExisting = false } = {}) {
|
|
30
87
|
return {
|
|
31
88
|
title: "Writing vercel.json...",
|
|
@@ -46,10 +103,36 @@ const vercelConfig = {
|
|
|
46
103
|
}
|
|
47
104
|
}
|
|
48
105
|
};
|
|
106
|
+
const vercelUDConfig = {
|
|
107
|
+
build: {
|
|
108
|
+
command: "yarn cedar build --ud --verbose",
|
|
109
|
+
env: {
|
|
110
|
+
ENABLE_EXPERIMENTAL_COREPACK: "1"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
49
114
|
const notes = [
|
|
50
115
|
"You are ready to deploy to Vercel!",
|
|
51
116
|
"See: https://cedarjs.com/docs/deploy#vercel-deploy"
|
|
52
117
|
];
|
|
118
|
+
const udNotes = [
|
|
119
|
+
"You are ready to deploy to Vercel with Universal Deploy!",
|
|
120
|
+
"Build with: yarn cedar build --ud",
|
|
121
|
+
"See: https://cedarjs.com/docs/deploy#vercel-deploy"
|
|
122
|
+
];
|
|
123
|
+
function writeVercelUDConfigTask({ overwriteExisting = false } = {}) {
|
|
124
|
+
return {
|
|
125
|
+
title: "Writing vercel.json for Universal Deploy...",
|
|
126
|
+
task: (_ctx, task) => {
|
|
127
|
+
writeFile(
|
|
128
|
+
path.join(getPaths().base, "vercel.json"),
|
|
129
|
+
JSON.stringify(vercelUDConfig, null, 2),
|
|
130
|
+
{ overwriteExisting },
|
|
131
|
+
task
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
53
136
|
export {
|
|
54
137
|
handler
|
|
55
138
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getConfig } from "../../../../lib/index.js";
|
|
2
|
+
const config = getConfig();
|
|
3
|
+
const NETLIFY_UD_TOML = `[build]
|
|
4
|
+
command = "yarn cedar build --ud --apiRootPath=/.api/functions && yarn cedar prisma migrate deploy && yarn cedar data-migrate up"
|
|
5
|
+
publish = "web/dist"
|
|
6
|
+
|
|
7
|
+
[build.environment]
|
|
8
|
+
NODE_VERSION = "24"
|
|
9
|
+
|
|
10
|
+
[functions]
|
|
11
|
+
directory = "api/dist/functions"
|
|
12
|
+
|
|
13
|
+
# To use Netlify Dev, install Netlify's CLI (\`netlify-cli\`) from NPM and use
|
|
14
|
+
# \`netlify link\` to connect your local project to a site on Netlify. Then run
|
|
15
|
+
# \`netlify dev\`.
|
|
16
|
+
#
|
|
17
|
+
# Quick links to the docs:
|
|
18
|
+
# - Netlify Dev https://docs.netlify.com/api-and-cli-guides/cli-guides/local-development
|
|
19
|
+
# - Netlify's CLI https://docs.netlify.com/api-and-cli-guides/cli-guides/get-started-with-cli/
|
|
20
|
+
# - \`netlify link\` https://cli.netlify.com/commands/link/
|
|
21
|
+
[dev]
|
|
22
|
+
framework = "cedarjs"
|
|
23
|
+
# Make sure \`targetPort\` matches \`web.port\` in your cedar.toml file
|
|
24
|
+
targetPort = ${config.web.port}
|
|
25
|
+
# Point your browser to this port to access your app
|
|
26
|
+
port = 8888
|
|
27
|
+
`;
|
|
28
|
+
export {
|
|
29
|
+
NETLIFY_UD_TOML
|
|
30
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli",
|
|
3
|
-
"version": "5.0.0-canary.
|
|
3
|
+
"version": "5.0.0-canary.2377",
|
|
4
4
|
"description": "The CedarJS Command Line",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@babel/parser": "7.29.3",
|
|
35
35
|
"@babel/preset-typescript": "7.28.5",
|
|
36
|
-
"@cedarjs/api-server": "5.0.0-canary.
|
|
37
|
-
"@cedarjs/cli-helpers": "5.0.0-canary.
|
|
38
|
-
"@cedarjs/fastify-web": "5.0.0-canary.
|
|
39
|
-
"@cedarjs/internal": "5.0.0-canary.
|
|
40
|
-
"@cedarjs/prerender": "5.0.0-canary.
|
|
41
|
-
"@cedarjs/project-config": "5.0.0-canary.
|
|
42
|
-
"@cedarjs/structure": "5.0.0-canary.
|
|
43
|
-
"@cedarjs/telemetry": "5.0.0-canary.
|
|
44
|
-
"@cedarjs/utils": "5.0.0-canary.
|
|
45
|
-
"@cedarjs/vite": "5.0.0-canary.
|
|
46
|
-
"@cedarjs/web-server": "5.0.0-canary.
|
|
36
|
+
"@cedarjs/api-server": "5.0.0-canary.2377",
|
|
37
|
+
"@cedarjs/cli-helpers": "5.0.0-canary.2377",
|
|
38
|
+
"@cedarjs/fastify-web": "5.0.0-canary.2377",
|
|
39
|
+
"@cedarjs/internal": "5.0.0-canary.2377",
|
|
40
|
+
"@cedarjs/prerender": "5.0.0-canary.2377",
|
|
41
|
+
"@cedarjs/project-config": "5.0.0-canary.2377",
|
|
42
|
+
"@cedarjs/structure": "5.0.0-canary.2377",
|
|
43
|
+
"@cedarjs/telemetry": "5.0.0-canary.2377",
|
|
44
|
+
"@cedarjs/utils": "5.0.0-canary.2377",
|
|
45
|
+
"@cedarjs/vite": "5.0.0-canary.2377",
|
|
46
|
+
"@cedarjs/web-server": "5.0.0-canary.2377",
|
|
47
47
|
"@listr2/prompt-adapter-enquirer": "4.2.1",
|
|
48
48
|
"@opentelemetry/api": "1.9.0",
|
|
49
49
|
"@opentelemetry/core": "1.30.1",
|