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 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
- generateResourcesLoader,
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 mergeJsonFiles = async (sourcePath, destinationPath) => {
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(sourceJson), JSON.parse(destinationJson)),
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 mergeJsonFiles(
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
- assets: siteData.assets,
556
- breakpoints: siteData.build?.breakpoints,
557
- styles: siteData.build?.styles,
558
- styleSourceSelections: siteData.build?.styleSourceSelections,
559
- // pass only used metas to not generate unused preset styles
560
- componentMetas: projectMetas
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 { Asset, FontAsset, ImageAsset, ProjectMeta, System } from "@webstudio-is/sdk";
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
- import type { PageData } from "~/routes/_index";
668
- export const imageAssets: ImageAsset[] = ${JSON.stringify(imageAssets)}
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[] = ${JSON.stringify(pageFontAssets)}
655
+ export const pageFontAssets: FontAsset[] =
656
+ ${JSON.stringify(pageFontAssets)}
672
657
 
673
- export const pageBackgroundImageAssets: ImageAsset[] = ${JSON.stringify(
674
- pageBackgroundImageAssets
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
- ${utilsExport}
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
- generateResourcesLoader({
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 LoaderArgs, redirect } from "@remix-run/server-runtime";
737
+ const content = `import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
739
738
 
740
- export const loader = (arg: LoaderArgs) => {
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.142.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: "^3.12.8",
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.142.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.142.0",
32
- "@webstudio-is/react-sdk": "0.142.0",
33
- "@webstudio-is/sdk": "0.142.0",
34
- "@webstudio-is/sdk-components-react": "0.142.0",
35
- "@webstudio-is/image": "0.142.0",
36
- "@webstudio-is/sdk-components-react-remix": "0.142.0",
37
- "@webstudio-is/sdk-components-react-radix": "0.142.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": "^3.12.8",
42
+ "tsx": "^4.7.2",
43
43
  "typescript": "5.2.2",
44
- "@webstudio-is/form-handlers": "0.142.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 V2_ServerRuntimeMetaFunction,
3
+ type ServerRuntimeMetaFunction as MetaFunction,
4
4
  type LinksFunction,
5
5
  type LinkDescriptor,
6
- type ActionArgs,
7
- type LoaderArgs,
8
- type HeadersArgs,
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
- imageAssets,
23
- getRemixParams,
24
- getPageMeta,
17
+ favIconAsset,
18
+ socialImageAsset,
25
19
  pageFontAssets,
26
20
  pageBackgroundImageAssets,
27
21
  } from "../../../__generated__/_index";
28
- import { loadResources } from "../../../__generated__/_index.server";
29
- import css from "../__generated__/index.css";
30
- import { assetBaseUrl, imageBaseUrl, imageLoader } from "~/constants.mjs";
22
+ import {
23
+ formsProperties,
24
+ loadResources,
25
+ getPageMeta,
26
+ getRemixParams,
27
+ projectId,
28
+ user,
29
+ projectMeta,
30
+ } from "../../../__generated__/_index.server";
31
31
 
32
- export type PageData = {
33
- project?: ProjectMeta;
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: LoaderArgs) => {
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 }: HeadersArgs) => {
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: V2_ServerRuntimeMetaFunction<typeof loader> = ({ data }) => {
94
- const metas: ReturnType<V2_ServerRuntimeMetaFunction> = [];
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 (project?.siteName) {
120
+ if (projectMeta?.siteName) {
122
121
  metas.push({
123
122
  property: "og:site_name",
124
- content: project.siteName,
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: project.siteName,
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 (pageMeta.socialImageAssetId) {
155
- const imageAsset = imageAssets.find(
156
- (asset) => asset.id === pageMeta.socialImageAssetId
157
- );
158
-
159
- if (imageAsset) {
160
- metas.push({
161
- property: "og:image",
162
- content: `https://${data.host}${imageLoader({
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
- const { project } = pageData;
190
-
191
- if (project?.faviconAssetId) {
192
- const imageAsset = imageAssets.find(
193
- (asset) => asset.id === project.faviconAssetId
194
- );
195
-
196
- if (imageAsset) {
197
- result.push({
198
- rel: "icon",
199
- href: imageLoader({
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 }: ActionArgs) => {
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
- export { Root as default } from "@webstudio-is/react-sdk";
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 { LoaderArgs } from "@remix-run/server-runtime";
1
+ import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
2
2
 
3
- export const loader = (arg: LoaderArgs) => {
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 { LoaderArgs } from "@remix-run/server-runtime";
1
+ import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
2
2
  import { sitemap } from "../__generated__/[sitemap.xml]";
3
3
 
4
- export const loader = (arg: LoaderArgs) => {
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="@remix-run/dev" />
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": "^1.19.2",
11
- "@remix-run/server-runtime": "^1.19.2",
12
- "@remix-run/node": "^1.19.2",
13
- "@webstudio-is/react-sdk": "0.142.0",
14
- "@webstudio-is/sdk-components-react-radix": "0.142.0",
15
- "@webstudio-is/sdk-components-react-remix": "0.142.0",
16
- "@webstudio-is/sdk-components-react": "0.142.0",
17
- "@webstudio-is/form-handlers": "0.142.0",
18
- "@webstudio-is/image": "0.142.0",
19
- "@webstudio-is/sdk": "0.142.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/serve": "^1.19.2",
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": ["remix.env.d.ts", "**/*.ts", "**/*.tsx", "**/*.mjs"],
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 = "public"
3
+ publish = "build/client"
4
4
 
5
5
  [dev]
6
6
  command = "npm run dev"
7
- targetPort = 3000
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": "^1.3.0",
8
- "@netlify/edge-functions": "^2.0.0",
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
- import type { EntryContext } from "@remix-run/node";
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 = "remix build && cp _app_redirects public/_redirects"
3
- publish = "public"
2
+ command = "npm run build"
3
+ publish = "build/client"
4
4
 
5
5
  [dev]
6
6
  command = "npm run dev"
7
- targetPort = 3000
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
- # Set to 60 seconds as an example. You can also add cache headers via Remix. See the documentation on [headers](https://remix.run/docs/en/v1/route/headers) in Remix.
14
- "Cache-Control" = "public, max-age=60, s-maxage=60"
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": "^1.3.0",
8
- "@netlify/remix-adapter": "^1.0.0"
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,5 +1 @@
1
- {
2
- "scripts": {
3
- "start": "remix-serve build"
4
- }
5
- }
1
+ {}
@@ -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
- };
@@ -1,7 +0,0 @@
1
- import { createRequestHandler } from "@netlify/remix-adapter";
2
- import * as build from "@remix-run/dev/server-build";
3
-
4
- export const handler = createRequestHandler({
5
- build,
6
- mode: process.env.NODE_ENV,
7
- });