webstudio 0.173.0 → 0.175.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.
- package/lib/cli.js +89 -50
- package/package.json +17 -17
- package/templates/cloudflare/package.json +2 -2
- package/templates/defaults/app/extension.ts +7 -1
- package/templates/defaults/app/route-templates/html.tsx +30 -36
- package/templates/defaults/app/route-templates/xml.tsx +1 -2
- package/templates/defaults/package.json +12 -13
- package/templates/internal/package.json +0 -1
- package/templates/ssg/app/constants.mjs +4 -0
- package/templates/ssg/app/route-templates/html/+Page.tsx +1 -1
- package/templates/ssg/package.json +7 -8
- package/templates/ssg-netlify/app/constants.mjs +33 -0
- package/templates/ssg-vercel/app/constants.mjs +33 -0
- package/templates/ssg-vercel/public/vercel.json +11 -0
package/lib/cli.js
CHANGED
|
@@ -44,12 +44,41 @@ var zGlobalConfig = z.record(
|
|
|
44
44
|
var jsonToGlobalConfig = (json) => {
|
|
45
45
|
return zGlobalConfig.parse(json);
|
|
46
46
|
};
|
|
47
|
-
var
|
|
48
|
-
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
var PROJECT_TEMPLATES = [
|
|
48
|
+
{
|
|
49
|
+
value: "vanilla",
|
|
50
|
+
label: "Vanilla",
|
|
51
|
+
expand: ["defaults"]
|
|
52
|
+
},
|
|
53
|
+
{ value: "vercel", label: "Vercel", expand: ["defaults", "vercel"] },
|
|
54
|
+
{
|
|
55
|
+
value: "netlify-functions",
|
|
56
|
+
label: "Netlify Functions",
|
|
57
|
+
expand: ["defaults", "netlify-functions"]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
value: "netlify-edge-functions",
|
|
61
|
+
label: "Netlify Edge Functions",
|
|
62
|
+
expand: ["defaults", "netlify-edge-functions"]
|
|
63
|
+
},
|
|
64
|
+
{ value: "ssg", label: "Static Site Generation (SSG)" },
|
|
65
|
+
{
|
|
66
|
+
value: "ssg-netlify",
|
|
67
|
+
label: "Static Site Generation (SSG) Netlify",
|
|
68
|
+
expand: ["ssg", "ssg-netlify"]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
value: "ssg-vercel",
|
|
72
|
+
label: "Static Site Generation (SSG) Vercel",
|
|
73
|
+
expand: ["ssg", "ssg-vercel"]
|
|
74
|
+
}
|
|
75
|
+
];
|
|
76
|
+
var INTERNAL_TEMPLATES = [
|
|
77
|
+
{
|
|
78
|
+
value: "cloudflare",
|
|
79
|
+
label: "Cloudflare",
|
|
80
|
+
expand: ["defaults", "cloudflare"]
|
|
81
|
+
}
|
|
53
82
|
];
|
|
54
83
|
|
|
55
84
|
// src/fs-utils.ts
|
|
@@ -99,20 +128,23 @@ import { cwd, exit } from "node:process";
|
|
|
99
128
|
import { join as join2 } from "node:path";
|
|
100
129
|
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
101
130
|
import { cancel, isCancel, log, text } from "@clack/prompts";
|
|
131
|
+
import { parseBuilderUrl } from "@webstudio-is/http-client";
|
|
102
132
|
var parseShareLink = (value) => {
|
|
103
133
|
const url = new URL(value);
|
|
104
|
-
const origin = url.origin;
|
|
105
134
|
const token = url.searchParams.get("authToken");
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
|
|
135
|
+
let { projectId, sourceOrigin } = parseBuilderUrl(url.href);
|
|
136
|
+
if (projectId === void 0) {
|
|
137
|
+
const segments = url.pathname.split("/").slice(1);
|
|
138
|
+
if (segments.length !== 2 || segments[0] !== "builder") {
|
|
139
|
+
throw Error("Segments not matching");
|
|
140
|
+
}
|
|
141
|
+
projectId = segments[1];
|
|
109
142
|
}
|
|
110
|
-
const [_builder, projectId] = segments;
|
|
111
143
|
if (token == null) {
|
|
112
144
|
throw Error("Token is missing");
|
|
113
145
|
}
|
|
114
146
|
return {
|
|
115
|
-
origin,
|
|
147
|
+
origin: sourceOrigin,
|
|
116
148
|
projectId,
|
|
117
149
|
token
|
|
118
150
|
};
|
|
@@ -180,7 +212,7 @@ import pc from "picocolors";
|
|
|
180
212
|
import { spinner } from "@clack/prompts";
|
|
181
213
|
import {
|
|
182
214
|
loadProjectDataByBuildId,
|
|
183
|
-
|
|
215
|
+
loadProjectDataByProjectId
|
|
184
216
|
} from "@webstudio-is/http-client";
|
|
185
217
|
var syncOptions = (yargs) => yargs.option("buildId", {
|
|
186
218
|
type: "string",
|
|
@@ -194,21 +226,13 @@ var syncOptions = (yargs) => yargs.option("buildId", {
|
|
|
194
226
|
});
|
|
195
227
|
var sync = async (options) => {
|
|
196
228
|
const syncing = spinner();
|
|
197
|
-
syncing.start("Synchronizing project data");
|
|
198
|
-
const definedOptionValues = [
|
|
199
|
-
options.buildId,
|
|
200
|
-
options.origin,
|
|
201
|
-
options.authToken
|
|
202
|
-
].filter(Boolean);
|
|
203
|
-
if (definedOptionValues.length > 0 && definedOptionValues.length < 3) {
|
|
204
|
-
syncing.stop(`Please provide buildId, origin and authToken`, 2);
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
229
|
let project;
|
|
230
|
+
syncing.start(`Synchronizing project data`);
|
|
208
231
|
if (options.buildId !== void 0 && options.origin !== void 0 && options.authToken !== void 0) {
|
|
232
|
+
syncing.message(`Synchronizing project data from ${options.origin}`);
|
|
209
233
|
project = await loadProjectDataByBuildId({
|
|
210
234
|
buildId: options.buildId,
|
|
211
|
-
|
|
235
|
+
seviceToken: options.authToken,
|
|
212
236
|
origin: options.origin
|
|
213
237
|
});
|
|
214
238
|
} else {
|
|
@@ -235,8 +259,13 @@ var sync = async (options) => {
|
|
|
235
259
|
return;
|
|
236
260
|
}
|
|
237
261
|
const { origin, token } = projectConfig;
|
|
262
|
+
syncing.message(`Synchronizing project data from ${origin}`);
|
|
238
263
|
try {
|
|
239
|
-
project = await
|
|
264
|
+
project = options.buildId !== void 0 ? await loadProjectDataByBuildId({
|
|
265
|
+
buildId: options.buildId,
|
|
266
|
+
authToken: token,
|
|
267
|
+
origin
|
|
268
|
+
}) : await loadProjectDataByProjectId({
|
|
240
269
|
projectId: localConfig.projectId,
|
|
241
270
|
authToken: token,
|
|
242
271
|
origin
|
|
@@ -659,9 +688,6 @@ Please check webstudio --help for more details`
|
|
|
659
688
|
exit2(1);
|
|
660
689
|
}
|
|
661
690
|
for (const template of options.template) {
|
|
662
|
-
if (template === "vanilla" || template === "ssg") {
|
|
663
|
-
continue;
|
|
664
|
-
}
|
|
665
691
|
if (template.startsWith(".") || template.startsWith("/")) {
|
|
666
692
|
continue;
|
|
667
693
|
}
|
|
@@ -679,12 +705,8 @@ Please check webstudio --help for more details`
|
|
|
679
705
|
await rm3(generatedDir, { recursive: true, force: true });
|
|
680
706
|
const routesDir = join6(appRoot, "routes");
|
|
681
707
|
await rm3(routesDir, { recursive: true, force: true });
|
|
682
|
-
await copyTemplates(options.template.includes("ssg") ? "ssg" : "defaults");
|
|
683
708
|
await writeFile4(join6(cwd3(), ".npmrc"), "force=true");
|
|
684
709
|
for (const template of options.template) {
|
|
685
|
-
if (template === "vanilla" || template === "ssg") {
|
|
686
|
-
continue;
|
|
687
|
-
}
|
|
688
710
|
await copyTemplates(template);
|
|
689
711
|
}
|
|
690
712
|
let framework;
|
|
@@ -701,10 +723,6 @@ Please check webstudio --help for more details`
|
|
|
701
723
|
`Project data is missing, please make sure you the project is synced.`
|
|
702
724
|
);
|
|
703
725
|
}
|
|
704
|
-
const domain = siteData.build.deployment?.projectDomain;
|
|
705
|
-
if (domain === void 0) {
|
|
706
|
-
throw new Error(`Project domain is missing from the project data`);
|
|
707
|
-
}
|
|
708
726
|
const metas = /* @__PURE__ */ new Map();
|
|
709
727
|
const componentSources = /* @__PURE__ */ new Map();
|
|
710
728
|
for (const entry of framework.components) {
|
|
@@ -803,6 +821,10 @@ Please check webstudio --help for more details`
|
|
|
803
821
|
}
|
|
804
822
|
const assetsToDownload = [];
|
|
805
823
|
const appDomain = options.preview ? "wstd.work" : "wstd.io";
|
|
824
|
+
const domain = siteData.build.deployment?.destination === "static" ? siteData.build.deployment?.assetsDomain : siteData.build.deployment?.projectDomain;
|
|
825
|
+
if (domain === void 0) {
|
|
826
|
+
throw new Error(`Project domain is missing from the project data`);
|
|
827
|
+
}
|
|
806
828
|
const assetBuildUrl = `https://${domain}.${appDomain}/cgi/asset/`;
|
|
807
829
|
const imageLoader = createImageLoader({
|
|
808
830
|
imageBaseUrl: assetBuildUrl
|
|
@@ -851,6 +873,7 @@ Please check webstudio --help for more details`
|
|
|
851
873
|
"useState",
|
|
852
874
|
"Fragment",
|
|
853
875
|
"useResource",
|
|
876
|
+
"useVariableState",
|
|
854
877
|
"Page",
|
|
855
878
|
"_props"
|
|
856
879
|
]);
|
|
@@ -948,7 +971,7 @@ Please check webstudio --help for more details`
|
|
|
948
971
|
|
|
949
972
|
import { Fragment, useState } from "react";
|
|
950
973
|
import type { FontAsset, ImageAsset } from "@webstudio-is/sdk";
|
|
951
|
-
import { useResource } from "@webstudio-is/react-sdk";
|
|
974
|
+
import { useResource, useVariableState } from "@webstudio-is/react-sdk/runtime";
|
|
952
975
|
${componentImports}
|
|
953
976
|
|
|
954
977
|
export const siteName = ${JSON.stringify(projectMeta?.siteName)};
|
|
@@ -1102,7 +1125,23 @@ var buildOptions = (yargs) => yargs.option("assets", {
|
|
|
1102
1125
|
type: "array",
|
|
1103
1126
|
string: true,
|
|
1104
1127
|
default: [],
|
|
1105
|
-
|
|
1128
|
+
coerce: (values) => {
|
|
1129
|
+
const templates = [];
|
|
1130
|
+
for (const value of values) {
|
|
1131
|
+
const template = PROJECT_TEMPLATES.find((item) => item.value === value) ?? INTERNAL_TEMPLATES.find((item) => item.value === value);
|
|
1132
|
+
if (template == null) {
|
|
1133
|
+
templates.push(value);
|
|
1134
|
+
continue;
|
|
1135
|
+
}
|
|
1136
|
+
if ("expand" in template && template.expand != null) {
|
|
1137
|
+
templates.push(...template.expand);
|
|
1138
|
+
continue;
|
|
1139
|
+
}
|
|
1140
|
+
templates.push(value);
|
|
1141
|
+
}
|
|
1142
|
+
return templates;
|
|
1143
|
+
},
|
|
1144
|
+
describe: `Template to use for the build [choices: ${PROJECT_TEMPLATES.map(
|
|
1106
1145
|
(item) => item.value
|
|
1107
1146
|
).join(", ")}]`
|
|
1108
1147
|
});
|
|
@@ -1178,7 +1217,7 @@ var initFlow = async (options) => {
|
|
|
1178
1217
|
projectTemplate = exitIfCancelled(
|
|
1179
1218
|
await select({
|
|
1180
1219
|
message: "Where would you like to deploy your project?",
|
|
1181
|
-
options:
|
|
1220
|
+
options: PROJECT_TEMPLATES
|
|
1182
1221
|
})
|
|
1183
1222
|
);
|
|
1184
1223
|
shouldInstallDeps = exitIfCancelled(
|
|
@@ -1192,7 +1231,7 @@ var initFlow = async (options) => {
|
|
|
1192
1231
|
projectTemplate = exitIfCancelled(
|
|
1193
1232
|
await select({
|
|
1194
1233
|
message: "Where would you like to deploy your project?",
|
|
1195
|
-
options:
|
|
1234
|
+
options: PROJECT_TEMPLATES
|
|
1196
1235
|
})
|
|
1197
1236
|
);
|
|
1198
1237
|
}
|
|
@@ -1242,7 +1281,7 @@ import makeCLI from "yargs";
|
|
|
1242
1281
|
// package.json
|
|
1243
1282
|
var package_default = {
|
|
1244
1283
|
name: "webstudio",
|
|
1245
|
-
version: "0.
|
|
1284
|
+
version: "0.175.0",
|
|
1246
1285
|
description: "Webstudio CLI",
|
|
1247
1286
|
author: "Webstudio <github@webstudio.is>",
|
|
1248
1287
|
homepage: "https://webstudio.is",
|
|
@@ -1296,25 +1335,25 @@ var package_default = {
|
|
|
1296
1335
|
"@jest/globals": "^29.7.0",
|
|
1297
1336
|
"@netlify/remix-adapter": "^2.4.0",
|
|
1298
1337
|
"@netlify/remix-edge-adapter": "3.3.0",
|
|
1299
|
-
"@remix-run/cloudflare": "^2.
|
|
1300
|
-
"@remix-run/cloudflare-pages": "^2.
|
|
1301
|
-
"@remix-run/dev": "^2.
|
|
1302
|
-
"@remix-run/node": "^2.
|
|
1303
|
-
"@remix-run/react": "^2.
|
|
1304
|
-
"@remix-run/server-runtime": "^2.
|
|
1338
|
+
"@remix-run/cloudflare": "^2.11.0",
|
|
1339
|
+
"@remix-run/cloudflare-pages": "^2.11.0",
|
|
1340
|
+
"@remix-run/dev": "^2.11.0",
|
|
1341
|
+
"@remix-run/node": "^2.11.0",
|
|
1342
|
+
"@remix-run/react": "^2.11.0",
|
|
1343
|
+
"@remix-run/server-runtime": "^2.11.0",
|
|
1305
1344
|
"@types/node": "^20.12.7",
|
|
1306
1345
|
"@types/react": "^18.2.70",
|
|
1307
1346
|
"@types/react-dom": "^18.2.25",
|
|
1308
1347
|
"@types/yargs": "^17.0.32",
|
|
1309
1348
|
"@vitejs/plugin-react": "^4.3.1",
|
|
1310
|
-
"@webstudio-is/form-handlers": "workspace:*",
|
|
1311
1349
|
"@webstudio-is/jest-config": "workspace:*",
|
|
1312
1350
|
"@webstudio-is/tsconfig": "workspace:*",
|
|
1313
1351
|
react: "18.3.0-canary-14898b6a9-20240318",
|
|
1314
1352
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
1353
|
+
"ts-expect": "^1.3.0",
|
|
1315
1354
|
typescript: "5.5.2",
|
|
1316
|
-
vike: "^0.4.
|
|
1317
|
-
vite: "^5.
|
|
1355
|
+
vike: "^0.4.182",
|
|
1356
|
+
vite: "^5.4.0",
|
|
1318
1357
|
wrangler: "^3.63.2"
|
|
1319
1358
|
}
|
|
1320
1359
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webstudio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.175.0",
|
|
4
4
|
"description": "Webstudio CLI",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -37,24 +37,24 @@
|
|
|
37
37
|
"strip-indent": "^4.0.0",
|
|
38
38
|
"yargs": "^17.7.2",
|
|
39
39
|
"zod": "^3.22.4",
|
|
40
|
-
"@webstudio-is/http-client": "0.
|
|
41
|
-
"@webstudio-is/
|
|
42
|
-
"@webstudio-is/sdk
|
|
43
|
-
"@webstudio-is/
|
|
44
|
-
"@webstudio-is/react-
|
|
45
|
-
"@webstudio-is/sdk-components-react
|
|
46
|
-
"@webstudio-is/sdk-components-react-
|
|
40
|
+
"@webstudio-is/http-client": "0.175.0",
|
|
41
|
+
"@webstudio-is/image": "0.175.0",
|
|
42
|
+
"@webstudio-is/react-sdk": "0.175.0",
|
|
43
|
+
"@webstudio-is/sdk": "0.175.0",
|
|
44
|
+
"@webstudio-is/sdk-components-react-remix": "0.175.0",
|
|
45
|
+
"@webstudio-is/sdk-components-react": "0.175.0",
|
|
46
|
+
"@webstudio-is/sdk-components-react-radix": "0.175.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@jest/globals": "^29.7.0",
|
|
50
50
|
"@netlify/remix-adapter": "^2.4.0",
|
|
51
51
|
"@netlify/remix-edge-adapter": "3.3.0",
|
|
52
|
-
"@remix-run/cloudflare": "^2.
|
|
53
|
-
"@remix-run/cloudflare-pages": "^2.
|
|
54
|
-
"@remix-run/dev": "^2.
|
|
55
|
-
"@remix-run/node": "^2.
|
|
56
|
-
"@remix-run/react": "^2.
|
|
57
|
-
"@remix-run/server-runtime": "^2.
|
|
52
|
+
"@remix-run/cloudflare": "^2.11.0",
|
|
53
|
+
"@remix-run/cloudflare-pages": "^2.11.0",
|
|
54
|
+
"@remix-run/dev": "^2.11.0",
|
|
55
|
+
"@remix-run/node": "^2.11.0",
|
|
56
|
+
"@remix-run/react": "^2.11.0",
|
|
57
|
+
"@remix-run/server-runtime": "^2.11.0",
|
|
58
58
|
"@types/node": "^20.12.7",
|
|
59
59
|
"@types/react": "^18.2.70",
|
|
60
60
|
"@types/react-dom": "^18.2.25",
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
"@vitejs/plugin-react": "^4.3.1",
|
|
63
63
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
64
64
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
65
|
+
"ts-expect": "^1.3.0",
|
|
65
66
|
"typescript": "5.5.2",
|
|
66
|
-
"vike": "^0.4.
|
|
67
|
-
"vite": "^5.
|
|
67
|
+
"vike": "^0.4.182",
|
|
68
|
+
"vite": "^5.4.0",
|
|
68
69
|
"wrangler": "^3.63.2",
|
|
69
|
-
"@webstudio-is/form-handlers": "0.173.0",
|
|
70
70
|
"@webstudio-is/jest-config": "1.0.7",
|
|
71
71
|
"@webstudio-is/tsconfig": "1.0.7"
|
|
72
72
|
},
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"build-cf-types": "wrangler types"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@remix-run/cloudflare": "2.
|
|
16
|
-
"@remix-run/cloudflare-pages": "2.
|
|
15
|
+
"@remix-run/cloudflare": "2.11.0",
|
|
16
|
+
"@remix-run/cloudflare-pages": "2.11.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@cloudflare/workers-types": "^4.20240620.0",
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2
2
|
// @ts-ignore
|
|
3
3
|
import { AppLoadContext } from "@remix-run/server-runtime";
|
|
4
|
+
import { ResourceRequest } from "@webstudio-is/sdk";
|
|
4
5
|
|
|
5
6
|
declare module "@remix-run/server-runtime" {
|
|
6
7
|
interface AppLoadContext {
|
|
7
8
|
EXCLUDE_FROM_SEARCH: boolean;
|
|
8
|
-
|
|
9
|
+
getDefaultActionResource?: (options: {
|
|
10
|
+
url: URL;
|
|
11
|
+
projectId: string;
|
|
12
|
+
contactEmail: string;
|
|
13
|
+
formData: FormData;
|
|
14
|
+
}) => ResourceRequest;
|
|
9
15
|
}
|
|
10
16
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable camelcase */
|
|
2
1
|
import {
|
|
3
2
|
type ServerRuntimeMetaFunction as MetaFunction,
|
|
4
3
|
type LinksFunction,
|
|
@@ -14,13 +13,10 @@ import {
|
|
|
14
13
|
isLocalResource,
|
|
15
14
|
loadResource,
|
|
16
15
|
loadResources,
|
|
17
|
-
} from "@webstudio-is/sdk";
|
|
18
|
-
import { ReactSdkContext } from "@webstudio-is/react-sdk";
|
|
19
|
-
import {
|
|
20
|
-
n8nHandler,
|
|
21
16
|
formIdFieldName,
|
|
22
17
|
formBotFieldName,
|
|
23
|
-
} from "@webstudio-is/
|
|
18
|
+
} from "@webstudio-is/sdk";
|
|
19
|
+
import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime";
|
|
24
20
|
import {
|
|
25
21
|
Page,
|
|
26
22
|
siteName,
|
|
@@ -251,24 +247,22 @@ export const action = async ({
|
|
|
251
247
|
{ success: true } | { success: false; errors: string[] }
|
|
252
248
|
> => {
|
|
253
249
|
try {
|
|
254
|
-
const
|
|
255
|
-
|
|
250
|
+
const url = new URL(request.url);
|
|
251
|
+
url.host = getRequestHost(request);
|
|
256
252
|
|
|
257
253
|
const formData = await request.formData();
|
|
258
254
|
|
|
259
255
|
const system = {
|
|
260
256
|
params: {},
|
|
261
257
|
search: {},
|
|
262
|
-
origin:
|
|
258
|
+
origin: url.origin,
|
|
263
259
|
};
|
|
264
260
|
|
|
265
261
|
const resourceName = formData.get(formIdFieldName);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const resource = getResources({ system }).action.get(resourceName);
|
|
262
|
+
let resource =
|
|
263
|
+
typeof resourceName === "string"
|
|
264
|
+
? getResources({ system }).action.get(resourceName)
|
|
265
|
+
: undefined;
|
|
272
266
|
|
|
273
267
|
const formBotValue = formData.get(formBotFieldName);
|
|
274
268
|
|
|
@@ -292,32 +286,32 @@ export const action = async ({
|
|
|
292
286
|
formData.delete(formBotFieldName);
|
|
293
287
|
|
|
294
288
|
if (resource) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
289
|
+
resource.headers.push({
|
|
290
|
+
name: "Content-Type",
|
|
291
|
+
value: "application/json",
|
|
298
292
|
});
|
|
299
|
-
|
|
300
|
-
|
|
293
|
+
resource.body = Object.fromEntries(formData);
|
|
294
|
+
} else {
|
|
295
|
+
if (contactEmail === undefined) {
|
|
296
|
+
throw new Error("Contact email not found");
|
|
301
297
|
}
|
|
302
|
-
return { success: false, errors: [statusText] };
|
|
303
|
-
}
|
|
304
298
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const result = await n8nHandler({
|
|
310
|
-
formInfo: {
|
|
311
|
-
formId: [projectId, resourceName].join("--"),
|
|
299
|
+
resource = context.getDefaultActionResource?.({
|
|
300
|
+
url,
|
|
301
|
+
projectId,
|
|
302
|
+
contactEmail,
|
|
312
303
|
formData,
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
fromEmail: pageUrl.hostname + "@webstudio.email",
|
|
316
|
-
},
|
|
317
|
-
hookUrl: context.N8N_FORM_EMAIL_HOOK,
|
|
318
|
-
});
|
|
304
|
+
});
|
|
305
|
+
}
|
|
319
306
|
|
|
320
|
-
|
|
307
|
+
if (resource === undefined) {
|
|
308
|
+
throw Error("Resource not found");
|
|
309
|
+
}
|
|
310
|
+
const { ok, statusText } = await loadResource(fetch, resource);
|
|
311
|
+
if (ok) {
|
|
312
|
+
return { success: true };
|
|
313
|
+
}
|
|
314
|
+
return { success: false, errors: [statusText] };
|
|
321
315
|
} catch (error) {
|
|
322
316
|
console.error(error);
|
|
323
317
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
/* eslint-disable camelcase */
|
|
2
1
|
import { renderToString } from "react-dom/server";
|
|
3
2
|
import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
|
|
4
3
|
import { isLocalResource, loadResources } from "@webstudio-is/sdk";
|
|
5
|
-
import { ReactSdkContext } from "@webstudio-is/react-sdk";
|
|
4
|
+
import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime";
|
|
6
5
|
import { Page } from "__CLIENT__";
|
|
7
6
|
import { getPageMeta, getRemixParams, getResources } from "__SERVER__";
|
|
8
7
|
import { assetBaseUrl, imageBaseUrl, imageLoader } from "__CONSTANTS__";
|
|
@@ -8,26 +8,25 @@
|
|
|
8
8
|
"typecheck": "tsc"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@remix-run/node": "2.
|
|
12
|
-
"@remix-run/react": "2.
|
|
13
|
-
"@remix-run/server-runtime": "2.
|
|
14
|
-
"@webstudio-is/react-sdk": "0.
|
|
15
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
16
|
-
"@webstudio-is/sdk-components-react-remix": "0.
|
|
17
|
-
"@webstudio-is/sdk-components-react": "0.
|
|
18
|
-
"@webstudio-is/
|
|
19
|
-
"@webstudio-is/
|
|
20
|
-
"
|
|
21
|
-
"isbot": "^5.1.13",
|
|
11
|
+
"@remix-run/node": "2.11.0",
|
|
12
|
+
"@remix-run/react": "2.11.0",
|
|
13
|
+
"@remix-run/server-runtime": "2.11.0",
|
|
14
|
+
"@webstudio-is/react-sdk": "0.175.0",
|
|
15
|
+
"@webstudio-is/sdk-components-react-radix": "0.175.0",
|
|
16
|
+
"@webstudio-is/sdk-components-react-remix": "0.175.0",
|
|
17
|
+
"@webstudio-is/sdk-components-react": "0.175.0",
|
|
18
|
+
"@webstudio-is/image": "0.175.0",
|
|
19
|
+
"@webstudio-is/sdk": "0.175.0",
|
|
20
|
+
"isbot": "^5.1.17",
|
|
22
21
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
23
22
|
"react-dom": "18.3.0-canary-14898b6a9-20240318"
|
|
24
23
|
},
|
|
25
24
|
"devDependencies": {
|
|
26
|
-
"@remix-run/dev": "2.
|
|
25
|
+
"@remix-run/dev": "2.11.0",
|
|
27
26
|
"@types/react": "^18.2.70",
|
|
28
27
|
"@types/react-dom": "^18.2.25",
|
|
29
28
|
"typescript": "5.5.2",
|
|
30
|
-
"vite": "^5.
|
|
29
|
+
"vite": "^5.4.0"
|
|
31
30
|
},
|
|
32
31
|
"engines": {
|
|
33
32
|
"node": ">=20.0.0"
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"@webstudio-is/sdk-components-react-radix": "workspace:*",
|
|
5
5
|
"@webstudio-is/sdk-components-react-remix": "workspace:*",
|
|
6
6
|
"@webstudio-is/sdk-components-react": "workspace:*",
|
|
7
|
-
"@webstudio-is/form-handlers": "workspace:*",
|
|
8
7
|
"@webstudio-is/image": "workspace:*",
|
|
9
8
|
"@webstudio-is/sdk": "workspace:*"
|
|
10
9
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PageContext } from "vike/types";
|
|
2
|
-
import { ReactSdkContext } from "@webstudio-is/react-sdk";
|
|
2
|
+
import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime";
|
|
3
3
|
import { assetBaseUrl, imageBaseUrl, imageLoader } from "__CONSTANTS__";
|
|
4
4
|
import { Page } from "__CLIENT__";
|
|
5
5
|
|
|
@@ -8,22 +8,21 @@
|
|
|
8
8
|
"typecheck": "tsc"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@webstudio-is/react-sdk": "0.
|
|
12
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
13
|
-
"@webstudio-is/sdk-components-react": "0.
|
|
14
|
-
"@webstudio-is/
|
|
15
|
-
"@webstudio-is/
|
|
16
|
-
"@webstudio-is/sdk": "0.173.0",
|
|
11
|
+
"@webstudio-is/react-sdk": "0.175.0",
|
|
12
|
+
"@webstudio-is/sdk-components-react-radix": "0.175.0",
|
|
13
|
+
"@webstudio-is/sdk-components-react": "0.175.0",
|
|
14
|
+
"@webstudio-is/image": "0.175.0",
|
|
15
|
+
"@webstudio-is/sdk": "0.175.0",
|
|
17
16
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
18
17
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
19
|
-
"vike": "^0.4.
|
|
18
|
+
"vike": "^0.4.182"
|
|
20
19
|
},
|
|
21
20
|
"devDependencies": {
|
|
22
21
|
"@types/react": "^18.2.70",
|
|
23
22
|
"@types/react-dom": "^18.2.25",
|
|
24
23
|
"@vitejs/plugin-react": "^4.3.1",
|
|
25
24
|
"typescript": "5.5.2",
|
|
26
|
-
"vite": "^5.
|
|
25
|
+
"vite": "^5.4.0"
|
|
27
26
|
},
|
|
28
27
|
"engines": {
|
|
29
28
|
"node": ">=20.0.0"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* We use mjs extension as constants in this file is shared with the build script
|
|
3
|
+
* and we use `node --eval` to extract the constants.
|
|
4
|
+
*/
|
|
5
|
+
export const assetBaseUrl = "/assets/";
|
|
6
|
+
export const imageBaseUrl = "/assets/";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @type {import("@webstudio-is/image").ImageLoader}
|
|
10
|
+
*/
|
|
11
|
+
export const imageLoader = (props) => {
|
|
12
|
+
if (URL.canParse(props.src)) {
|
|
13
|
+
return props.src;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (process.env.NODE_ENV !== "production") {
|
|
17
|
+
return imageBaseUrl + props.src;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (props.format === "raw") {
|
|
21
|
+
return imageBaseUrl + props.src;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// https://docs.netlify.com/image-cdn/overview/
|
|
25
|
+
return (
|
|
26
|
+
"/.netlify/images?url=" +
|
|
27
|
+
encodeURIComponent(imageBaseUrl + props.src) +
|
|
28
|
+
"&w=" +
|
|
29
|
+
props.width +
|
|
30
|
+
"&q=" +
|
|
31
|
+
props.quality
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* We use mjs extension as constants in this file is shared with the build script
|
|
3
|
+
* and we use `node --eval` to extract the constants.
|
|
4
|
+
*/
|
|
5
|
+
export const assetBaseUrl = "/assets/";
|
|
6
|
+
export const imageBaseUrl = "/assets/";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @type {import("@webstudio-is/image").ImageLoader}
|
|
10
|
+
*/
|
|
11
|
+
export const imageLoader = (props) => {
|
|
12
|
+
if (URL.canParse(props.src)) {
|
|
13
|
+
return props.src;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (process.env.NODE_ENV !== "production") {
|
|
17
|
+
return imageBaseUrl + props.src;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (props.format === "raw") {
|
|
21
|
+
return imageBaseUrl + props.src;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// https://vercel.com/blog/build-your-own-web-framework#automatic-image-optimization
|
|
25
|
+
return (
|
|
26
|
+
"/_vercel/image?url=" +
|
|
27
|
+
encodeURIComponent(imageBaseUrl + props.src) +
|
|
28
|
+
"&w=" +
|
|
29
|
+
props.width +
|
|
30
|
+
"&q=" +
|
|
31
|
+
props.quality
|
|
32
|
+
);
|
|
33
|
+
};
|