webstudio 0.168.0 → 0.173.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 +295 -147
- package/package.json +20 -21
- package/templates/cloudflare/functions/[[path]].ts +2 -0
- package/templates/cloudflare/package.json +4 -6
- package/templates/cloudflare/tsconfig.json +3 -18
- package/templates/defaults/app/route-templates/default-sitemap.tsx +1 -1
- package/templates/defaults/app/route-templates/html.tsx +72 -58
- package/templates/defaults/app/route-templates/redirect.tsx +6 -0
- package/templates/defaults/app/route-templates/xml.tsx +25 -10
- package/templates/defaults/package.json +14 -14
- package/templates/defaults/tsconfig.json +5 -6
- package/templates/internal/tsconfig.json +1 -21
- package/templates/netlify-edge-functions/package.json +1 -1
- package/templates/netlify-functions/package.json +1 -1
- package/templates/saas-helpers/tsconfig.json +3 -19
- package/templates/ssg/app/constants.mjs +13 -0
- package/templates/ssg/app/route-templates/html/+Head.tsx +92 -0
- package/templates/ssg/app/route-templates/html/+Page.tsx +22 -0
- package/templates/ssg/app/route-templates/html/+data.ts +37 -0
- package/templates/ssg/package.json +31 -0
- package/templates/ssg/pages/+config.ts +12 -0
- package/templates/ssg/public/favicon.ico +0 -0
- package/templates/ssg/renderer/+onRenderClient.tsx +30 -0
- package/templates/ssg/renderer/+onRenderHtml.tsx +29 -0
- package/templates/ssg/tsconfig.json +22 -0
- package/templates/ssg/vike.d.ts +26 -0
- package/templates/ssg/vite.config.ts +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webstudio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.173.0",
|
|
4
4
|
"description": "Webstudio CLI",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -35,45 +35,44 @@
|
|
|
35
35
|
"parse5": "7.1.2",
|
|
36
36
|
"picocolors": "^1.0.1",
|
|
37
37
|
"strip-indent": "^4.0.0",
|
|
38
|
-
"title-case": "^4.1.0",
|
|
39
38
|
"yargs": "^17.7.2",
|
|
40
39
|
"zod": "^3.22.4",
|
|
41
|
-
"@webstudio-is/
|
|
42
|
-
"@webstudio-is/
|
|
43
|
-
"@webstudio-is/sdk": "0.
|
|
44
|
-
"@webstudio-is/
|
|
45
|
-
"@webstudio-is/sdk
|
|
46
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
47
|
-
"@webstudio-is/sdk-components-react-remix": "0.
|
|
40
|
+
"@webstudio-is/http-client": "0.173.0",
|
|
41
|
+
"@webstudio-is/sdk": "0.173.0",
|
|
42
|
+
"@webstudio-is/sdk-components-react": "0.173.0",
|
|
43
|
+
"@webstudio-is/image": "0.173.0",
|
|
44
|
+
"@webstudio-is/react-sdk": "0.173.0",
|
|
45
|
+
"@webstudio-is/sdk-components-react-radix": "0.173.0",
|
|
46
|
+
"@webstudio-is/sdk-components-react-remix": "0.173.0"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
49
|
"@jest/globals": "^29.7.0",
|
|
51
50
|
"@netlify/remix-adapter": "^2.4.0",
|
|
52
51
|
"@netlify/remix-edge-adapter": "3.3.0",
|
|
53
|
-
"@remix-run/cloudflare": "^2.
|
|
54
|
-
"@remix-run/cloudflare-pages": "^2.
|
|
55
|
-
"@remix-run/dev": "^2.
|
|
56
|
-
"@remix-run/node": "^2.
|
|
57
|
-
"@remix-run/react": "^2.
|
|
58
|
-
"@remix-run/server-runtime": "^2.
|
|
52
|
+
"@remix-run/cloudflare": "^2.10.3",
|
|
53
|
+
"@remix-run/cloudflare-pages": "^2.10.3",
|
|
54
|
+
"@remix-run/dev": "^2.10.3",
|
|
55
|
+
"@remix-run/node": "^2.10.3",
|
|
56
|
+
"@remix-run/react": "^2.10.3",
|
|
57
|
+
"@remix-run/server-runtime": "^2.10.3",
|
|
59
58
|
"@types/node": "^20.12.7",
|
|
60
59
|
"@types/react": "^18.2.70",
|
|
61
60
|
"@types/react-dom": "^18.2.25",
|
|
62
61
|
"@types/yargs": "^17.0.32",
|
|
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
|
-
"typescript": "5.
|
|
66
|
-
"
|
|
67
|
-
"
|
|
65
|
+
"typescript": "5.5.2",
|
|
66
|
+
"vike": "^0.4.180",
|
|
67
|
+
"vite": "^5.3.4",
|
|
68
|
+
"wrangler": "^3.63.2",
|
|
69
|
+
"@webstudio-is/form-handlers": "0.173.0",
|
|
68
70
|
"@webstudio-is/jest-config": "1.0.7",
|
|
69
|
-
"@webstudio-is/form-handlers": "0.168.0",
|
|
70
71
|
"@webstudio-is/tsconfig": "1.0.7"
|
|
71
72
|
},
|
|
72
73
|
"scripts": {
|
|
73
74
|
"typecheck": "tsc",
|
|
74
|
-
"checks": "pnpm typecheck",
|
|
75
75
|
"build": "rm -rf lib && esbuild src/cli.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
76
|
-
"dev": "esbuild src/cli.ts --watch --bundle --format=esm --packages=external --outdir=./lib",
|
|
77
76
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest"
|
|
78
77
|
}
|
|
79
78
|
}
|
|
@@ -4,4 +4,6 @@ import { createPagesFunctionHandler } from "@remix-run/cloudflare-pages";
|
|
|
4
4
|
// @ts-ignore - the server build file is generated by `remix vite:build`
|
|
5
5
|
import * as build from "../build/server";
|
|
6
6
|
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
8
|
+
// @ts-ignore - the server build file is generated by `remix vite:build`
|
|
7
9
|
export const onRequest = createPagesFunctionHandler({ build });
|
|
@@ -12,13 +12,11 @@
|
|
|
12
12
|
"build-cf-types": "wrangler types"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@remix-run/cloudflare": "2.
|
|
16
|
-
"@remix-run/cloudflare-pages": "2.
|
|
17
|
-
"isbot": "^5.1.8"
|
|
15
|
+
"@remix-run/cloudflare": "2.10.3",
|
|
16
|
+
"@remix-run/cloudflare-pages": "2.10.3"
|
|
18
17
|
},
|
|
19
18
|
"devDependencies": {
|
|
20
|
-
"@cloudflare/workers-types": "^4.
|
|
21
|
-
"wrangler": "^3.
|
|
22
|
-
"miniflare": "^3.20231030.4"
|
|
19
|
+
"@cloudflare/workers-types": "^4.20240620.0",
|
|
20
|
+
"wrangler": "^3.63.2"
|
|
23
21
|
}
|
|
24
22
|
}
|
|
@@ -8,26 +8,11 @@
|
|
|
8
8
|
"**/.client/**/*.tsx"
|
|
9
9
|
],
|
|
10
10
|
"compilerOptions": {
|
|
11
|
-
"lib": ["DOM", "DOM.Iterable", "ES2023"],
|
|
12
11
|
"types": [
|
|
13
12
|
"@remix-run/cloudflare",
|
|
14
13
|
"vite/client",
|
|
15
|
-
"@cloudflare/workers-types/2023-07-01"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"esModuleInterop": true,
|
|
19
|
-
"jsx": "react-jsx",
|
|
20
|
-
"module": "ESNext",
|
|
21
|
-
"moduleResolution": "Bundler",
|
|
22
|
-
"resolveJsonModule": true,
|
|
23
|
-
"target": "ES2022",
|
|
24
|
-
"strict": true,
|
|
25
|
-
"allowJs": true,
|
|
26
|
-
"skipLibCheck": true,
|
|
27
|
-
"forceConsistentCasingInFileNames": true,
|
|
28
|
-
"baseUrl": ".",
|
|
29
|
-
|
|
30
|
-
// Vite takes care of building everything, not tsc.
|
|
31
|
-
"noEmit": true
|
|
14
|
+
"@cloudflare/workers-types/2023-07-01",
|
|
15
|
+
"@webstudio-is/react-sdk/placeholder"
|
|
16
|
+
]
|
|
32
17
|
}
|
|
33
18
|
}
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
redirect,
|
|
11
11
|
} from "@remix-run/server-runtime";
|
|
12
12
|
import { useLoaderData } from "@remix-run/react";
|
|
13
|
+
import {
|
|
14
|
+
isLocalResource,
|
|
15
|
+
loadResource,
|
|
16
|
+
loadResources,
|
|
17
|
+
} from "@webstudio-is/sdk";
|
|
13
18
|
import { ReactSdkContext } from "@webstudio-is/react-sdk";
|
|
14
19
|
import {
|
|
15
20
|
n8nHandler,
|
|
@@ -20,21 +25,34 @@ import {
|
|
|
20
25
|
Page,
|
|
21
26
|
siteName,
|
|
22
27
|
favIconAsset,
|
|
23
|
-
socialImageAsset,
|
|
24
28
|
pageFontAssets,
|
|
25
29
|
pageBackgroundImageAssets,
|
|
26
|
-
} from "
|
|
30
|
+
} from "__CLIENT__";
|
|
27
31
|
import {
|
|
28
|
-
|
|
29
|
-
loadResources,
|
|
32
|
+
getResources,
|
|
30
33
|
getPageMeta,
|
|
31
34
|
getRemixParams,
|
|
32
35
|
projectId,
|
|
33
36
|
contactEmail,
|
|
34
|
-
} from "
|
|
37
|
+
} from "__SERVER__";
|
|
38
|
+
import { assetBaseUrl, imageBaseUrl, imageLoader } from "__CONSTANTS__";
|
|
39
|
+
import css from "__CSS__?url";
|
|
40
|
+
import { sitemap } from "__SITEMAP__";
|
|
41
|
+
|
|
42
|
+
const customFetch: typeof fetch = (input, init) => {
|
|
43
|
+
if (typeof input !== "string") {
|
|
44
|
+
return fetch(input, init);
|
|
45
|
+
}
|
|
35
46
|
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
if (isLocalResource(input, "sitemap.xml")) {
|
|
48
|
+
// @todo: dynamic import sitemap ???
|
|
49
|
+
const response = new Response(JSON.stringify(sitemap));
|
|
50
|
+
response.headers.set("content-type", "application/json; charset=utf-8");
|
|
51
|
+
return Promise.resolve(response);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return fetch(input, init);
|
|
55
|
+
};
|
|
38
56
|
|
|
39
57
|
export const loader = async (arg: LoaderFunctionArgs) => {
|
|
40
58
|
const url = new URL(arg.request.url);
|
|
@@ -52,7 +70,10 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
52
70
|
origin: url.origin,
|
|
53
71
|
};
|
|
54
72
|
|
|
55
|
-
const resources = await loadResources(
|
|
73
|
+
const resources = await loadResources(
|
|
74
|
+
customFetch,
|
|
75
|
+
getResources({ system }).data
|
|
76
|
+
);
|
|
56
77
|
const pageMeta = getPageMeta({ system, resources });
|
|
57
78
|
|
|
58
79
|
if (pageMeta.redirect) {
|
|
@@ -66,11 +87,14 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
66
87
|
// typecheck
|
|
67
88
|
arg.context.EXCLUDE_FROM_SEARCH satisfies boolean;
|
|
68
89
|
|
|
90
|
+
if (arg.context.EXCLUDE_FROM_SEARCH) {
|
|
91
|
+
pageMeta.excludePageFromSearch = arg.context.EXCLUDE_FROM_SEARCH;
|
|
92
|
+
}
|
|
93
|
+
|
|
69
94
|
return json(
|
|
70
95
|
{
|
|
71
96
|
host,
|
|
72
97
|
url: url.href,
|
|
73
|
-
excludeFromSearch: arg.context.EXCLUDE_FROM_SEARCH,
|
|
74
98
|
system,
|
|
75
99
|
resources,
|
|
76
100
|
pageMeta,
|
|
@@ -86,7 +110,7 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
86
110
|
);
|
|
87
111
|
};
|
|
88
112
|
|
|
89
|
-
export const headers: HeadersFunction = (
|
|
113
|
+
export const headers: HeadersFunction = () => {
|
|
90
114
|
return {
|
|
91
115
|
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
92
116
|
};
|
|
@@ -134,7 +158,7 @@ export const meta: MetaFunction<typeof loader> = ({ data }) => {
|
|
|
134
158
|
});
|
|
135
159
|
}
|
|
136
160
|
|
|
137
|
-
if (pageMeta.excludePageFromSearch
|
|
161
|
+
if (pageMeta.excludePageFromSearch) {
|
|
138
162
|
metas.push({
|
|
139
163
|
name: "robots",
|
|
140
164
|
content: "noindex, nofollow",
|
|
@@ -152,11 +176,11 @@ export const meta: MetaFunction<typeof loader> = ({ data }) => {
|
|
|
152
176
|
});
|
|
153
177
|
}
|
|
154
178
|
|
|
155
|
-
if (
|
|
179
|
+
if (pageMeta.socialImageAssetName) {
|
|
156
180
|
metas.push({
|
|
157
181
|
property: "og:image",
|
|
158
182
|
content: `https://${data.host}${imageLoader({
|
|
159
|
-
src:
|
|
183
|
+
src: pageMeta.socialImageAssetName,
|
|
160
184
|
// Do not transform social image (not enough information do we need to do this)
|
|
161
185
|
format: "raw",
|
|
162
186
|
})}`,
|
|
@@ -220,19 +244,6 @@ export const links: LinksFunction = () => {
|
|
|
220
244
|
const getRequestHost = (request: Request): string =>
|
|
221
245
|
request.headers.get("x-forwarded-host") || request.headers.get("host") || "";
|
|
222
246
|
|
|
223
|
-
const getMethod = (value: string | undefined) => {
|
|
224
|
-
if (value === undefined) {
|
|
225
|
-
return "post";
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
switch (value.toLowerCase()) {
|
|
229
|
-
case "get":
|
|
230
|
-
return "get";
|
|
231
|
-
default:
|
|
232
|
-
return "post";
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
247
|
export const action = async ({
|
|
237
248
|
request,
|
|
238
249
|
context,
|
|
@@ -240,14 +251,25 @@ export const action = async ({
|
|
|
240
251
|
{ success: true } | { success: false; errors: string[] }
|
|
241
252
|
> => {
|
|
242
253
|
try {
|
|
254
|
+
const pageUrl = new URL(request.url);
|
|
255
|
+
pageUrl.host = getRequestHost(request);
|
|
256
|
+
|
|
243
257
|
const formData = await request.formData();
|
|
244
258
|
|
|
245
|
-
const
|
|
259
|
+
const system = {
|
|
260
|
+
params: {},
|
|
261
|
+
search: {},
|
|
262
|
+
origin: pageUrl.origin,
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const resourceName = formData.get(formIdFieldName);
|
|
246
266
|
|
|
247
|
-
if (
|
|
267
|
+
if (resourceName == null || typeof resourceName !== "string") {
|
|
248
268
|
throw new Error("No form id in FormData");
|
|
249
269
|
}
|
|
250
270
|
|
|
271
|
+
const resource = getResources({ system }).action.get(resourceName);
|
|
272
|
+
|
|
251
273
|
const formBotValue = formData.get(formBotFieldName);
|
|
252
274
|
|
|
253
275
|
if (formBotValue == null || typeof formBotValue !== "string") {
|
|
@@ -266,41 +288,32 @@ export const action = async ({
|
|
|
266
288
|
throw new Error(`Form bot value invalid ${formBotValue}`);
|
|
267
289
|
}
|
|
268
290
|
|
|
269
|
-
|
|
291
|
+
formData.delete(formIdFieldName);
|
|
292
|
+
formData.delete(formBotFieldName);
|
|
270
293
|
|
|
271
|
-
|
|
272
|
-
|
|
294
|
+
if (resource) {
|
|
295
|
+
const { ok, statusText } = await loadResource(fetch, {
|
|
296
|
+
...resource,
|
|
297
|
+
body: Object.fromEntries(formData),
|
|
298
|
+
});
|
|
299
|
+
if (ok) {
|
|
300
|
+
return { success: true };
|
|
301
|
+
}
|
|
302
|
+
return { success: false, errors: [statusText] };
|
|
303
|
+
}
|
|
273
304
|
|
|
274
305
|
if (contactEmail === undefined) {
|
|
275
306
|
throw new Error("Contact email not found");
|
|
276
307
|
}
|
|
277
308
|
|
|
278
|
-
const pageUrl = new URL(request.url);
|
|
279
|
-
pageUrl.host = getRequestHost(request);
|
|
280
|
-
|
|
281
|
-
if (action !== undefined) {
|
|
282
|
-
try {
|
|
283
|
-
// Test that action is full URL
|
|
284
|
-
new URL(action);
|
|
285
|
-
} catch {
|
|
286
|
-
throw new Error(
|
|
287
|
-
"Invalid action URL, must be valid http/https protocol"
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const formInfo = {
|
|
293
|
-
formData,
|
|
294
|
-
projectId,
|
|
295
|
-
action: action ?? null,
|
|
296
|
-
method: getMethod(method),
|
|
297
|
-
pageUrl: pageUrl.toString(),
|
|
298
|
-
toEmail: contactEmail,
|
|
299
|
-
fromEmail: pageUrl.hostname + "@webstudio.email",
|
|
300
|
-
} as const;
|
|
301
|
-
|
|
302
309
|
const result = await n8nHandler({
|
|
303
|
-
formInfo
|
|
310
|
+
formInfo: {
|
|
311
|
+
formId: [projectId, resourceName].join("--"),
|
|
312
|
+
formData,
|
|
313
|
+
pageUrl: pageUrl.toString(),
|
|
314
|
+
toEmail: contactEmail,
|
|
315
|
+
fromEmail: pageUrl.hostname + "@webstudio.email",
|
|
316
|
+
},
|
|
304
317
|
hookUrl: context.N8N_FORM_EMAIL_HOOK,
|
|
305
318
|
});
|
|
306
319
|
|
|
@@ -316,7 +329,7 @@ export const action = async ({
|
|
|
316
329
|
};
|
|
317
330
|
|
|
318
331
|
const Outlet = () => {
|
|
319
|
-
const { system, resources } = useLoaderData<typeof loader>();
|
|
332
|
+
const { system, resources, url } = useLoaderData<typeof loader>();
|
|
320
333
|
return (
|
|
321
334
|
<ReactSdkContext.Provider
|
|
322
335
|
value={{
|
|
@@ -326,7 +339,8 @@ const Outlet = () => {
|
|
|
326
339
|
resources,
|
|
327
340
|
}}
|
|
328
341
|
>
|
|
329
|
-
|
|
342
|
+
{/* Use the URL as the key to force scripts in HTML Embed to reload on dynamic pages */}
|
|
343
|
+
<Page key={url} system={system} />
|
|
330
344
|
</ReactSdkContext.Provider>
|
|
331
345
|
);
|
|
332
346
|
};
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
|
+
import { renderToString } from "react-dom/server";
|
|
2
3
|
import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
|
|
4
|
+
import { isLocalResource, loadResources } from "@webstudio-is/sdk";
|
|
3
5
|
import { ReactSdkContext } from "@webstudio-is/react-sdk";
|
|
4
|
-
import { Page } from "
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
import { Page } from "__CLIENT__";
|
|
7
|
+
import { getPageMeta, getRemixParams, getResources } from "__SERVER__";
|
|
8
|
+
import { assetBaseUrl, imageBaseUrl, imageLoader } from "__CONSTANTS__";
|
|
9
|
+
import { sitemap } from "__SITEMAP__";
|
|
10
|
+
|
|
11
|
+
const customFetch: typeof fetch = (input, init) => {
|
|
12
|
+
if (typeof input !== "string") {
|
|
13
|
+
return fetch(input, init);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (isLocalResource(input, "sitemap.xml")) {
|
|
17
|
+
// @todo: dynamic import sitemap ???
|
|
18
|
+
const response = new Response(JSON.stringify(sitemap));
|
|
19
|
+
response.headers.set("content-type", "application/json; charset=utf-8");
|
|
20
|
+
return Promise.resolve(response);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return fetch(input, init);
|
|
24
|
+
};
|
|
13
25
|
|
|
14
26
|
export const loader = async (arg: LoaderFunctionArgs) => {
|
|
15
27
|
const url = new URL(arg.request.url);
|
|
@@ -28,7 +40,10 @@ export const loader = async (arg: LoaderFunctionArgs) => {
|
|
|
28
40
|
origin: url.origin,
|
|
29
41
|
};
|
|
30
42
|
|
|
31
|
-
const resources = await loadResources(
|
|
43
|
+
const resources = await loadResources(
|
|
44
|
+
customFetch,
|
|
45
|
+
getResources({ system }).data
|
|
46
|
+
);
|
|
32
47
|
const pageMeta = getPageMeta({ system, resources });
|
|
33
48
|
|
|
34
49
|
if (pageMeta.redirect) {
|
|
@@ -8,26 +8,26 @@
|
|
|
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/form-handlers": "0.
|
|
19
|
-
"@webstudio-is/image": "0.
|
|
20
|
-
"@webstudio-is/sdk": "0.
|
|
21
|
-
"isbot": "^5.1.
|
|
11
|
+
"@remix-run/node": "2.10.3",
|
|
12
|
+
"@remix-run/react": "2.10.3",
|
|
13
|
+
"@remix-run/server-runtime": "2.10.3",
|
|
14
|
+
"@webstudio-is/react-sdk": "0.173.0",
|
|
15
|
+
"@webstudio-is/sdk-components-react-radix": "0.173.0",
|
|
16
|
+
"@webstudio-is/sdk-components-react-remix": "0.173.0",
|
|
17
|
+
"@webstudio-is/sdk-components-react": "0.173.0",
|
|
18
|
+
"@webstudio-is/form-handlers": "0.173.0",
|
|
19
|
+
"@webstudio-is/image": "0.173.0",
|
|
20
|
+
"@webstudio-is/sdk": "0.173.0",
|
|
21
|
+
"isbot": "^5.1.13",
|
|
22
22
|
"react": "18.3.0-canary-14898b6a9-20240318",
|
|
23
23
|
"react-dom": "18.3.0-canary-14898b6a9-20240318"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@remix-run/dev": "2.
|
|
26
|
+
"@remix-run/dev": "2.10.3",
|
|
27
27
|
"@types/react": "^18.2.70",
|
|
28
28
|
"@types/react-dom": "^18.2.25",
|
|
29
|
-
"typescript": "5.
|
|
30
|
-
"vite": "^5.
|
|
29
|
+
"typescript": "5.5.2",
|
|
30
|
+
"vite": "^5.3.4"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=20.0.0"
|
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
"include": ["**/*.ts", "**/*.tsx", "**/*.mjs"],
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
5
|
-
"types": [
|
|
5
|
+
"types": [
|
|
6
|
+
"@remix-run/node",
|
|
7
|
+
"vite/client",
|
|
8
|
+
"@webstudio-is/react-sdk/placeholder"
|
|
9
|
+
],
|
|
6
10
|
"isolatedModules": true,
|
|
7
11
|
"esModuleInterop": true,
|
|
8
12
|
"jsx": "react-jsx",
|
|
9
13
|
"module": "ESNext",
|
|
10
14
|
"moduleResolution": "bundler",
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
15
|
"target": "ES2022",
|
|
13
16
|
"strict": true,
|
|
14
17
|
"allowJs": true,
|
|
15
|
-
"checkJs": true,
|
|
16
18
|
"forceConsistentCasingInFileNames": true,
|
|
17
|
-
"allowImportingTsExtensions": true,
|
|
18
|
-
"baseUrl": ".",
|
|
19
|
-
// Remix takes care of building everything in `remix build`.
|
|
20
19
|
"noEmit": true,
|
|
21
20
|
"skipLibCheck": true
|
|
22
21
|
}
|
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"include": ["**/*.ts", "**/*.tsx", "**/*.mjs"],
|
|
3
2
|
"compilerOptions": {
|
|
4
|
-
"
|
|
5
|
-
"types": ["@remix-run/node", "vite/client"],
|
|
6
|
-
"isolatedModules": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"jsx": "react-jsx",
|
|
9
|
-
"module": "ESNext",
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"resolveJsonModule": true,
|
|
12
|
-
"target": "ES2022",
|
|
13
|
-
"strict": true,
|
|
14
|
-
"allowJs": true,
|
|
15
|
-
"checkJs": true,
|
|
16
|
-
"forceConsistentCasingInFileNames": true,
|
|
17
|
-
"allowImportingTsExtensions": true,
|
|
18
|
-
"baseUrl": ".",
|
|
19
|
-
"customConditions": ["webstudio"],
|
|
20
|
-
|
|
21
|
-
// Remix takes care of building everything in `remix build`.
|
|
22
|
-
"noEmit": true,
|
|
23
|
-
"skipLibCheck": true
|
|
3
|
+
"customConditions": ["webstudio"]
|
|
24
4
|
}
|
|
25
5
|
}
|
|
@@ -8,27 +8,11 @@
|
|
|
8
8
|
"**/.client/**/*.tsx"
|
|
9
9
|
],
|
|
10
10
|
"compilerOptions": {
|
|
11
|
-
"lib": ["DOM", "DOM.Iterable", "ES2023"],
|
|
12
11
|
"types": [
|
|
13
12
|
"@remix-run/cloudflare",
|
|
14
13
|
"vite/client",
|
|
15
|
-
"@cloudflare/workers-types/2023-07-01"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"esModuleInterop": true,
|
|
19
|
-
"jsx": "react-jsx",
|
|
20
|
-
"module": "ESNext",
|
|
21
|
-
"moduleResolution": "Bundler",
|
|
22
|
-
"resolveJsonModule": true,
|
|
23
|
-
"target": "ES2022",
|
|
24
|
-
"strict": true,
|
|
25
|
-
"allowJs": true,
|
|
26
|
-
"skipLibCheck": true,
|
|
27
|
-
"forceConsistentCasingInFileNames": true,
|
|
28
|
-
"baseUrl": ".",
|
|
29
|
-
"customConditions": ["webstudio"],
|
|
30
|
-
|
|
31
|
-
// Vite takes care of building everything, not tsc.
|
|
32
|
-
"noEmit": true
|
|
14
|
+
"@cloudflare/workers-types/2023-07-01",
|
|
15
|
+
"@webstudio-is/react-sdk/placeholder"
|
|
16
|
+
]
|
|
33
17
|
}
|
|
34
18
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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 = ({ src }) => {
|
|
12
|
+
return imageBaseUrl + src;
|
|
13
|
+
};
|