webstudio 0.305.0 → 0.306.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 +6717 -1804
- package/lib/content-runtime.js +2 -2
- package/package.json +23 -23
- package/templates/cloudflare/package.json +1 -1
- package/templates/defaults/app/route-templates/html.tsx +79 -13
- package/templates/defaults/app/route-templates/text.tsx +2 -2
- package/templates/defaults/app/route-templates/xml.tsx +2 -2
- package/templates/defaults/package.json +8 -8
- package/templates/react-router/app/route-templates/html.tsx +80 -14
- package/templates/react-router/app/route-templates/text.tsx +2 -2
- package/templates/react-router/app/route-templates/xml.tsx +2 -2
- package/templates/react-router/package.json +8 -8
- package/templates/react-router/vite.config.ts +15 -1
- package/templates/react-router-cloudflare/package.json +1 -1
- package/templates/ssg/app/route-templates/dynamic/+onBeforePrerenderStart.ts.template +1 -0
- package/templates/ssg/app/route-templates/{html → shared}/+data.ts +2 -2
- package/templates/ssg/app/route-templates/text/+config.ts +5 -0
- package/templates/ssg/app/route-templates/text/+onRenderHtml.ts +5 -0
- package/templates/ssg/app/route-templates/text/+route.ts.template +1 -0
- package/templates/ssg/package.json +10 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webstudio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.306.0",
|
|
4
4
|
"description": "Webstudio CLI",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"which": "^5.0.0",
|
|
54
54
|
"yargs": "^17.7.2",
|
|
55
55
|
"zod": "^4.4.3",
|
|
56
|
-
"@webstudio-is/
|
|
57
|
-
"@webstudio-is/
|
|
58
|
-
"@webstudio-is/protocol": "0.
|
|
56
|
+
"@webstudio-is/project-migrations": "0.306.0",
|
|
57
|
+
"@webstudio-is/http-client": "0.306.0",
|
|
58
|
+
"@webstudio-is/protocol": "0.306.0",
|
|
59
59
|
"@webstudio-is/sync-client": "0.0.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@types/which": "^3.0.4",
|
|
81
81
|
"@types/yargs": "^17.0.33",
|
|
82
82
|
"@vercel/react-router": "^1.1.0",
|
|
83
|
-
"@vitejs/plugin-react": "^4.
|
|
83
|
+
"@vitejs/plugin-react": "^4.7.0",
|
|
84
84
|
"h3": "^1.15.1",
|
|
85
85
|
"ipx": "^3.0.3",
|
|
86
86
|
"isbot": "^5.1.25",
|
|
@@ -95,28 +95,28 @@
|
|
|
95
95
|
"shiki": "4.4.1",
|
|
96
96
|
"ts-expect": "^1.3.0",
|
|
97
97
|
"typescript": "7.0.2",
|
|
98
|
-
"vike": "
|
|
99
|
-
"vite": "
|
|
98
|
+
"vike": "0.4.267-commit-feffb0f",
|
|
99
|
+
"vite": "7.1.12",
|
|
100
100
|
"vitest": "^3.1.2",
|
|
101
101
|
"wrangler": "4.130.0",
|
|
102
|
-
"@webstudio-is/css-engine": "0.
|
|
103
|
-
"@webstudio-is/content-engine": "0.
|
|
104
|
-
"@webstudio-is/
|
|
105
|
-
"@webstudio-is/
|
|
106
|
-
"@webstudio-is/
|
|
102
|
+
"@webstudio-is/css-engine": "0.306.0",
|
|
103
|
+
"@webstudio-is/content-engine": "0.306.0",
|
|
104
|
+
"@webstudio-is/expression": "0.306.0",
|
|
105
|
+
"@webstudio-is/fonts": "0.306.0",
|
|
106
|
+
"@webstudio-is/image": "0.306.0",
|
|
107
|
+
"@webstudio-is/react-sdk": "0.306.0",
|
|
108
|
+
"@webstudio-is/query-builder": "0.306.0",
|
|
109
|
+
"@webstudio-is/sdk": "0.306.0",
|
|
107
110
|
"@webstudio-is/project-build": "0.0.0",
|
|
108
|
-
"@webstudio-is/
|
|
109
|
-
"@webstudio-is/sdk": "0.
|
|
110
|
-
"@webstudio-is/sdk-components-
|
|
111
|
-
"@webstudio-is/sdk-components-
|
|
112
|
-
"@webstudio-is/sdk-components-react": "0.305.0",
|
|
113
|
-
"@webstudio-is/sdk-components-react-remix": "0.305.0",
|
|
114
|
-
"@webstudio-is/react-sdk": "0.305.0",
|
|
115
|
-
"@webstudio-is/sdk-components-registry": "0.305.0",
|
|
116
|
-
"@webstudio-is/vision": "0.0.0",
|
|
111
|
+
"@webstudio-is/sdk-components-react": "0.306.0",
|
|
112
|
+
"@webstudio-is/sdk-components-animation": "0.306.0",
|
|
113
|
+
"@webstudio-is/sdk-components-react-radix": "0.306.0",
|
|
114
|
+
"@webstudio-is/sdk-components-registry": "0.306.0",
|
|
117
115
|
"@webstudio-is/tsconfig": "1.0.7",
|
|
118
|
-
"@webstudio-is/sdk-components-react-
|
|
119
|
-
"@webstudio-is/
|
|
116
|
+
"@webstudio-is/sdk-components-react-remix": "0.306.0",
|
|
117
|
+
"@webstudio-is/sdk-components-react-router": "0.306.0",
|
|
118
|
+
"@webstudio-is/wsauth": "0.306.0",
|
|
119
|
+
"@webstudio-is/vision": "0.0.0"
|
|
120
120
|
},
|
|
121
121
|
"scripts": {
|
|
122
122
|
"typecheck": "tsc --noEmit",
|
|
@@ -12,12 +12,24 @@ import {
|
|
|
12
12
|
import { useLoaderData } from "@remix-run/react";
|
|
13
13
|
import {
|
|
14
14
|
isLocalResource,
|
|
15
|
-
loadResource,
|
|
16
15
|
loadResources,
|
|
16
|
+
loadResourceWithEmail,
|
|
17
|
+
loadResourcesWithEmail,
|
|
17
18
|
cachedFetch,
|
|
19
|
+
getSystemSearch,
|
|
20
|
+
} from "@webstudio-is/sdk/runtime";
|
|
21
|
+
import {
|
|
22
|
+
handleManagedFormSubmission,
|
|
23
|
+
getManagedFormFailure,
|
|
24
|
+
readFormDataWithLimit,
|
|
25
|
+
type ManagedFormResponse,
|
|
26
|
+
} from "@webstudio-is/sdk/form/server";
|
|
27
|
+
import {
|
|
28
|
+
managedFormRequestParamName,
|
|
18
29
|
formIdFieldName,
|
|
30
|
+
managedFormIdFieldName,
|
|
19
31
|
formBotFieldName,
|
|
20
|
-
} from "@webstudio-is/sdk/
|
|
32
|
+
} from "@webstudio-is/sdk/form";
|
|
21
33
|
import { authenticateRequest } from "@webstudio-is/wsauth";
|
|
22
34
|
import {
|
|
23
35
|
ReactSdkContext,
|
|
@@ -37,6 +49,8 @@ import {
|
|
|
37
49
|
} from "__CLIENT__";
|
|
38
50
|
import {
|
|
39
51
|
getResources,
|
|
52
|
+
getManagedFormSubmissions,
|
|
53
|
+
getManagedFormResourceGraph,
|
|
40
54
|
getPageMeta,
|
|
41
55
|
getRemixParams,
|
|
42
56
|
contactEmail,
|
|
@@ -46,6 +60,11 @@ import css from "__CSS__?url";
|
|
|
46
60
|
import { sitemap } from "__SITEMAP__";
|
|
47
61
|
import { authRoutes } from "__AUTH__";
|
|
48
62
|
import { createGeneratedAssetResourceFetch } from "__ASSET_QUERY_RUNTIME__";
|
|
63
|
+
import {
|
|
64
|
+
createManagedFormEmailSender,
|
|
65
|
+
createManagedFormResourceFetch,
|
|
66
|
+
validateManagedFormEmail,
|
|
67
|
+
} from "__MANAGED_FORM_FETCH__";
|
|
49
68
|
import { assetUrlsByPath } from "__ASSETS__";
|
|
50
69
|
|
|
51
70
|
const authenticateProductionRequest = (request: Request) => {
|
|
@@ -113,7 +132,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
113
132
|
const params = getRemixParams(arg.params);
|
|
114
133
|
const system = {
|
|
115
134
|
params,
|
|
116
|
-
|
|
135
|
+
...getSystemSearch(url.searchParams),
|
|
117
136
|
origin: url.origin,
|
|
118
137
|
pathname: url.pathname,
|
|
119
138
|
};
|
|
@@ -257,24 +276,66 @@ const getRequestHost = (request: Request): string =>
|
|
|
257
276
|
export const action = async ({
|
|
258
277
|
request,
|
|
259
278
|
context,
|
|
279
|
+
params,
|
|
260
280
|
}: ActionFunctionArgs): Promise<
|
|
261
|
-
{ success: true } | { success: false; errors: string[] }
|
|
281
|
+
{ success: true } | { success: false; errors: string[] } | ManagedFormResponse
|
|
262
282
|
> => {
|
|
263
283
|
authenticateProductionRequest(request);
|
|
264
284
|
|
|
285
|
+
let isManagedFormRequest = false;
|
|
265
286
|
try {
|
|
266
287
|
const url = new URL(request.url);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
288
|
+
isManagedFormRequest =
|
|
289
|
+
url.searchParams.get(managedFormRequestParamName) === "1";
|
|
290
|
+
url.searchParams.delete(managedFormRequestParamName);
|
|
291
|
+
if (!isManagedFormRequest) {
|
|
292
|
+
url.host = getRequestHost(request);
|
|
293
|
+
}
|
|
294
|
+
const formData = isManagedFormRequest
|
|
295
|
+
? await readFormDataWithLimit(request)
|
|
296
|
+
: await request.formData();
|
|
270
297
|
|
|
271
298
|
const system = {
|
|
272
|
-
params: {},
|
|
273
|
-
|
|
299
|
+
params: getRemixParams(params ?? {}),
|
|
300
|
+
...getSystemSearch(url.searchParams),
|
|
274
301
|
origin: url.origin,
|
|
275
302
|
pathname: url.pathname,
|
|
276
303
|
};
|
|
277
304
|
|
|
305
|
+
const managedFormIds = formData.getAll(managedFormIdFieldName);
|
|
306
|
+
if (!isManagedFormRequest && managedFormIds.length > 0) {
|
|
307
|
+
throw new Error("Invalid Form submission");
|
|
308
|
+
}
|
|
309
|
+
if (isManagedFormRequest) {
|
|
310
|
+
if (managedFormIds.length !== 1 || formData.has(formIdFieldName)) {
|
|
311
|
+
throw new Error("Invalid Form submission");
|
|
312
|
+
}
|
|
313
|
+
const protectedFetch = createManagedFormResourceFetch({
|
|
314
|
+
request,
|
|
315
|
+
context,
|
|
316
|
+
projectDomain,
|
|
317
|
+
});
|
|
318
|
+
return await handleManagedFormSubmission({
|
|
319
|
+
request,
|
|
320
|
+
formData,
|
|
321
|
+
url,
|
|
322
|
+
system,
|
|
323
|
+
configuration: (id) => getManagedFormSubmissions().get(id),
|
|
324
|
+
getGraph: (id, values) => getManagedFormResourceGraph(id, values),
|
|
325
|
+
createEmailSender: (data) =>
|
|
326
|
+
createManagedFormEmailSender({ context, formData: data, projectId }),
|
|
327
|
+
validateEmail: validateManagedFormEmail,
|
|
328
|
+
resourceFetch: protectedFetch,
|
|
329
|
+
validateDestination: protectedFetch.validateDestination,
|
|
330
|
+
trustedIp:
|
|
331
|
+
typeof context === "object" &&
|
|
332
|
+
context !== null &&
|
|
333
|
+
"cloudflare" in context
|
|
334
|
+
? request.headers.get("cf-connecting-ip") ?? undefined
|
|
335
|
+
: undefined,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
278
339
|
const resourceName = formData.get(formIdFieldName);
|
|
279
340
|
const generatedResources = getResources({ system });
|
|
280
341
|
const actionResource =
|
|
@@ -308,7 +369,7 @@ export const action = async ({
|
|
|
308
369
|
formData.delete(formIdFieldName);
|
|
309
370
|
formData.delete(formBotFieldName);
|
|
310
371
|
|
|
311
|
-
let result: Awaited<ReturnType<typeof
|
|
372
|
+
let result: Awaited<ReturnType<typeof loadResourceWithEmail>>;
|
|
312
373
|
if (actionResource === undefined) {
|
|
313
374
|
if (contactEmail === undefined) {
|
|
314
375
|
throw new Error("Contact email not found");
|
|
@@ -322,14 +383,14 @@ export const action = async ({
|
|
|
322
383
|
if (resource === undefined) {
|
|
323
384
|
throw Error("Resource not found");
|
|
324
385
|
}
|
|
325
|
-
result = await
|
|
386
|
+
result = await loadResourceWithEmail(fetch, resource);
|
|
326
387
|
} else {
|
|
327
388
|
const actionFetch = await createGeneratedAssetResourceFetch({
|
|
328
389
|
request,
|
|
329
390
|
context,
|
|
330
391
|
fallback: customFetch,
|
|
331
392
|
});
|
|
332
|
-
const results = await
|
|
393
|
+
const results = await loadResourcesWithEmail(
|
|
333
394
|
actionFetch,
|
|
334
395
|
{
|
|
335
396
|
...generatedResources.data,
|
|
@@ -348,7 +409,7 @@ export const action = async ({
|
|
|
348
409
|
if (actionResult === undefined) {
|
|
349
410
|
throw Error("Resource not found");
|
|
350
411
|
}
|
|
351
|
-
result = actionResult as Awaited<ReturnType<typeof
|
|
412
|
+
result = actionResult as Awaited<ReturnType<typeof loadResourceWithEmail>>;
|
|
352
413
|
}
|
|
353
414
|
const { ok, statusText } = result;
|
|
354
415
|
if (ok) {
|
|
@@ -358,6 +419,11 @@ export const action = async ({
|
|
|
358
419
|
} catch (error) {
|
|
359
420
|
console.error(error);
|
|
360
421
|
|
|
422
|
+
if (isManagedFormRequest) {
|
|
423
|
+
return getManagedFormFailure(
|
|
424
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
425
|
+
);
|
|
426
|
+
}
|
|
361
427
|
return {
|
|
362
428
|
success: false,
|
|
363
429
|
errors: [error instanceof Error ? error.message : "Unknown error"],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
|
|
2
|
-
import { isLocalResource, loadResources } from "@webstudio-is/sdk/runtime";
|
|
2
|
+
import { isLocalResource, loadResources, getSystemSearch } from "@webstudio-is/sdk/runtime";
|
|
3
3
|
import { authenticateRequest } from "@webstudio-is/wsauth";
|
|
4
4
|
import { projectDomain } from "__CLIENT__";
|
|
5
5
|
import { getPageMeta, getRemixParams, getResources } from "__SERVER__";
|
|
@@ -71,7 +71,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
71
71
|
|
|
72
72
|
const system = {
|
|
73
73
|
params,
|
|
74
|
-
|
|
74
|
+
...getSystemSearch(url.searchParams),
|
|
75
75
|
origin: url.origin,
|
|
76
76
|
pathname: url.pathname,
|
|
77
77
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderToString } from "react-dom/server";
|
|
2
2
|
import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
|
|
3
|
-
import { isLocalResource, loadResources } from "@webstudio-is/sdk/runtime";
|
|
3
|
+
import { isLocalResource, loadResources, getSystemSearch } from "@webstudio-is/sdk/runtime";
|
|
4
4
|
import { authenticateRequest } from "@webstudio-is/wsauth";
|
|
5
5
|
import {
|
|
6
6
|
ReactSdkContext,
|
|
@@ -79,7 +79,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
79
79
|
|
|
80
80
|
const system = {
|
|
81
81
|
params,
|
|
82
|
-
|
|
82
|
+
...getSystemSearch(url.searchParams),
|
|
83
83
|
origin: url.origin,
|
|
84
84
|
pathname: url.pathname,
|
|
85
85
|
};
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
"@remix-run/node": "2.16.5",
|
|
14
14
|
"@remix-run/react": "2.16.5",
|
|
15
15
|
"@remix-run/server-runtime": "2.16.5",
|
|
16
|
-
"@webstudio-is/image": "0.
|
|
17
|
-
"@webstudio-is/react-sdk": "0.
|
|
18
|
-
"@webstudio-is/sdk": "0.
|
|
19
|
-
"@webstudio-is/sdk-components-react": "0.
|
|
20
|
-
"@webstudio-is/sdk-components-animation": "0.
|
|
21
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
22
|
-
"@webstudio-is/sdk-components-react-remix": "0.
|
|
23
|
-
"@webstudio-is/wsauth": "0.
|
|
16
|
+
"@webstudio-is/image": "0.306.0",
|
|
17
|
+
"@webstudio-is/react-sdk": "0.306.0",
|
|
18
|
+
"@webstudio-is/sdk": "0.306.0",
|
|
19
|
+
"@webstudio-is/sdk-components-react": "0.306.0",
|
|
20
|
+
"@webstudio-is/sdk-components-animation": "0.306.0",
|
|
21
|
+
"@webstudio-is/sdk-components-react-radix": "0.306.0",
|
|
22
|
+
"@webstudio-is/sdk-components-react-remix": "0.306.0",
|
|
23
|
+
"@webstudio-is/wsauth": "0.306.0",
|
|
24
24
|
"isbot": "^5.1.25",
|
|
25
25
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
26
26
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
@@ -12,12 +12,24 @@ import {
|
|
|
12
12
|
} from "react-router";
|
|
13
13
|
import {
|
|
14
14
|
isLocalResource,
|
|
15
|
-
loadResource,
|
|
16
15
|
loadResources,
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
loadResourceWithEmail,
|
|
17
|
+
loadResourcesWithEmail,
|
|
18
|
+
getSystemSearch,
|
|
19
19
|
cachedFetch,
|
|
20
20
|
} from "@webstudio-is/sdk/runtime";
|
|
21
|
+
import {
|
|
22
|
+
handleManagedFormSubmission,
|
|
23
|
+
getManagedFormFailure,
|
|
24
|
+
readFormDataWithLimit,
|
|
25
|
+
type ManagedFormResponse,
|
|
26
|
+
} from "@webstudio-is/sdk/form/server";
|
|
27
|
+
import {
|
|
28
|
+
managedFormRequestParamName,
|
|
29
|
+
formIdFieldName,
|
|
30
|
+
managedFormIdFieldName,
|
|
31
|
+
formBotFieldName,
|
|
32
|
+
} from "@webstudio-is/sdk/form";
|
|
21
33
|
import { authenticateProjectRequest } from "@webstudio-is/wsauth";
|
|
22
34
|
import {
|
|
23
35
|
ReactSdkContext,
|
|
@@ -36,6 +48,8 @@ import {
|
|
|
36
48
|
} from "__CLIENT__";
|
|
37
49
|
import {
|
|
38
50
|
getResources,
|
|
51
|
+
getManagedFormSubmissions,
|
|
52
|
+
getManagedFormResourceGraph,
|
|
39
53
|
getPageMeta,
|
|
40
54
|
getRemixParams,
|
|
41
55
|
contactEmail,
|
|
@@ -45,6 +59,11 @@ import css from "__CSS__?url";
|
|
|
45
59
|
import { sitemap } from "__SITEMAP__";
|
|
46
60
|
import { authRoutes } from "__AUTH__";
|
|
47
61
|
import { createGeneratedAssetResourceFetch } from "__ASSET_QUERY_RUNTIME__";
|
|
62
|
+
import {
|
|
63
|
+
createManagedFormEmailSender,
|
|
64
|
+
createManagedFormResourceFetch,
|
|
65
|
+
validateManagedFormEmail,
|
|
66
|
+
} from "__MANAGED_FORM_FETCH__";
|
|
48
67
|
import { assetUrlsByPath } from "__ASSETS__";
|
|
49
68
|
|
|
50
69
|
const customFetch: typeof fetch = (input, init) => {
|
|
@@ -98,7 +117,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
98
117
|
const params = getRemixParams(arg.params);
|
|
99
118
|
const system = {
|
|
100
119
|
params,
|
|
101
|
-
|
|
120
|
+
...getSystemSearch(url.searchParams),
|
|
102
121
|
origin: url.origin,
|
|
103
122
|
pathname: url.pathname,
|
|
104
123
|
};
|
|
@@ -242,24 +261,66 @@ const getRequestHost = (request: Request): string =>
|
|
|
242
261
|
export const action = async ({
|
|
243
262
|
request,
|
|
244
263
|
context,
|
|
264
|
+
params,
|
|
245
265
|
}: ActionFunctionArgs): Promise<
|
|
246
|
-
{ success: true } | { success: false; errors: string[] }
|
|
266
|
+
{ success: true } | { success: false; errors: string[] } | ManagedFormResponse
|
|
247
267
|
> => {
|
|
248
268
|
authenticateProjectRequest(request, authRoutes, projectDomain);
|
|
249
269
|
|
|
270
|
+
let isManagedFormRequest = false;
|
|
250
271
|
try {
|
|
251
272
|
const url = new URL(request.url);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
273
|
+
isManagedFormRequest =
|
|
274
|
+
url.searchParams.get(managedFormRequestParamName) === "1";
|
|
275
|
+
url.searchParams.delete(managedFormRequestParamName);
|
|
276
|
+
if (!isManagedFormRequest) {
|
|
277
|
+
url.host = getRequestHost(request);
|
|
278
|
+
}
|
|
279
|
+
const formData = isManagedFormRequest
|
|
280
|
+
? await readFormDataWithLimit(request)
|
|
281
|
+
: await request.formData();
|
|
255
282
|
|
|
256
283
|
const system = {
|
|
257
|
-
params: {},
|
|
258
|
-
|
|
284
|
+
params: getRemixParams(params ?? {}),
|
|
285
|
+
...getSystemSearch(url.searchParams),
|
|
259
286
|
origin: url.origin,
|
|
260
287
|
pathname: url.pathname,
|
|
261
288
|
};
|
|
262
289
|
|
|
290
|
+
const managedFormIds = formData.getAll(managedFormIdFieldName);
|
|
291
|
+
if (!isManagedFormRequest && managedFormIds.length > 0) {
|
|
292
|
+
throw new Error("Invalid Form submission");
|
|
293
|
+
}
|
|
294
|
+
if (isManagedFormRequest) {
|
|
295
|
+
if (managedFormIds.length !== 1 || formData.has(formIdFieldName)) {
|
|
296
|
+
throw new Error("Invalid Form submission");
|
|
297
|
+
}
|
|
298
|
+
const protectedFetch = createManagedFormResourceFetch({
|
|
299
|
+
request,
|
|
300
|
+
context,
|
|
301
|
+
projectDomain,
|
|
302
|
+
});
|
|
303
|
+
return await handleManagedFormSubmission({
|
|
304
|
+
request,
|
|
305
|
+
formData,
|
|
306
|
+
url,
|
|
307
|
+
system,
|
|
308
|
+
configuration: (formId) => getManagedFormSubmissions().get(formId),
|
|
309
|
+
getGraph: getManagedFormResourceGraph,
|
|
310
|
+
createEmailSender: (formData) =>
|
|
311
|
+
createManagedFormEmailSender({ context, formData, projectId }),
|
|
312
|
+
validateEmail: validateManagedFormEmail,
|
|
313
|
+
resourceFetch: protectedFetch,
|
|
314
|
+
validateDestination: protectedFetch.validateDestination,
|
|
315
|
+
trustedIp:
|
|
316
|
+
typeof context === "object" &&
|
|
317
|
+
context !== null &&
|
|
318
|
+
"cloudflare" in context
|
|
319
|
+
? request.headers.get("cf-connecting-ip") ?? undefined
|
|
320
|
+
: undefined,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
263
324
|
const resourceName = formData.get(formIdFieldName);
|
|
264
325
|
const generatedResources = getResources({ system });
|
|
265
326
|
const actionResource =
|
|
@@ -293,7 +354,7 @@ export const action = async ({
|
|
|
293
354
|
formData.delete(formIdFieldName);
|
|
294
355
|
formData.delete(formBotFieldName);
|
|
295
356
|
|
|
296
|
-
let result: Awaited<ReturnType<typeof
|
|
357
|
+
let result: Awaited<ReturnType<typeof loadResourceWithEmail>>;
|
|
297
358
|
if (actionResource === undefined) {
|
|
298
359
|
if (contactEmail === undefined) {
|
|
299
360
|
throw new Error("Contact email not found");
|
|
@@ -307,14 +368,14 @@ export const action = async ({
|
|
|
307
368
|
if (resource === undefined) {
|
|
308
369
|
throw Error("Resource not found");
|
|
309
370
|
}
|
|
310
|
-
result = await
|
|
371
|
+
result = await loadResourceWithEmail(fetch, resource);
|
|
311
372
|
} else {
|
|
312
373
|
const actionFetch = await createGeneratedAssetResourceFetch({
|
|
313
374
|
request,
|
|
314
375
|
context,
|
|
315
376
|
fallback: customFetch,
|
|
316
377
|
});
|
|
317
|
-
const results = await
|
|
378
|
+
const results = await loadResourcesWithEmail(
|
|
318
379
|
actionFetch,
|
|
319
380
|
{
|
|
320
381
|
...generatedResources.data,
|
|
@@ -333,7 +394,7 @@ export const action = async ({
|
|
|
333
394
|
if (actionResult === undefined) {
|
|
334
395
|
throw Error("Resource not found");
|
|
335
396
|
}
|
|
336
|
-
result = actionResult as Awaited<ReturnType<typeof
|
|
397
|
+
result = actionResult as Awaited<ReturnType<typeof loadResourceWithEmail>>;
|
|
337
398
|
}
|
|
338
399
|
const { ok, statusText } = result;
|
|
339
400
|
if (ok) {
|
|
@@ -343,6 +404,11 @@ export const action = async ({
|
|
|
343
404
|
} catch (error) {
|
|
344
405
|
console.error(error);
|
|
345
406
|
|
|
407
|
+
if (isManagedFormRequest) {
|
|
408
|
+
return getManagedFormFailure(
|
|
409
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
410
|
+
);
|
|
411
|
+
}
|
|
346
412
|
return {
|
|
347
413
|
success: false,
|
|
348
414
|
errors: [error instanceof Error ? error.message : "Unknown error"],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type LoaderFunctionArgs, redirect } from "react-router";
|
|
2
|
-
import { isLocalResource, loadResources } from "@webstudio-is/sdk/runtime";
|
|
2
|
+
import { isLocalResource, loadResources, getSystemSearch } from "@webstudio-is/sdk/runtime";
|
|
3
3
|
import { authenticateProjectRequest } from "@webstudio-is/wsauth";
|
|
4
4
|
import { projectDomain } from "__CLIENT__";
|
|
5
5
|
import { getPageMeta, getRemixParams, getResources } from "__SERVER__";
|
|
@@ -57,7 +57,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
57
57
|
|
|
58
58
|
const system = {
|
|
59
59
|
params,
|
|
60
|
-
|
|
60
|
+
...getSystemSearch(url.searchParams),
|
|
61
61
|
origin: url.origin,
|
|
62
62
|
pathname: url.pathname,
|
|
63
63
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderToString } from "react-dom/server";
|
|
2
2
|
import { type LoaderFunctionArgs, redirect } from "react-router";
|
|
3
|
-
import { isLocalResource, loadResources } from "@webstudio-is/sdk/runtime";
|
|
3
|
+
import { isLocalResource, loadResources, getSystemSearch } from "@webstudio-is/sdk/runtime";
|
|
4
4
|
import { authenticateProjectRequest } from "@webstudio-is/wsauth";
|
|
5
5
|
import {
|
|
6
6
|
ReactSdkContext,
|
|
@@ -65,7 +65,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
65
65
|
|
|
66
66
|
const system = {
|
|
67
67
|
params,
|
|
68
|
-
|
|
68
|
+
...getSystemSearch(url.searchParams),
|
|
69
69
|
origin: url.origin,
|
|
70
70
|
pathname: url.pathname,
|
|
71
71
|
};
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
"@react-router/fs-routes": "^7.5.3",
|
|
16
16
|
"@react-router/node": "^7.5.3",
|
|
17
17
|
"@react-router/serve": "^7.5.3",
|
|
18
|
-
"@webstudio-is/image": "0.
|
|
19
|
-
"@webstudio-is/react-sdk": "0.
|
|
20
|
-
"@webstudio-is/sdk": "0.
|
|
21
|
-
"@webstudio-is/sdk-components-animation": "0.
|
|
22
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
23
|
-
"@webstudio-is/sdk-components-react-router": "0.
|
|
24
|
-
"@webstudio-is/sdk-components-react": "0.
|
|
25
|
-
"@webstudio-is/wsauth": "0.
|
|
18
|
+
"@webstudio-is/image": "0.306.0",
|
|
19
|
+
"@webstudio-is/react-sdk": "0.306.0",
|
|
20
|
+
"@webstudio-is/sdk": "0.306.0",
|
|
21
|
+
"@webstudio-is/sdk-components-animation": "0.306.0",
|
|
22
|
+
"@webstudio-is/sdk-components-react-radix": "0.306.0",
|
|
23
|
+
"@webstudio-is/sdk-components-react-router": "0.306.0",
|
|
24
|
+
"@webstudio-is/sdk-components-react": "0.306.0",
|
|
25
|
+
"@webstudio-is/wsauth": "0.306.0",
|
|
26
26
|
"isbot": "^5.1.25",
|
|
27
27
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
28
28
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { defineConfig, searchForWorkspaceRoot } from "vite";
|
|
2
4
|
import { reactRouter } from "@react-router/dev/vite";
|
|
3
5
|
|
|
4
6
|
const sourceConditions =
|
|
5
7
|
process.env.WEBSTUDIO_LOCAL_CLI_BOOTSTRAPPED === "1" ? ["webstudio"] : [];
|
|
8
|
+
const templateDirectory = fileURLToPath(new URL(".", import.meta.url));
|
|
9
|
+
const templateNodeModules = new URL("./node_modules", import.meta.url);
|
|
6
10
|
|
|
7
11
|
export default defineConfig({
|
|
8
12
|
// Local previews share node_modules, but must not share optimizer state.
|
|
@@ -10,6 +14,16 @@ export default defineConfig({
|
|
|
10
14
|
plugins: [reactRouter()],
|
|
11
15
|
server: {
|
|
12
16
|
hmr: process.env.WEBSTUDIO_PREVIEW_HMR === "disabled" ? false : undefined,
|
|
17
|
+
// The local CLI links node_modules from its source workspace. Vite must
|
|
18
|
+
// serve React Router's client entry from that workspace to hydrate Preview.
|
|
19
|
+
fs: {
|
|
20
|
+
allow: [
|
|
21
|
+
templateDirectory,
|
|
22
|
+
...(existsSync(templateNodeModules)
|
|
23
|
+
? [searchForWorkspaceRoot(realpathSync(templateNodeModules))]
|
|
24
|
+
: []),
|
|
25
|
+
],
|
|
26
|
+
},
|
|
13
27
|
},
|
|
14
28
|
resolve: {
|
|
15
29
|
conditions: [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const onBeforePrerenderStart = () => __PRERENDER_PATHS__;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PageContextServer } from "vike/types";
|
|
2
|
-
import { isLocalResource, loadResources } from "@webstudio-is/sdk/runtime";
|
|
2
|
+
import { isLocalResource, loadResources, getSystemSearch } from "@webstudio-is/sdk/runtime";
|
|
3
3
|
import { getPageMeta, getResources } from "__SERVER__";
|
|
4
4
|
import { assets } from "__ASSETS__";
|
|
5
5
|
import {
|
|
@@ -57,7 +57,7 @@ export const data = async (pageContext: PageContextServer) => {
|
|
|
57
57
|
const params = pageContext.routeParams;
|
|
58
58
|
const system = {
|
|
59
59
|
params,
|
|
60
|
-
|
|
60
|
+
...getSystemSearch(url.searchParams),
|
|
61
61
|
origin: url.origin,
|
|
62
62
|
pathname: url.pathname,
|
|
63
63
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default __PAGE_PATH__;
|