webstudio 0.142.0 → 0.144.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 +68 -69
- package/package.json +10 -10
- package/templates/defaults/__templates__/route-template.tsx +50 -65
- package/templates/defaults/app/root.tsx +17 -1
- package/templates/defaults/app/routes/[robots.txt].tsx +2 -2
- package/templates/defaults/app/routes/[sitemap.xml].tsx +2 -2
- package/templates/defaults/{remix.env.d.ts → env.d.ts} +1 -1
- package/templates/defaults/package.json +16 -15
- package/templates/defaults/tsconfig.json +2 -1
- package/templates/defaults/vite.config.ts +15 -0
- package/templates/internal/package.json +11 -0
- package/templates/netlify-edge-functions/netlify.toml +11 -2
- package/templates/netlify-edge-functions/package.json +2 -4
- package/templates/netlify-edge-functions/vite.config.ts +16 -0
- package/templates/netlify-functions/app/entry.server.tsx +1 -21
- package/templates/netlify-functions/netlify.toml +7 -5
- package/templates/netlify-functions/package.json +2 -3
- package/templates/netlify-functions/vite.config.ts +16 -0
- package/templates/vercel/package.json +1 -5
- package/templates/defaults/remix.config.js +0 -20
- package/templates/netlify-edge-functions/remix.config.js +0 -29
- package/templates/netlify-edge-functions/server.js +0 -19
- package/templates/netlify-functions/_app_redirects +0 -9
- package/templates/netlify-functions/remix.config.js +0 -31
- package/templates/netlify-functions/server.js +0 -7
package/lib/cli.js
CHANGED
|
@@ -259,23 +259,23 @@ import ora2 from "ora";
|
|
|
259
259
|
import merge from "deepmerge";
|
|
260
260
|
import {
|
|
261
261
|
generateCss,
|
|
262
|
-
generateUtilsExport,
|
|
263
262
|
generateWebstudioComponent,
|
|
264
263
|
getIndexesWithinAncestors,
|
|
265
264
|
namespaceMeta,
|
|
266
265
|
normalizeProps,
|
|
267
266
|
generateRemixRoute,
|
|
268
267
|
generateRemixParams,
|
|
269
|
-
|
|
270
|
-
collectionComponent,
|
|
271
|
-
generatePageMeta,
|
|
272
|
-
executeExpression
|
|
268
|
+
collectionComponent
|
|
273
269
|
} from "@webstudio-is/react-sdk";
|
|
274
270
|
import {
|
|
275
271
|
createScope,
|
|
276
272
|
findTreeInstanceIds,
|
|
277
273
|
getPagePath,
|
|
278
|
-
parseComponentName
|
|
274
|
+
parseComponentName,
|
|
275
|
+
executeExpression,
|
|
276
|
+
generateFormsProperties,
|
|
277
|
+
generateResourcesLoader,
|
|
278
|
+
generatePageMeta
|
|
279
279
|
} from "@webstudio-is/sdk";
|
|
280
280
|
import { createImageLoader } from "@webstudio-is/image";
|
|
281
281
|
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
|
|
@@ -306,7 +306,7 @@ var downloadAsset = async (url, name, assetBaseUrl) => {
|
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
};
|
|
309
|
-
var
|
|
309
|
+
var mergeJsonInto = async (sourcePath, destinationPath) => {
|
|
310
310
|
const sourceJson = await readFile4(sourcePath, "utf8");
|
|
311
311
|
const destinationJson = await readFile4(destinationPath, "utf8").catch(
|
|
312
312
|
(error) => {
|
|
@@ -317,7 +317,7 @@ var mergeJsonFiles = async (sourcePath, destinationPath) => {
|
|
|
317
317
|
}
|
|
318
318
|
);
|
|
319
319
|
const content = JSON.stringify(
|
|
320
|
-
merge(JSON.parse(
|
|
320
|
+
merge(JSON.parse(destinationJson), JSON.parse(sourceJson)),
|
|
321
321
|
null,
|
|
322
322
|
" "
|
|
323
323
|
);
|
|
@@ -350,7 +350,7 @@ var copyTemplates = async (template = "defaults") => {
|
|
|
350
350
|
}
|
|
351
351
|
});
|
|
352
352
|
if (await isFileExists(join4(templatePath, "package.json")) === true) {
|
|
353
|
-
await
|
|
353
|
+
await mergeJsonInto(
|
|
354
354
|
join4(templatePath, "package.json"),
|
|
355
355
|
join4(cwd3(), "package.json")
|
|
356
356
|
);
|
|
@@ -514,12 +514,6 @@ var prebuild = async (options) => {
|
|
|
514
514
|
backgroundImageAssetsByPage[page.id] = backgroundImageAssets;
|
|
515
515
|
}
|
|
516
516
|
const assetsToDownload = [];
|
|
517
|
-
const imageAssets = [];
|
|
518
|
-
for (const asset of siteData.assets) {
|
|
519
|
-
if (asset.type === "image") {
|
|
520
|
-
imageAssets.push(asset);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
517
|
const appDomain = options.preview ? "wstd.work" : "wstd.io";
|
|
524
518
|
const assetBuildUrl = `https://${domain}.${appDomain}/cgi/asset/`;
|
|
525
519
|
const imageLoader = createImageLoader({
|
|
@@ -549,21 +543,18 @@ var prebuild = async (options) => {
|
|
|
549
543
|
}
|
|
550
544
|
}
|
|
551
545
|
}
|
|
546
|
+
const assets = new Map(siteData.assets.map((asset) => [asset.id, asset]));
|
|
552
547
|
spinner.text = "Generating css file";
|
|
553
|
-
const { cssText, classesMap } = generateCss(
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
assetBaseUrl,
|
|
564
|
-
atomic: siteData.build.pages.compiler?.atomicStyles ?? true
|
|
565
|
-
}
|
|
566
|
-
);
|
|
548
|
+
const { cssText, classesMap } = generateCss({
|
|
549
|
+
assets,
|
|
550
|
+
breakpoints: new Map(siteData.build?.breakpoints),
|
|
551
|
+
styles: new Map(siteData.build?.styles),
|
|
552
|
+
styleSourceSelections: new Map(siteData.build?.styleSourceSelections),
|
|
553
|
+
// pass only used metas to not generate unused preset styles
|
|
554
|
+
componentMetas: projectMetas,
|
|
555
|
+
assetBaseUrl,
|
|
556
|
+
atomic: siteData.build.pages.compiler?.atomicStyles ?? true
|
|
557
|
+
});
|
|
567
558
|
await ensureFileInPath(join4(generatedDir, "index.css"), cssText);
|
|
568
559
|
spinner.text = "Generating routes and pages";
|
|
569
560
|
const routeTemplatePath = normalize(
|
|
@@ -577,17 +568,6 @@ var prebuild = async (options) => {
|
|
|
577
568
|
"useState",
|
|
578
569
|
"Fragment",
|
|
579
570
|
"useResource",
|
|
580
|
-
"PageMeta",
|
|
581
|
-
"createPageMeta",
|
|
582
|
-
"PageData",
|
|
583
|
-
"Asset",
|
|
584
|
-
"ProjectMeta",
|
|
585
|
-
"System",
|
|
586
|
-
"fontAssets",
|
|
587
|
-
"pageData",
|
|
588
|
-
"user",
|
|
589
|
-
"projectId",
|
|
590
|
-
"formsProperties",
|
|
591
571
|
"Page",
|
|
592
572
|
"_props"
|
|
593
573
|
]);
|
|
@@ -624,15 +604,11 @@ var prebuild = async (options) => {
|
|
|
624
604
|
const pageData = siteDataByPage[pageId];
|
|
625
605
|
const pageFontAssets = fontAssetsByPage[pageId];
|
|
626
606
|
const pageBackgroundImageAssets = backgroundImageAssetsByPage[pageId];
|
|
627
|
-
const renderedPageData = {
|
|
628
|
-
project: siteData.build.pages.meta
|
|
629
|
-
};
|
|
630
607
|
const rootInstanceId = pageData.page.rootInstanceId;
|
|
631
608
|
const instances = new Map(pageData.build.instances);
|
|
632
609
|
const props = new Map(pageData.build.props);
|
|
633
610
|
const dataSources = new Map(pageData.build.dataSources);
|
|
634
611
|
const resources = new Map(pageData.build.resources);
|
|
635
|
-
const utilsExport = generateUtilsExport({ props });
|
|
636
612
|
const pageComponent = generateWebstudioComponent({
|
|
637
613
|
scope,
|
|
638
614
|
name: "Page",
|
|
@@ -656,39 +632,67 @@ var prebuild = async (options) => {
|
|
|
656
632
|
[rootInstanceId]
|
|
657
633
|
)
|
|
658
634
|
});
|
|
635
|
+
const projectMeta = siteData.build.pages.meta;
|
|
636
|
+
const pageMeta = pageData.page.meta;
|
|
637
|
+
const favIconAsset = assets.get(projectMeta?.faviconAssetId ?? "");
|
|
638
|
+
const socialImageAsset = assets.get(pageMeta.socialImageAssetId ?? "");
|
|
659
639
|
const pageExports = `/* eslint-disable */
|
|
660
640
|
/* This is a auto generated file for building the project */
|
|
661
641
|
|
|
642
|
+
|
|
662
643
|
import { Fragment, useState } from "react";
|
|
663
|
-
import type {
|
|
644
|
+
import type { FontAsset, ImageAsset } from "@webstudio-is/sdk";
|
|
664
645
|
import { useResource } from "@webstudio-is/react-sdk";
|
|
665
|
-
import type { PageMeta } from "@webstudio-is/react-sdk";
|
|
666
646
|
${componentImports}
|
|
667
|
-
|
|
668
|
-
export const
|
|
647
|
+
|
|
648
|
+
export const favIconAsset: ImageAsset | undefined =
|
|
649
|
+
${JSON.stringify(favIconAsset)};
|
|
650
|
+
|
|
651
|
+
export const socialImageAsset: ImageAsset | undefined =
|
|
652
|
+
${JSON.stringify(socialImageAsset)};
|
|
669
653
|
|
|
670
654
|
// Font assets on current page (can be preloaded)
|
|
671
|
-
export const pageFontAssets: FontAsset[] =
|
|
655
|
+
export const pageFontAssets: FontAsset[] =
|
|
656
|
+
${JSON.stringify(pageFontAssets)}
|
|
672
657
|
|
|
673
|
-
export const pageBackgroundImageAssets: ImageAsset[] =
|
|
674
|
-
|
|
675
|
-
)}
|
|
658
|
+
export const pageBackgroundImageAssets: ImageAsset[] =
|
|
659
|
+
${JSON.stringify(pageBackgroundImageAssets)}
|
|
676
660
|
|
|
677
|
-
export const pageData: PageData = ${JSON.stringify(renderedPageData)};
|
|
678
|
-
export const user: { email: string | null } | undefined = ${JSON.stringify(
|
|
679
|
-
siteData.user
|
|
680
|
-
)};
|
|
681
|
-
export const projectId = "${siteData.build.projectId}";
|
|
682
661
|
|
|
683
|
-
${generatePageMeta({ globalScope: scope, page: pageData.page, dataSources })}
|
|
684
662
|
|
|
685
663
|
${pageComponent}
|
|
686
664
|
|
|
687
665
|
export { Page }
|
|
666
|
+
`;
|
|
667
|
+
const serverExports = `/* eslint-disable */
|
|
668
|
+
/* This is a auto generated file for building the project */
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
import type { ProjectMeta, PageMeta } from "@webstudio-is/sdk";
|
|
672
|
+
${generateResourcesLoader({
|
|
673
|
+
scope,
|
|
674
|
+
page: pageData.page,
|
|
675
|
+
dataSources,
|
|
676
|
+
resources
|
|
677
|
+
})}
|
|
678
|
+
|
|
679
|
+
${generatePageMeta({
|
|
680
|
+
globalScope: scope,
|
|
681
|
+
page: pageData.page,
|
|
682
|
+
dataSources
|
|
683
|
+
})}
|
|
684
|
+
|
|
685
|
+
${generateFormsProperties(props)}
|
|
688
686
|
|
|
689
687
|
${generateRemixParams(pageData.page.path)}
|
|
690
688
|
|
|
691
|
-
${
|
|
689
|
+
export const projectId = "${siteData.build.projectId}";
|
|
690
|
+
|
|
691
|
+
export const user: { email: string | null } | undefined =
|
|
692
|
+
${JSON.stringify(siteData.user)};
|
|
693
|
+
|
|
694
|
+
export const projectMeta: ProjectMeta =
|
|
695
|
+
${JSON.stringify(projectMeta)};
|
|
692
696
|
`;
|
|
693
697
|
const pagePath = getPagePath(pageData.page.id, siteData.build.pages);
|
|
694
698
|
const remixRoute = generateRemixRoute(pagePath);
|
|
@@ -704,12 +708,7 @@ ${utilsExport}
|
|
|
704
708
|
await ensureFileInPath(join4(generatedDir, fileName), pageExports);
|
|
705
709
|
await ensureFileInPath(
|
|
706
710
|
join4(generatedDir, `${remixRoute}.server.tsx`),
|
|
707
|
-
|
|
708
|
-
scope,
|
|
709
|
-
page: pageData.page,
|
|
710
|
-
dataSources,
|
|
711
|
-
resources
|
|
712
|
-
})
|
|
711
|
+
serverExports
|
|
713
712
|
);
|
|
714
713
|
}
|
|
715
714
|
await writeFile4(
|
|
@@ -735,9 +734,9 @@ ${utilsExport}
|
|
|
735
734
|
for (const redirect of redirects) {
|
|
736
735
|
const redirectPagePath = generateRemixRoute(redirect.old);
|
|
737
736
|
const redirectFileName = `${redirectPagePath}.ts`;
|
|
738
|
-
const content = `import { type
|
|
737
|
+
const content = `import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
|
|
739
738
|
|
|
740
|
-
export const loader = (arg:
|
|
739
|
+
export const loader = (arg: LoaderFunctionArgs) => {
|
|
741
740
|
return redirect("${redirect.new}", ${redirect.status ?? 301});
|
|
742
741
|
};
|
|
743
742
|
`;
|
|
@@ -918,7 +917,7 @@ import makeCLI from "yargs";
|
|
|
918
917
|
// package.json
|
|
919
918
|
var package_default = {
|
|
920
919
|
name: "webstudio",
|
|
921
|
-
version: "0.
|
|
920
|
+
version: "0.144.0",
|
|
922
921
|
description: "Webstudio CLI",
|
|
923
922
|
author: "Webstudio <github@webstudio.is>",
|
|
924
923
|
homepage: "https://webstudio.is",
|
|
@@ -966,7 +965,7 @@ var package_default = {
|
|
|
966
965
|
"@types/prompts": "^2.4.5",
|
|
967
966
|
"@webstudio-is/form-handlers": "workspace:*",
|
|
968
967
|
"@webstudio-is/tsconfig": "workspace:*",
|
|
969
|
-
tsx: "^
|
|
968
|
+
tsx: "^4.7.2",
|
|
970
969
|
typescript: "5.2.2"
|
|
971
970
|
}
|
|
972
971
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webstudio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.144.0",
|
|
4
4
|
"description": "Webstudio CLI",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -28,20 +28,20 @@
|
|
|
28
28
|
"title-case": "^4.1.0",
|
|
29
29
|
"yargs": "^17.7.2",
|
|
30
30
|
"zod": "^3.22.4",
|
|
31
|
-
"@webstudio-is/http-client": "0.
|
|
32
|
-
"@webstudio-is/react-sdk": "0.
|
|
33
|
-
"@webstudio-is/
|
|
34
|
-
"@webstudio-is/sdk
|
|
35
|
-
"@webstudio-is/
|
|
36
|
-
"@webstudio-is/sdk-components-react-remix": "0.
|
|
37
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
31
|
+
"@webstudio-is/http-client": "0.144.0",
|
|
32
|
+
"@webstudio-is/react-sdk": "0.144.0",
|
|
33
|
+
"@webstudio-is/image": "0.144.0",
|
|
34
|
+
"@webstudio-is/sdk": "0.144.0",
|
|
35
|
+
"@webstudio-is/sdk-components-react": "0.144.0",
|
|
36
|
+
"@webstudio-is/sdk-components-react-remix": "0.144.0",
|
|
37
|
+
"@webstudio-is/sdk-components-react-radix": "0.144.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^18.17.1",
|
|
41
41
|
"@types/prompts": "^2.4.5",
|
|
42
|
-
"tsx": "^
|
|
42
|
+
"tsx": "^4.7.2",
|
|
43
43
|
"typescript": "5.2.2",
|
|
44
|
-
"@webstudio-is/form-handlers": "0.
|
|
44
|
+
"@webstudio-is/form-handlers": "0.144.0",
|
|
45
45
|
"@webstudio-is/tsconfig": "1.0.7"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import {
|
|
3
|
-
type
|
|
3
|
+
type ServerRuntimeMetaFunction as MetaFunction,
|
|
4
4
|
type LinksFunction,
|
|
5
5
|
type LinkDescriptor,
|
|
6
|
-
type
|
|
7
|
-
type
|
|
8
|
-
type
|
|
6
|
+
type ActionFunctionArgs,
|
|
7
|
+
type LoaderFunctionArgs,
|
|
8
|
+
type HeadersFunction,
|
|
9
9
|
json,
|
|
10
10
|
redirect,
|
|
11
11
|
} from "@remix-run/server-runtime";
|
|
12
12
|
import { useLoaderData } from "@remix-run/react";
|
|
13
|
-
import type { ProjectMeta } from "@webstudio-is/sdk";
|
|
14
13
|
import { ReactSdkContext } from "@webstudio-is/react-sdk";
|
|
15
14
|
import { n8nHandler, getFormId } from "@webstudio-is/form-handlers";
|
|
16
15
|
import {
|
|
17
|
-
pageData,
|
|
18
|
-
user,
|
|
19
|
-
projectId,
|
|
20
|
-
formsProperties,
|
|
21
16
|
Page,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
getPageMeta,
|
|
17
|
+
favIconAsset,
|
|
18
|
+
socialImageAsset,
|
|
25
19
|
pageFontAssets,
|
|
26
20
|
pageBackgroundImageAssets,
|
|
27
21
|
} from "../../../__generated__/_index";
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
import {
|
|
23
|
+
formsProperties,
|
|
24
|
+
loadResources,
|
|
25
|
+
getPageMeta,
|
|
26
|
+
getRemixParams,
|
|
27
|
+
projectId,
|
|
28
|
+
user,
|
|
29
|
+
projectMeta,
|
|
30
|
+
} from "../../../__generated__/_index.server";
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
32
|
+
import css from "../__generated__/index.css?url";
|
|
33
|
+
import { assetBaseUrl, imageBaseUrl, imageLoader } from "~/constants.mjs";
|
|
35
34
|
|
|
36
|
-
export const loader = async (arg:
|
|
35
|
+
export const loader = async (arg: LoaderFunctionArgs) => {
|
|
36
|
+
const url = new URL(arg.request.url);
|
|
37
37
|
const params = getRemixParams(arg.params);
|
|
38
38
|
const system = {
|
|
39
39
|
params,
|
|
40
|
-
search:
|
|
40
|
+
search: Object.fromEntries(url.searchParams),
|
|
41
41
|
};
|
|
42
42
|
const resources = await loadResources({ system });
|
|
43
43
|
const pageMeta = getPageMeta({ system, resources });
|
|
@@ -55,7 +55,6 @@ export const loader = async (arg: LoaderArgs) => {
|
|
|
55
55
|
arg.request.headers.get("host") ||
|
|
56
56
|
"";
|
|
57
57
|
|
|
58
|
-
const url = new URL(arg.request.url);
|
|
59
58
|
url.host = host;
|
|
60
59
|
url.protocol = "https";
|
|
61
60
|
|
|
@@ -70,6 +69,7 @@ export const loader = async (arg: LoaderArgs) => {
|
|
|
70
69
|
system,
|
|
71
70
|
resources,
|
|
72
71
|
pageMeta,
|
|
72
|
+
projectMeta,
|
|
73
73
|
},
|
|
74
74
|
// No way for current information to change, so add cache for 10 minutes
|
|
75
75
|
// In case of CRM Data, this should be set to 0
|
|
@@ -83,20 +83,19 @@ export const loader = async (arg: LoaderArgs) => {
|
|
|
83
83
|
);
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
-
export const headers = ({ loaderHeaders }
|
|
86
|
+
export const headers: HeadersFunction = ({ loaderHeaders }) => {
|
|
87
87
|
return {
|
|
88
88
|
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
89
|
-
"x-ws-language": loaderHeaders.get("x-ws-language"),
|
|
89
|
+
"x-ws-language": loaderHeaders.get("x-ws-language") ?? "",
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
-
export const meta:
|
|
94
|
-
const metas: ReturnType<
|
|
93
|
+
export const meta: MetaFunction<typeof loader> = ({ data }) => {
|
|
94
|
+
const metas: ReturnType<MetaFunction> = [];
|
|
95
95
|
if (data === undefined) {
|
|
96
96
|
return metas;
|
|
97
97
|
}
|
|
98
|
-
const { pageMeta } = data;
|
|
99
|
-
const { project } = pageData;
|
|
98
|
+
const { pageMeta, projectMeta } = data;
|
|
100
99
|
|
|
101
100
|
if (data.url) {
|
|
102
101
|
metas.push({
|
|
@@ -118,16 +117,16 @@ export const meta: V2_ServerRuntimeMetaFunction<typeof loader> = ({ data }) => {
|
|
|
118
117
|
|
|
119
118
|
const origin = `https://${data.host}`;
|
|
120
119
|
|
|
121
|
-
if (
|
|
120
|
+
if (projectMeta?.siteName) {
|
|
122
121
|
metas.push({
|
|
123
122
|
property: "og:site_name",
|
|
124
|
-
content:
|
|
123
|
+
content: projectMeta.siteName,
|
|
125
124
|
});
|
|
126
125
|
metas.push({
|
|
127
126
|
"script:ld+json": {
|
|
128
127
|
"@context": "https://schema.org",
|
|
129
128
|
"@type": "WebSite",
|
|
130
|
-
name:
|
|
129
|
+
name: projectMeta.siteName,
|
|
131
130
|
url: origin,
|
|
132
131
|
},
|
|
133
132
|
});
|
|
@@ -151,21 +150,15 @@ export const meta: V2_ServerRuntimeMetaFunction<typeof loader> = ({ data }) => {
|
|
|
151
150
|
});
|
|
152
151
|
}
|
|
153
152
|
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
src: imageAsset.name,
|
|
164
|
-
// Do not transform social image (not enough information do we need to do this)
|
|
165
|
-
format: "raw",
|
|
166
|
-
})}`,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
153
|
+
if (socialImageAsset) {
|
|
154
|
+
metas.push({
|
|
155
|
+
property: "og:image",
|
|
156
|
+
content: `https://${data.host}${imageLoader({
|
|
157
|
+
src: socialImageAsset.name,
|
|
158
|
+
// Do not transform social image (not enough information do we need to do this)
|
|
159
|
+
format: "raw",
|
|
160
|
+
})}`,
|
|
161
|
+
});
|
|
169
162
|
} else if (pageMeta.socialImageUrl) {
|
|
170
163
|
metas.push({
|
|
171
164
|
property: "og:image",
|
|
@@ -186,25 +179,17 @@ export const links: LinksFunction = () => {
|
|
|
186
179
|
href: css,
|
|
187
180
|
});
|
|
188
181
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
src: imageAsset.name,
|
|
201
|
-
width: 128,
|
|
202
|
-
quality: 100,
|
|
203
|
-
format: "auto",
|
|
204
|
-
}),
|
|
205
|
-
type: undefined,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
182
|
+
if (favIconAsset) {
|
|
183
|
+
result.push({
|
|
184
|
+
rel: "icon",
|
|
185
|
+
href: imageLoader({
|
|
186
|
+
src: favIconAsset.name,
|
|
187
|
+
width: 128,
|
|
188
|
+
quality: 100,
|
|
189
|
+
format: "auto",
|
|
190
|
+
}),
|
|
191
|
+
type: undefined,
|
|
192
|
+
});
|
|
208
193
|
} else {
|
|
209
194
|
result.push({
|
|
210
195
|
rel: "icon",
|
|
@@ -255,7 +240,7 @@ const getMethod = (value: string | undefined) => {
|
|
|
255
240
|
}
|
|
256
241
|
};
|
|
257
242
|
|
|
258
|
-
export const action = async ({ request, context }:
|
|
243
|
+
export const action = async ({ request, context }: ActionFunctionArgs) => {
|
|
259
244
|
const formData = await request.formData();
|
|
260
245
|
|
|
261
246
|
const formId = getFormId(formData);
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import { Links, Meta, Outlet } from "@remix-run/react";
|
|
2
|
+
|
|
3
|
+
const Root = () => {
|
|
4
|
+
return (
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charSet="utf-8" />
|
|
8
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
9
|
+
<Meta />
|
|
10
|
+
<Links />
|
|
11
|
+
</head>
|
|
12
|
+
<Outlet />
|
|
13
|
+
</html>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default Root;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
|
|
2
2
|
|
|
3
|
-
export const loader = (arg:
|
|
3
|
+
export const loader = (arg: LoaderFunctionArgs) => {
|
|
4
4
|
const host =
|
|
5
5
|
arg.request.headers.get("x-forwarded-host") ||
|
|
6
6
|
arg.request.headers.get("host") ||
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
|
|
2
2
|
import { sitemap } from "../__generated__/[sitemap.xml]";
|
|
3
3
|
|
|
4
|
-
export const loader = (arg:
|
|
4
|
+
export const loader = (arg: LoaderFunctionArgs) => {
|
|
5
5
|
const host =
|
|
6
6
|
arg.request.headers.get("x-forwarded-host") ||
|
|
7
7
|
arg.request.headers.get("host") ||
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/// <reference types="
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
2
|
/// <reference types="@remix-run/node" />
|
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
+
"type": "module",
|
|
2
3
|
"private": true,
|
|
3
4
|
"sideEffects": false,
|
|
4
5
|
"scripts": {
|
|
5
|
-
"build": "remix build",
|
|
6
|
-
"dev": "remix dev",
|
|
6
|
+
"build": "remix vite:build",
|
|
7
|
+
"dev": "remix vite:dev",
|
|
7
8
|
"typecheck": "tsc"
|
|
8
9
|
},
|
|
9
10
|
"dependencies": {
|
|
10
|
-
"@remix-run/react": "^
|
|
11
|
-
"@remix-run/server-runtime": "^
|
|
12
|
-
"@remix-run/node": "^
|
|
13
|
-
"@webstudio-is/react-sdk": "0.
|
|
14
|
-
"@webstudio-is/sdk-components-react-radix": "0.
|
|
15
|
-
"@webstudio-is/sdk-components-react-remix": "0.
|
|
16
|
-
"@webstudio-is/sdk-components-react": "0.
|
|
17
|
-
"@webstudio-is/form-handlers": "0.
|
|
18
|
-
"@webstudio-is/image": "0.
|
|
19
|
-
"@webstudio-is/sdk": "0.
|
|
11
|
+
"@remix-run/react": "^2.8.1",
|
|
12
|
+
"@remix-run/server-runtime": "^2.8.1",
|
|
13
|
+
"@remix-run/node": "^2.8.1",
|
|
14
|
+
"@webstudio-is/react-sdk": "0.144.0",
|
|
15
|
+
"@webstudio-is/sdk-components-react-radix": "0.144.0",
|
|
16
|
+
"@webstudio-is/sdk-components-react-remix": "0.144.0",
|
|
17
|
+
"@webstudio-is/sdk-components-react": "0.144.0",
|
|
18
|
+
"@webstudio-is/form-handlers": "0.144.0",
|
|
19
|
+
"@webstudio-is/image": "0.144.0",
|
|
20
|
+
"@webstudio-is/sdk": "0.144.0",
|
|
20
21
|
"isbot": "^3.6.8",
|
|
21
22
|
"react": "^18.2.0",
|
|
22
23
|
"react-dom": "^18.2.0"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
|
-
"@remix-run/
|
|
26
|
-
"@remix-run/dev": "^1.19.2",
|
|
26
|
+
"@remix-run/dev": "^2.8.1",
|
|
27
27
|
"@types/react": "^18.2.20",
|
|
28
28
|
"@types/react-dom": "^18.2.7",
|
|
29
|
-
"typescript": "5.2.2"
|
|
29
|
+
"typescript": "5.2.2",
|
|
30
|
+
"vite": "^5.2.8"
|
|
30
31
|
},
|
|
31
32
|
"engines": {
|
|
32
33
|
"node": ">=18.0.0"
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"include": ["
|
|
2
|
+
"include": ["env.d.ts", "**/*.ts", "**/*.tsx", "**/*.mjs"],
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
5
5
|
"isolatedModules": true,
|
|
6
6
|
"esModuleInterop": true,
|
|
7
7
|
"jsx": "react-jsx",
|
|
8
|
+
"module": "ESNext",
|
|
8
9
|
"moduleResolution": "bundler",
|
|
9
10
|
"resolveJsonModule": true,
|
|
10
11
|
"target": "ES2022",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { defineConfig } from "vite";
|
|
3
|
+
import { vitePlugin as remix } from "@remix-run/dev";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [remix()],
|
|
7
|
+
resolve: {
|
|
8
|
+
alias: [
|
|
9
|
+
{
|
|
10
|
+
find: "~",
|
|
11
|
+
replacement: resolve("app"),
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"@webstudio-is/react-sdk": "workspace:*",
|
|
4
|
+
"@webstudio-is/sdk-components-react-radix": "workspace:*",
|
|
5
|
+
"@webstudio-is/sdk-components-react-remix": "workspace:*",
|
|
6
|
+
"@webstudio-is/sdk-components-react": "workspace:*",
|
|
7
|
+
"@webstudio-is/form-handlers": "workspace:*",
|
|
8
|
+
"@webstudio-is/image": "workspace:*",
|
|
9
|
+
"@webstudio-is/sdk": "workspace:*"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
[build]
|
|
2
2
|
command = "npm run build"
|
|
3
|
-
publish = "
|
|
3
|
+
publish = "build/client"
|
|
4
4
|
|
|
5
5
|
[dev]
|
|
6
6
|
command = "npm run dev"
|
|
7
|
-
|
|
7
|
+
framework = "vite"
|
|
8
|
+
|
|
9
|
+
# Set immutable caching for static files, because they have fingerprinted filenames
|
|
10
|
+
|
|
11
|
+
[[headers]]
|
|
12
|
+
for = "/build/*"
|
|
13
|
+
|
|
14
|
+
[headers.values]
|
|
15
|
+
|
|
16
|
+
"Cache-Control" = "public, max-age=31560000, immutable"
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"scripts": {
|
|
3
|
-
"predev": "node -e \"fs.rmSync('./public/_redirects', { recursive: true, force: true })\"",
|
|
4
3
|
"start": "netlify serve"
|
|
5
4
|
},
|
|
6
5
|
"dependencies": {
|
|
7
|
-
"@netlify/functions": "^
|
|
8
|
-
"@netlify/edge-
|
|
9
|
-
"@netlify/remix-edge-adapter": "1.2.0"
|
|
6
|
+
"@netlify/edge-functions": "^2.3.1",
|
|
7
|
+
"@netlify/remix-edge-adapter": "3.2.0"
|
|
10
8
|
}
|
|
11
9
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { vitePlugin as remix } from "@remix-run/dev";
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
import { netlifyPlugin } from "@netlify/remix-edge-adapter/plugin";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [remix(), netlifyPlugin()],
|
|
8
|
+
resolve: {
|
|
9
|
+
alias: [
|
|
10
|
+
{
|
|
11
|
+
find: "~",
|
|
12
|
+
replacement: resolve("app"),
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -1,21 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { RemixServer } from "@remix-run/react";
|
|
3
|
-
import { renderToString } from "react-dom/server";
|
|
4
|
-
|
|
5
|
-
export default function handleRequest(
|
|
6
|
-
request: Request,
|
|
7
|
-
responseStatusCode: number,
|
|
8
|
-
responseHeaders: Headers,
|
|
9
|
-
remixContext: EntryContext
|
|
10
|
-
) {
|
|
11
|
-
const markup = renderToString(
|
|
12
|
-
<RemixServer context={remixContext} url={request.url} />
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
responseHeaders.set("Content-Type", "text/html");
|
|
16
|
-
|
|
17
|
-
return new Response("<!DOCTYPE html>" + markup, {
|
|
18
|
-
headers: responseHeaders,
|
|
19
|
-
status: responseStatusCode,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
1
|
+
export { handleRequest as default } from "@netlify/remix-adapter";
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
[build]
|
|
2
|
-
command = "
|
|
3
|
-
publish = "
|
|
2
|
+
command = "npm run build"
|
|
3
|
+
publish = "build/client"
|
|
4
4
|
|
|
5
5
|
[dev]
|
|
6
6
|
command = "npm run dev"
|
|
7
|
-
|
|
7
|
+
framework = "vite"
|
|
8
|
+
|
|
9
|
+
# Set immutable caching for static files, because they have fingerprinted filenames
|
|
8
10
|
|
|
9
11
|
[[headers]]
|
|
10
12
|
for = "/build/*"
|
|
11
13
|
|
|
12
14
|
[headers.values]
|
|
13
|
-
|
|
14
|
-
"Cache-Control" = "public, max-age=
|
|
15
|
+
|
|
16
|
+
"Cache-Control" = "public, max-age=31560000, immutable"
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"scripts": {
|
|
3
|
-
"predev": "node -e \"fs.rmSync('./public/_redirects', { recursive: true, force: true })\"",
|
|
4
3
|
"start": "netlify serve"
|
|
5
4
|
},
|
|
6
5
|
"dependencies": {
|
|
7
|
-
"@netlify/functions": "^
|
|
8
|
-
"@netlify/remix-adapter": "^
|
|
6
|
+
"@netlify/functions": "^2.6.0",
|
|
7
|
+
"@netlify/remix-adapter": "^2.3.0"
|
|
9
8
|
}
|
|
10
9
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { vitePlugin as remix } from "@remix-run/dev";
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
import { netlifyPlugin } from "@netlify/remix-adapter/plugin";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [remix(), netlifyPlugin()],
|
|
8
|
+
resolve: {
|
|
9
|
+
alias: [
|
|
10
|
+
{
|
|
11
|
+
find: "~",
|
|
12
|
+
replacement: resolve("app"),
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/** @type {import('@remix-run/dev').AppConfig} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
ignoredRouteFiles: ["**/.*"],
|
|
4
|
-
serverModuleFormat: "cjs",
|
|
5
|
-
serverDependenciesToBundle: [
|
|
6
|
-
/@webstudio-is\//,
|
|
7
|
-
"nanoid",
|
|
8
|
-
"@jsep-plugin/assignment",
|
|
9
|
-
"change-case",
|
|
10
|
-
"title-case",
|
|
11
|
-
],
|
|
12
|
-
future: {
|
|
13
|
-
v2_errorBoundary: true,
|
|
14
|
-
v2_headers: true,
|
|
15
|
-
v2_meta: true,
|
|
16
|
-
v2_normalizeFormMethod: true,
|
|
17
|
-
v2_routeConvention: true,
|
|
18
|
-
v2_dev: true,
|
|
19
|
-
},
|
|
20
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const { config } = require("@netlify/remix-edge-adapter");
|
|
2
|
-
const baseConfig =
|
|
3
|
-
process.env.NODE_ENV === "production"
|
|
4
|
-
? config
|
|
5
|
-
: {
|
|
6
|
-
ignoredRouteFiles: ["**/.*"],
|
|
7
|
-
serverModuleFormat: "cjs",
|
|
8
|
-
serverDependenciesToBundle: [
|
|
9
|
-
/@webstudio-is\//,
|
|
10
|
-
"nanoid",
|
|
11
|
-
"@jsep-plugin/assignment",
|
|
12
|
-
"change-case",
|
|
13
|
-
"title-case",
|
|
14
|
-
],
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/** @type {import('@remix-run/dev').AppConfig} */
|
|
18
|
-
module.exports = {
|
|
19
|
-
ignoredRouteFiles: ["**/.*"],
|
|
20
|
-
...baseConfig,
|
|
21
|
-
future: {
|
|
22
|
-
v2_errorBoundary: true,
|
|
23
|
-
v2_headers: true,
|
|
24
|
-
v2_meta: true,
|
|
25
|
-
v2_normalizeFormMethod: true,
|
|
26
|
-
v2_routeConvention: true,
|
|
27
|
-
v2_dev: true,
|
|
28
|
-
},
|
|
29
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Import path interpreted by the Remix compiler
|
|
2
|
-
import * as build from "@remix-run/dev/server-build";
|
|
3
|
-
import { createRequestHandler } from "@netlify/remix-edge-adapter";
|
|
4
|
-
|
|
5
|
-
export default createRequestHandler({
|
|
6
|
-
build,
|
|
7
|
-
// process.env.NODE_ENV is provided by Remix at compile time
|
|
8
|
-
mode: process.env.NODE_ENV,
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export const config = {
|
|
12
|
-
cache: "manual",
|
|
13
|
-
path: "/*",
|
|
14
|
-
// Let the CDN handle requests for static assets, i.e. ^/_assets/*$
|
|
15
|
-
//
|
|
16
|
-
// Add other exclusions here, e.g. "^/api/*$" for custom Netlify functions or
|
|
17
|
-
// custom Netlify Edge Functions
|
|
18
|
-
excluded_patterns: ["^/_assets/*$"],
|
|
19
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# This template uses this file instead of the typicial Netlify \_redirects file.
|
|
2
|
-
|
|
3
|
-
# For more information about redirects and rewrites, see https://docs.netlify.com/routing/redirects/.
|
|
4
|
-
|
|
5
|
-
# Do not remove the line below. This is required to serve the project when deployed.
|
|
6
|
-
|
|
7
|
-
/\* /.netlify/functions/server 200
|
|
8
|
-
|
|
9
|
-
# Add other redirects and rewrites here and/or in your netlify.toml
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const baseConfig =
|
|
2
|
-
process.env.NODE_ENV === "production"
|
|
3
|
-
? // when running the Netify CLI or building on Netlify, we want to use
|
|
4
|
-
{
|
|
5
|
-
server: "./server.js",
|
|
6
|
-
serverBuildPath: ".netlify/functions-internal/server.js",
|
|
7
|
-
}
|
|
8
|
-
: // otherwise support running remix dev, i.e. no custom server
|
|
9
|
-
undefined;
|
|
10
|
-
|
|
11
|
-
/** @type {import('@remix-run/dev').AppConfig} */
|
|
12
|
-
module.exports = {
|
|
13
|
-
...baseConfig,
|
|
14
|
-
ignoredRouteFiles: ["**/.*"],
|
|
15
|
-
serverModuleFormat: "cjs",
|
|
16
|
-
serverDependenciesToBundle: [
|
|
17
|
-
/@webstudio-is\//,
|
|
18
|
-
"nanoid",
|
|
19
|
-
"@jsep-plugin/assignment",
|
|
20
|
-
"change-case",
|
|
21
|
-
"title-case",
|
|
22
|
-
],
|
|
23
|
-
future: {
|
|
24
|
-
v2_errorBoundary: true,
|
|
25
|
-
v2_headers: true,
|
|
26
|
-
v2_meta: true,
|
|
27
|
-
v2_normalizeFormMethod: true,
|
|
28
|
-
v2_routeConvention: true,
|
|
29
|
-
v2_dev: true,
|
|
30
|
-
},
|
|
31
|
-
};
|