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/lib/cli.js
CHANGED
|
@@ -45,10 +45,11 @@ var jsonToGlobalConfig = (json) => {
|
|
|
45
45
|
return zGlobalConfig.parse(json);
|
|
46
46
|
};
|
|
47
47
|
var PROJECT_TEMPALTES = [
|
|
48
|
-
"vanilla",
|
|
49
|
-
"vercel",
|
|
50
|
-
"netlify-functions",
|
|
51
|
-
"netlify-edge-functions"
|
|
48
|
+
{ value: "vanilla", label: "Vanilla" },
|
|
49
|
+
{ value: "vercel", label: "Vercel" },
|
|
50
|
+
{ value: "netlify-functions", label: "Netlify Functions" },
|
|
51
|
+
{ value: "netlify-edge-functions", label: "Netlify Edge Functions" },
|
|
52
|
+
{ value: "ssg", label: "Static Site Generation (SSG)" }
|
|
52
53
|
];
|
|
53
54
|
|
|
54
55
|
// src/fs-utils.ts
|
|
@@ -258,14 +259,14 @@ import { exit as exit3 } from "node:process";
|
|
|
258
259
|
import { log as log3 } from "@clack/prompts";
|
|
259
260
|
|
|
260
261
|
// src/prebuild.ts
|
|
261
|
-
import { basename, dirname as dirname2, join as
|
|
262
|
-
import { createWriteStream } from "node:fs";
|
|
262
|
+
import { basename, dirname as dirname2, join as join6, normalize, relative } from "node:path";
|
|
263
|
+
import { createWriteStream, existsSync } from "node:fs";
|
|
263
264
|
import {
|
|
264
|
-
rm,
|
|
265
|
+
rm as rm3,
|
|
265
266
|
access as access2,
|
|
266
267
|
rename,
|
|
267
268
|
cp,
|
|
268
|
-
readFile as
|
|
269
|
+
readFile as readFile6,
|
|
269
270
|
writeFile as writeFile4,
|
|
270
271
|
readdir
|
|
271
272
|
} from "node:fs/promises";
|
|
@@ -279,9 +280,8 @@ import {
|
|
|
279
280
|
generateCss,
|
|
280
281
|
generateWebstudioComponent,
|
|
281
282
|
getIndexesWithinAncestors,
|
|
282
|
-
namespaceMeta,
|
|
283
283
|
normalizeProps,
|
|
284
|
-
generateRemixRoute,
|
|
284
|
+
generateRemixRoute as generateRemixRoute2,
|
|
285
285
|
generateRemixParams,
|
|
286
286
|
isCoreComponent
|
|
287
287
|
} from "@webstudio-is/react-sdk";
|
|
@@ -290,15 +290,12 @@ import {
|
|
|
290
290
|
findTreeInstanceIds,
|
|
291
291
|
getPagePath,
|
|
292
292
|
parseComponentName,
|
|
293
|
-
|
|
294
|
-
generateResourcesLoader,
|
|
293
|
+
generateResources,
|
|
295
294
|
generatePageMeta,
|
|
296
|
-
getStaticSiteMapXml
|
|
295
|
+
getStaticSiteMapXml,
|
|
296
|
+
replaceFormActionsWithResources
|
|
297
297
|
} from "@webstudio-is/sdk";
|
|
298
298
|
import { createImageLoader } from "@webstudio-is/image";
|
|
299
|
-
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
|
|
300
|
-
import * as remixComponentMetas from "@webstudio-is/sdk-components-react-remix/metas";
|
|
301
|
-
import * as radixComponentMetas from "@webstudio-is/sdk-components-react-radix/metas";
|
|
302
299
|
|
|
303
300
|
// src/html-to-jsx.ts
|
|
304
301
|
import {
|
|
@@ -414,10 +411,161 @@ var htmlToJsx = (html) => {
|
|
|
414
411
|
return result;
|
|
415
412
|
};
|
|
416
413
|
|
|
414
|
+
// src/framework-remix.ts
|
|
415
|
+
import { join as join4 } from "node:path";
|
|
416
|
+
import { readFile as readFile4, rm } from "node:fs/promises";
|
|
417
|
+
import {
|
|
418
|
+
generateRemixRoute,
|
|
419
|
+
namespaceMeta
|
|
420
|
+
} from "@webstudio-is/react-sdk";
|
|
421
|
+
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
|
|
422
|
+
import * as remixComponentMetas from "@webstudio-is/sdk-components-react-remix/metas";
|
|
423
|
+
import * as radixComponentMetas from "@webstudio-is/sdk-components-react-radix/metas";
|
|
424
|
+
var createFramework = async () => {
|
|
425
|
+
const routeTemplatesDir = join4("app", "route-templates");
|
|
426
|
+
const htmlTemplate = await readFile4(
|
|
427
|
+
join4(routeTemplatesDir, "html.tsx"),
|
|
428
|
+
"utf8"
|
|
429
|
+
);
|
|
430
|
+
const xmlTemplate = await readFile4(
|
|
431
|
+
join4(routeTemplatesDir, "xml.tsx"),
|
|
432
|
+
"utf8"
|
|
433
|
+
);
|
|
434
|
+
const defaultSitemapTemplate = await readFile4(
|
|
435
|
+
join4(routeTemplatesDir, "default-sitemap.tsx"),
|
|
436
|
+
"utf8"
|
|
437
|
+
);
|
|
438
|
+
const redirectTemplate = await readFile4(
|
|
439
|
+
join4(routeTemplatesDir, "redirect.tsx"),
|
|
440
|
+
"utf8"
|
|
441
|
+
);
|
|
442
|
+
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
443
|
+
const radixComponentNamespacedMetas = {};
|
|
444
|
+
for (const [name, meta] of Object.entries(radixComponentMetas)) {
|
|
445
|
+
const namespace = "@webstudio-is/sdk-components-react-radix";
|
|
446
|
+
radixComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta(
|
|
447
|
+
meta,
|
|
448
|
+
namespace,
|
|
449
|
+
new Set(Object.keys(radixComponentMetas))
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
return {
|
|
453
|
+
components: [
|
|
454
|
+
{
|
|
455
|
+
source: "@webstudio-is/sdk-components-react",
|
|
456
|
+
metas: baseComponentMetas
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
source: "@webstudio-is/sdk-components-react-radix",
|
|
460
|
+
metas: radixComponentNamespacedMetas
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
source: "@webstudio-is/sdk-components-react-remix",
|
|
464
|
+
metas: remixComponentMetas
|
|
465
|
+
}
|
|
466
|
+
],
|
|
467
|
+
html: ({ pagePath }) => [
|
|
468
|
+
{
|
|
469
|
+
file: join4("app", "routes", `${generateRemixRoute(pagePath)}.tsx`),
|
|
470
|
+
template: htmlTemplate
|
|
471
|
+
}
|
|
472
|
+
],
|
|
473
|
+
xml: ({ pagePath }) => [
|
|
474
|
+
{
|
|
475
|
+
file: join4("app", "routes", `${generateRemixRoute(pagePath)}.tsx`),
|
|
476
|
+
template: xmlTemplate
|
|
477
|
+
}
|
|
478
|
+
],
|
|
479
|
+
redirect: ({ pagePath }) => [
|
|
480
|
+
{
|
|
481
|
+
file: join4("app", "routes", `${generateRemixRoute(pagePath)}.ts`),
|
|
482
|
+
template: redirectTemplate
|
|
483
|
+
}
|
|
484
|
+
],
|
|
485
|
+
defaultSitemap: () => [
|
|
486
|
+
{
|
|
487
|
+
file: join4(
|
|
488
|
+
"app",
|
|
489
|
+
"routes",
|
|
490
|
+
`${generateRemixRoute("/sitemap.xml")}.tsx`
|
|
491
|
+
),
|
|
492
|
+
template: defaultSitemapTemplate
|
|
493
|
+
}
|
|
494
|
+
]
|
|
495
|
+
};
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
// src/framework-vike-ssg.ts
|
|
499
|
+
import { join as join5 } from "node:path";
|
|
500
|
+
import { readFile as readFile5, rm as rm2 } from "node:fs/promises";
|
|
501
|
+
import { namespaceMeta as namespaceMeta2 } from "@webstudio-is/react-sdk";
|
|
502
|
+
import * as baseComponentMetas2 from "@webstudio-is/sdk-components-react/metas";
|
|
503
|
+
import * as radixComponentMetas2 from "@webstudio-is/sdk-components-react-radix/metas";
|
|
504
|
+
var generateVikeRoute = (pagePath) => {
|
|
505
|
+
if (pagePath === "/") {
|
|
506
|
+
return "index";
|
|
507
|
+
}
|
|
508
|
+
return pagePath;
|
|
509
|
+
};
|
|
510
|
+
var createFramework2 = async () => {
|
|
511
|
+
const routeTemplatesDir = join5("app", "route-templates");
|
|
512
|
+
const htmlPageTemplate = await readFile5(
|
|
513
|
+
join5(routeTemplatesDir, "html", "+Page.tsx"),
|
|
514
|
+
"utf8"
|
|
515
|
+
);
|
|
516
|
+
const htmlHeadTemplate = await readFile5(
|
|
517
|
+
join5(routeTemplatesDir, "html", "+Head.tsx"),
|
|
518
|
+
"utf8"
|
|
519
|
+
);
|
|
520
|
+
const htmlDataTemplate = await readFile5(
|
|
521
|
+
join5(routeTemplatesDir, "html", "+data.ts"),
|
|
522
|
+
"utf8"
|
|
523
|
+
);
|
|
524
|
+
await rm2(routeTemplatesDir, { recursive: true, force: true });
|
|
525
|
+
const radixComponentNamespacedMetas = {};
|
|
526
|
+
for (const [name, meta] of Object.entries(radixComponentMetas2)) {
|
|
527
|
+
const namespace = "@webstudio-is/sdk-components-react-radix";
|
|
528
|
+
radixComponentNamespacedMetas[`${namespace}:${name}`] = namespaceMeta2(
|
|
529
|
+
meta,
|
|
530
|
+
namespace,
|
|
531
|
+
new Set(Object.keys(radixComponentMetas2))
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
return {
|
|
535
|
+
components: [
|
|
536
|
+
{
|
|
537
|
+
source: "@webstudio-is/sdk-components-react",
|
|
538
|
+
metas: baseComponentMetas2
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
source: "@webstudio-is/sdk-components-react-radix",
|
|
542
|
+
metas: radixComponentNamespacedMetas
|
|
543
|
+
}
|
|
544
|
+
],
|
|
545
|
+
html: ({ pagePath }) => [
|
|
546
|
+
{
|
|
547
|
+
file: join5("pages", generateVikeRoute(pagePath), "+Page.tsx"),
|
|
548
|
+
template: htmlPageTemplate
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
file: join5("pages", generateVikeRoute(pagePath), "+Head.tsx"),
|
|
552
|
+
template: htmlHeadTemplate
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
file: join5("pages", generateVikeRoute(pagePath), "+data.ts"),
|
|
556
|
+
template: htmlDataTemplate
|
|
557
|
+
}
|
|
558
|
+
],
|
|
559
|
+
xml: () => [],
|
|
560
|
+
redirect: () => [],
|
|
561
|
+
defaultSitemap: () => []
|
|
562
|
+
};
|
|
563
|
+
};
|
|
564
|
+
|
|
417
565
|
// src/prebuild.ts
|
|
418
566
|
var limit = pLimit(10);
|
|
419
567
|
var downloadAsset = async (url, name, assetBaseUrl) => {
|
|
420
|
-
const assetPath =
|
|
568
|
+
const assetPath = join6("public", assetBaseUrl, name);
|
|
421
569
|
const tempAssetPath = `${assetPath}.tmp`;
|
|
422
570
|
try {
|
|
423
571
|
await access2(assetPath);
|
|
@@ -441,8 +589,8 @@ var downloadAsset = async (url, name, assetBaseUrl) => {
|
|
|
441
589
|
}
|
|
442
590
|
};
|
|
443
591
|
var mergeJsonInto = async (sourcePath, destinationPath) => {
|
|
444
|
-
const sourceJson = await
|
|
445
|
-
const destinationJson = await
|
|
592
|
+
const sourceJson = await readFile6(sourcePath, "utf8");
|
|
593
|
+
const destinationJson = await readFile6(destinationPath, "utf8").catch(
|
|
446
594
|
(error) => {
|
|
447
595
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
448
596
|
return "{}";
|
|
@@ -451,7 +599,9 @@ var mergeJsonInto = async (sourcePath, destinationPath) => {
|
|
|
451
599
|
}
|
|
452
600
|
);
|
|
453
601
|
const content = JSON.stringify(
|
|
454
|
-
merge(JSON.parse(destinationJson), JSON.parse(sourceJson)
|
|
602
|
+
merge(JSON.parse(destinationJson), JSON.parse(sourceJson), {
|
|
603
|
+
arrayMerge: (_target, source) => source
|
|
604
|
+
}),
|
|
455
605
|
null,
|
|
456
606
|
" "
|
|
457
607
|
);
|
|
@@ -460,7 +610,7 @@ var mergeJsonInto = async (sourcePath, destinationPath) => {
|
|
|
460
610
|
var isCliTemplate = async (template) => {
|
|
461
611
|
const currentPath = fileURLToPath(new URL(import.meta.url));
|
|
462
612
|
const templatesPath = normalize(
|
|
463
|
-
|
|
613
|
+
join6(dirname2(currentPath), "..", "templates")
|
|
464
614
|
);
|
|
465
615
|
const dirents = await readdir(templatesPath, { withFileTypes: true });
|
|
466
616
|
for (const dirent of dirents) {
|
|
@@ -472,23 +622,33 @@ var isCliTemplate = async (template) => {
|
|
|
472
622
|
};
|
|
473
623
|
var getTemplatePath = async (template) => {
|
|
474
624
|
const currentPath = fileURLToPath(new URL(import.meta.url));
|
|
475
|
-
const templatePath = await isCliTemplate(template) ? normalize(
|
|
625
|
+
const templatePath = await isCliTemplate(template) ? normalize(join6(dirname2(currentPath), "..", "templates", template)) : template;
|
|
476
626
|
return templatePath;
|
|
477
627
|
};
|
|
478
|
-
var copyTemplates = async (template
|
|
628
|
+
var copyTemplates = async (template) => {
|
|
479
629
|
const templatePath = await getTemplatePath(template);
|
|
480
630
|
await cp(templatePath, cwd3(), {
|
|
481
631
|
recursive: true,
|
|
482
632
|
filter: (source) => {
|
|
483
|
-
|
|
633
|
+
const name = basename(source);
|
|
634
|
+
return name !== "package.json" && name !== "tsconfig.json";
|
|
484
635
|
}
|
|
485
636
|
});
|
|
486
|
-
if (
|
|
637
|
+
if (existsSync(join6(templatePath, "package.json"))) {
|
|
487
638
|
await mergeJsonInto(
|
|
488
|
-
|
|
489
|
-
|
|
639
|
+
join6(templatePath, "package.json"),
|
|
640
|
+
join6(cwd3(), "package.json")
|
|
490
641
|
);
|
|
491
642
|
}
|
|
643
|
+
if (existsSync(join6(templatePath, "tsconfig.json"))) {
|
|
644
|
+
await mergeJsonInto(
|
|
645
|
+
join6(templatePath, "tsconfig.json"),
|
|
646
|
+
join6(cwd3(), "tsconfig.json")
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
var importFrom = (importee, importer) => {
|
|
651
|
+
return relative(dirname2(importer), importee).replaceAll("\\", "/");
|
|
492
652
|
};
|
|
493
653
|
var prebuild = async (options) => {
|
|
494
654
|
if (options.template.length === 0) {
|
|
@@ -499,7 +659,7 @@ Please check webstudio --help for more details`
|
|
|
499
659
|
exit2(1);
|
|
500
660
|
}
|
|
501
661
|
for (const template of options.template) {
|
|
502
|
-
if (template === "vanilla") {
|
|
662
|
+
if (template === "vanilla" || template === "ssg") {
|
|
503
663
|
continue;
|
|
504
664
|
}
|
|
505
665
|
if (template.startsWith(".") || template.startsWith("/")) {
|
|
@@ -515,19 +675,25 @@ Please check webstudio --help for more details`
|
|
|
515
675
|
}
|
|
516
676
|
log2.step("Scaffolding the project files");
|
|
517
677
|
const appRoot = "app";
|
|
518
|
-
const generatedDir =
|
|
519
|
-
await
|
|
520
|
-
const routesDir =
|
|
521
|
-
await
|
|
522
|
-
await copyTemplates();
|
|
523
|
-
await writeFile4(
|
|
678
|
+
const generatedDir = join6(appRoot, "__generated__");
|
|
679
|
+
await rm3(generatedDir, { recursive: true, force: true });
|
|
680
|
+
const routesDir = join6(appRoot, "routes");
|
|
681
|
+
await rm3(routesDir, { recursive: true, force: true });
|
|
682
|
+
await copyTemplates(options.template.includes("ssg") ? "ssg" : "defaults");
|
|
683
|
+
await writeFile4(join6(cwd3(), ".npmrc"), "force=true");
|
|
524
684
|
for (const template of options.template) {
|
|
525
|
-
if (template === "vanilla") {
|
|
685
|
+
if (template === "vanilla" || template === "ssg") {
|
|
526
686
|
continue;
|
|
527
687
|
}
|
|
528
688
|
await copyTemplates(template);
|
|
529
689
|
}
|
|
530
|
-
|
|
690
|
+
let framework;
|
|
691
|
+
if (options.template.includes("ssg")) {
|
|
692
|
+
framework = await createFramework2();
|
|
693
|
+
} else {
|
|
694
|
+
framework = await createFramework();
|
|
695
|
+
}
|
|
696
|
+
const constants2 = await import(pathToFileURL(join6(cwd3(), "app/constants.mjs")).href);
|
|
531
697
|
const { assetBaseUrl } = constants2;
|
|
532
698
|
const siteData = await loadJSONFile(LOCAL_DATA_FILE);
|
|
533
699
|
if (siteData === null) {
|
|
@@ -539,27 +705,14 @@ Please check webstudio --help for more details`
|
|
|
539
705
|
if (domain === void 0) {
|
|
540
706
|
throw new Error(`Project domain is missing from the project data`);
|
|
541
707
|
}
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
)
|
|
545
|
-
(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
new Set(Object.keys(radixComponentMetas))
|
|
551
|
-
);
|
|
552
|
-
return r;
|
|
553
|
-
},
|
|
554
|
-
{}
|
|
555
|
-
);
|
|
556
|
-
const metas = new Map(
|
|
557
|
-
Object.entries({
|
|
558
|
-
...baseComponentMetas,
|
|
559
|
-
...radixComponentNamespacedMetas,
|
|
560
|
-
...remixComponentMetas
|
|
561
|
-
})
|
|
562
|
-
);
|
|
708
|
+
const metas = /* @__PURE__ */ new Map();
|
|
709
|
+
const componentSources = /* @__PURE__ */ new Map();
|
|
710
|
+
for (const entry of framework.components) {
|
|
711
|
+
for (const [componentName, meta] of Object.entries(entry.metas)) {
|
|
712
|
+
metas.set(componentName, meta);
|
|
713
|
+
componentSources.set(componentName, entry.source);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
563
716
|
const projectMetas = /* @__PURE__ */ new Map();
|
|
564
717
|
const componentsByPage = {};
|
|
565
718
|
const siteDataByPage = {};
|
|
@@ -577,7 +730,9 @@ Please check webstudio --help for more details`
|
|
|
577
730
|
props: siteData.build.props.map(([_id, prop]) => prop),
|
|
578
731
|
assetBaseUrl,
|
|
579
732
|
assets: new Map(siteData.assets.map((asset) => [asset.id, asset])),
|
|
580
|
-
|
|
733
|
+
uploadingImageAssets: [],
|
|
734
|
+
pages: siteData.build.pages,
|
|
735
|
+
source: "prebuild"
|
|
581
736
|
});
|
|
582
737
|
const props = [];
|
|
583
738
|
for (const prop of normalizedProps) {
|
|
@@ -677,7 +832,7 @@ Please check webstudio --help for more details`
|
|
|
677
832
|
}
|
|
678
833
|
}
|
|
679
834
|
const assets = new Map(siteData.assets.map((asset) => [asset.id, asset]));
|
|
680
|
-
const { cssText,
|
|
835
|
+
const { cssText, classes } = generateCss({
|
|
681
836
|
instances: new Map(siteData.build.instances),
|
|
682
837
|
props: new Map(siteData.build.props),
|
|
683
838
|
assets,
|
|
@@ -689,17 +844,7 @@ Please check webstudio --help for more details`
|
|
|
689
844
|
assetBaseUrl,
|
|
690
845
|
atomic: siteData.build.pages.compiler?.atomicStyles ?? true
|
|
691
846
|
});
|
|
692
|
-
await createFileIfNotExists(
|
|
693
|
-
const routeTemplatesDir = join4(cwd3(), "app/route-templates");
|
|
694
|
-
const routeTemplatePath = normalize(join4(routeTemplatesDir, "html.tsx"));
|
|
695
|
-
const routeXmlTemplatePath = normalize(join4(routeTemplatesDir, "xml.tsx"));
|
|
696
|
-
const defaultSiteMapXmlPath = normalize(
|
|
697
|
-
join4(routeTemplatesDir, "default-sitemap.tsx")
|
|
698
|
-
);
|
|
699
|
-
const routeFileTemplate = await readFile4(routeTemplatePath, "utf8");
|
|
700
|
-
const routeXmlFileTemplate = await readFile4(routeXmlTemplatePath, "utf8");
|
|
701
|
-
const defaultSiteMapTemplate = await readFile4(defaultSiteMapXmlPath, "utf8");
|
|
702
|
-
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
847
|
+
await createFileIfNotExists(join6(generatedDir, "index.css"), cssText);
|
|
703
848
|
for (const [pageId, pageComponents] of Object.entries(componentsByPage)) {
|
|
704
849
|
const scope = createScope([
|
|
705
850
|
// manually maintained list of occupied identifiers
|
|
@@ -710,18 +855,10 @@ Please check webstudio --help for more details`
|
|
|
710
855
|
"_props"
|
|
711
856
|
]);
|
|
712
857
|
const namespaces = /* @__PURE__ */ new Map();
|
|
713
|
-
const BASE_NAMESPACE = "@webstudio-is/sdk-components-react";
|
|
714
|
-
const REMIX_NAMESPACE = "@webstudio-is/sdk-components-react-remix";
|
|
715
858
|
for (const component of pageComponents) {
|
|
716
|
-
const
|
|
717
|
-
let [namespace] = parsed;
|
|
718
|
-
const [_namespace, shortName] = parsed;
|
|
859
|
+
const namespace = componentSources.get(component);
|
|
719
860
|
if (namespace === void 0) {
|
|
720
|
-
|
|
721
|
-
namespace = REMIX_NAMESPACE;
|
|
722
|
-
} else {
|
|
723
|
-
namespace = BASE_NAMESPACE;
|
|
724
|
-
}
|
|
861
|
+
continue;
|
|
725
862
|
}
|
|
726
863
|
if (namespaces.has(namespace) === false) {
|
|
727
864
|
namespaces.set(
|
|
@@ -729,6 +866,7 @@ Please check webstudio --help for more details`
|
|
|
729
866
|
/* @__PURE__ */ new Set()
|
|
730
867
|
);
|
|
731
868
|
}
|
|
869
|
+
const [_namespace, shortName] = parseComponentName(component);
|
|
732
870
|
namespaces.get(namespace)?.add([shortName, component]);
|
|
733
871
|
}
|
|
734
872
|
let componentImports = "";
|
|
@@ -769,6 +907,11 @@ Please check webstudio --help for more details`
|
|
|
769
907
|
const props = new Map(pageData.build.props);
|
|
770
908
|
const dataSources = new Map(pageData.build.dataSources);
|
|
771
909
|
const resources = new Map(pageData.build.resources);
|
|
910
|
+
replaceFormActionsWithResources({
|
|
911
|
+
instances,
|
|
912
|
+
resources,
|
|
913
|
+
props
|
|
914
|
+
});
|
|
772
915
|
const pageComponent = generateWebstudioComponent({
|
|
773
916
|
scope,
|
|
774
917
|
name: "Page",
|
|
@@ -785,7 +928,7 @@ Please check webstudio --help for more details`
|
|
|
785
928
|
instances,
|
|
786
929
|
props,
|
|
787
930
|
dataSources,
|
|
788
|
-
classesMap,
|
|
931
|
+
classesMap: classes,
|
|
789
932
|
indexesWithinAncestors: getIndexesWithinAncestors(
|
|
790
933
|
projectMetas,
|
|
791
934
|
instances,
|
|
@@ -797,12 +940,8 @@ Please check webstudio --help for more details`
|
|
|
797
940
|
// fallback to user email when contact email is empty string
|
|
798
941
|
projectMeta?.contactEmail || siteData.user?.email || void 0
|
|
799
942
|
);
|
|
800
|
-
const pageMeta = pageData.page.meta;
|
|
801
943
|
const favIconAsset = assets.get(projectMeta?.faviconAssetId ?? "");
|
|
802
|
-
const socialImageAsset = assets.get(pageMeta.socialImageAssetId ?? "");
|
|
803
944
|
const pagePath = getPagePath(pageData.page.id, siteData.build.pages);
|
|
804
|
-
const remixRoute = generateRemixRoute(pagePath);
|
|
805
|
-
const fileName = `${remixRoute}.tsx`;
|
|
806
945
|
const pageExports = `/* eslint-disable */
|
|
807
946
|
/* This is a auto generated file for building the project */
|
|
808
947
|
|
|
@@ -817,9 +956,6 @@ Please check webstudio --help for more details`
|
|
|
817
956
|
export const favIconAsset: ImageAsset | undefined =
|
|
818
957
|
${JSON.stringify(favIconAsset)};
|
|
819
958
|
|
|
820
|
-
export const socialImageAsset: ImageAsset | undefined =
|
|
821
|
-
${JSON.stringify(socialImageAsset)};
|
|
822
|
-
|
|
823
959
|
// Font assets on current page (can be preloaded)
|
|
824
960
|
export const pageFontAssets: FontAsset[] =
|
|
825
961
|
${JSON.stringify(pageFontAssets)}
|
|
@@ -827,7 +963,7 @@ Please check webstudio --help for more details`
|
|
|
827
963
|
export const pageBackgroundImageAssets: ImageAsset[] =
|
|
828
964
|
${JSON.stringify(pageBackgroundImageAssets)}
|
|
829
965
|
|
|
830
|
-
${
|
|
966
|
+
${pagePath === "/" ? `
|
|
831
967
|
${projectMeta?.code ? `
|
|
832
968
|
const Script = ({children, ...props}: Record<string, string | boolean>) => {
|
|
833
969
|
if (children == null) {
|
|
@@ -861,47 +997,59 @@ Please check webstudio --help for more details`
|
|
|
861
997
|
|
|
862
998
|
|
|
863
999
|
import type { PageMeta } from "@webstudio-is/sdk";
|
|
864
|
-
${
|
|
1000
|
+
${generateResources({
|
|
865
1001
|
scope,
|
|
866
1002
|
page: pageData.page,
|
|
867
1003
|
dataSources,
|
|
1004
|
+
props,
|
|
868
1005
|
resources
|
|
869
1006
|
})}
|
|
870
1007
|
|
|
871
1008
|
${generatePageMeta({
|
|
872
1009
|
globalScope: scope,
|
|
873
1010
|
page: pageData.page,
|
|
874
|
-
dataSources
|
|
1011
|
+
dataSources,
|
|
1012
|
+
assets
|
|
875
1013
|
})}
|
|
876
1014
|
|
|
877
|
-
${generateFormsProperties(props)}
|
|
878
|
-
|
|
879
1015
|
${generateRemixParams(pageData.page.path)}
|
|
880
1016
|
|
|
881
1017
|
export const projectId = "${siteData.build.projectId}";
|
|
882
1018
|
|
|
883
1019
|
export const contactEmail = ${JSON.stringify(contactEmail)};
|
|
884
1020
|
`;
|
|
885
|
-
const
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
)
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
)
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1021
|
+
const generatedBasename = generateRemixRoute2(pagePath);
|
|
1022
|
+
const clientFile = join6(generatedDir, `${generatedBasename}.tsx`);
|
|
1023
|
+
await createFileIfNotExists(clientFile, pageExports);
|
|
1024
|
+
const serverFile = join6(generatedDir, `${generatedBasename}.server.tsx`);
|
|
1025
|
+
await createFileIfNotExists(serverFile, serverExports);
|
|
1026
|
+
const getTemplates = documentType === "html" ? framework.html : framework.xml;
|
|
1027
|
+
for (const { file, template } of getTemplates({ pagePath })) {
|
|
1028
|
+
const content = template.replaceAll("__CONSTANTS__", importFrom("./app/constants.mjs", file)).replaceAll(
|
|
1029
|
+
"__SITEMAP__",
|
|
1030
|
+
importFrom(`./app/__generated__/$resources.sitemap.xml`, file)
|
|
1031
|
+
).replaceAll(
|
|
1032
|
+
"__CLIENT__",
|
|
1033
|
+
importFrom(`./app/__generated__/${generatedBasename}`, file)
|
|
1034
|
+
).replaceAll(
|
|
1035
|
+
"__SERVER__",
|
|
1036
|
+
importFrom(`./app/__generated__/${generatedBasename}.server`, file)
|
|
1037
|
+
).replaceAll(
|
|
1038
|
+
"__CSS__",
|
|
1039
|
+
importFrom(`./app/__generated__/index.css`, file)
|
|
1040
|
+
);
|
|
1041
|
+
await createFileIfNotExists(file, content);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
for (const { file, template } of framework.defaultSitemap()) {
|
|
1045
|
+
const content = template.replaceAll(
|
|
1046
|
+
"__SITEMAP__",
|
|
1047
|
+
importFrom(`./app/__generated__/$resources.sitemap.xml`, file)
|
|
897
1048
|
);
|
|
1049
|
+
await createFileIfNotExists(file, content);
|
|
898
1050
|
}
|
|
899
1051
|
await createFileIfNotExists(
|
|
900
|
-
|
|
901
|
-
defaultSiteMapTemplate.replace(/".*\/__generated__\//, `"../__generated__/`)
|
|
902
|
-
);
|
|
903
|
-
await createFileIfNotExists(
|
|
904
|
-
join4(generatedDir, "$resources.sitemap.xml.ts"),
|
|
1052
|
+
join6(generatedDir, "$resources.sitemap.xml.ts"),
|
|
905
1053
|
`
|
|
906
1054
|
export const sitemap = ${JSON.stringify(
|
|
907
1055
|
getStaticSiteMapXml(siteData.build.pages, siteData.build.updatedAt),
|
|
@@ -913,15 +1061,23 @@ Please check webstudio --help for more details`
|
|
|
913
1061
|
const redirects = siteData.build.pages?.redirects;
|
|
914
1062
|
if (redirects !== void 0 && redirects.length > 0) {
|
|
915
1063
|
for (const redirect of redirects) {
|
|
916
|
-
const
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1064
|
+
const generatedBasename = generateRemixRoute2(redirect.old);
|
|
1065
|
+
await createFileIfNotExists(
|
|
1066
|
+
join6(generatedDir, `${generatedBasename}.ts`),
|
|
1067
|
+
`
|
|
1068
|
+
export const url = "${redirect.new}";
|
|
1069
|
+
export const status = ${redirect.status ?? 301};
|
|
1070
|
+
`
|
|
1071
|
+
);
|
|
1072
|
+
for (const { file, template } of framework.redirect({
|
|
1073
|
+
pagePath: redirect.old
|
|
1074
|
+
})) {
|
|
1075
|
+
const content = template.replaceAll(
|
|
1076
|
+
"__REDIRECT__",
|
|
1077
|
+
importFrom(`./app/__generated__/${generatedBasename}`, file)
|
|
1078
|
+
);
|
|
1079
|
+
await createFileIfNotExists(file, content);
|
|
1080
|
+
}
|
|
925
1081
|
}
|
|
926
1082
|
}
|
|
927
1083
|
if (assetsToDownload.length > 0) {
|
|
@@ -946,9 +1102,9 @@ var buildOptions = (yargs) => yargs.option("assets", {
|
|
|
946
1102
|
type: "array",
|
|
947
1103
|
string: true,
|
|
948
1104
|
default: [],
|
|
949
|
-
describe: `Template to use for the build [choices: ${PROJECT_TEMPALTES.
|
|
950
|
-
|
|
951
|
-
)}]`
|
|
1105
|
+
describe: `Template to use for the build [choices: ${PROJECT_TEMPALTES.map(
|
|
1106
|
+
(item) => item.value
|
|
1107
|
+
).join(", ")}]`
|
|
952
1108
|
});
|
|
953
1109
|
var build = async (options) => {
|
|
954
1110
|
try {
|
|
@@ -967,7 +1123,7 @@ var build = async (options) => {
|
|
|
967
1123
|
|
|
968
1124
|
// src/commands/init-flow.ts
|
|
969
1125
|
import { chdir, cwd as cwd4 } from "node:process";
|
|
970
|
-
import { join as
|
|
1126
|
+
import { join as join7 } from "node:path";
|
|
971
1127
|
import pc2 from "picocolors";
|
|
972
1128
|
import {
|
|
973
1129
|
cancel as cancel2,
|
|
@@ -979,7 +1135,6 @@ import {
|
|
|
979
1135
|
text as text2
|
|
980
1136
|
} from "@clack/prompts";
|
|
981
1137
|
import { $ } from "execa";
|
|
982
|
-
import { titleCase } from "title-case";
|
|
983
1138
|
var exitIfCancelled = (value) => {
|
|
984
1139
|
if (isCancel2(value)) {
|
|
985
1140
|
cancel2("Project initialization is cancelled");
|
|
@@ -1010,8 +1165,8 @@ var initFlow = async (options) => {
|
|
|
1010
1165
|
}
|
|
1011
1166
|
})
|
|
1012
1167
|
);
|
|
1013
|
-
await createFolderIfNotExists(
|
|
1014
|
-
chdir(
|
|
1168
|
+
await createFolderIfNotExists(join7(cwd4(), folderName));
|
|
1169
|
+
chdir(join7(cwd4(), folderName));
|
|
1015
1170
|
}
|
|
1016
1171
|
const shareLink = exitIfCancelled(
|
|
1017
1172
|
await text2({
|
|
@@ -1023,10 +1178,7 @@ var initFlow = async (options) => {
|
|
|
1023
1178
|
projectTemplate = exitIfCancelled(
|
|
1024
1179
|
await select({
|
|
1025
1180
|
message: "Where would you like to deploy your project?",
|
|
1026
|
-
options: PROJECT_TEMPALTES
|
|
1027
|
-
value: template,
|
|
1028
|
-
label: titleCase(template)
|
|
1029
|
-
}))
|
|
1181
|
+
options: PROJECT_TEMPALTES
|
|
1030
1182
|
})
|
|
1031
1183
|
);
|
|
1032
1184
|
shouldInstallDeps = exitIfCancelled(
|
|
@@ -1040,10 +1192,7 @@ var initFlow = async (options) => {
|
|
|
1040
1192
|
projectTemplate = exitIfCancelled(
|
|
1041
1193
|
await select({
|
|
1042
1194
|
message: "Where would you like to deploy your project?",
|
|
1043
|
-
options: PROJECT_TEMPALTES
|
|
1044
|
-
value: template,
|
|
1045
|
-
label: titleCase(template)
|
|
1046
|
-
}))
|
|
1195
|
+
options: PROJECT_TEMPALTES
|
|
1047
1196
|
})
|
|
1048
1197
|
);
|
|
1049
1198
|
}
|
|
@@ -1093,7 +1242,7 @@ import makeCLI from "yargs";
|
|
|
1093
1242
|
// package.json
|
|
1094
1243
|
var package_default = {
|
|
1095
1244
|
name: "webstudio",
|
|
1096
|
-
version: "0.
|
|
1245
|
+
version: "0.173.0",
|
|
1097
1246
|
description: "Webstudio CLI",
|
|
1098
1247
|
author: "Webstudio <github@webstudio.is>",
|
|
1099
1248
|
homepage: "https://webstudio.is",
|
|
@@ -1116,9 +1265,7 @@ var package_default = {
|
|
|
1116
1265
|
],
|
|
1117
1266
|
scripts: {
|
|
1118
1267
|
typecheck: "tsc",
|
|
1119
|
-
checks: "pnpm typecheck",
|
|
1120
1268
|
build: "rm -rf lib && esbuild src/cli.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
1121
|
-
dev: "esbuild src/cli.ts --watch --bundle --format=esm --packages=external --outdir=./lib",
|
|
1122
1269
|
test: "NODE_OPTIONS=--experimental-vm-modules jest"
|
|
1123
1270
|
},
|
|
1124
1271
|
license: "AGPL-3.0-or-later",
|
|
@@ -1142,7 +1289,6 @@ var package_default = {
|
|
|
1142
1289
|
parse5: "7.1.2",
|
|
1143
1290
|
picocolors: "^1.0.1",
|
|
1144
1291
|
"strip-indent": "^4.0.0",
|
|
1145
|
-
"title-case": "^4.1.0",
|
|
1146
1292
|
yargs: "^17.7.2",
|
|
1147
1293
|
zod: "^3.22.4"
|
|
1148
1294
|
},
|
|
@@ -1150,24 +1296,26 @@ var package_default = {
|
|
|
1150
1296
|
"@jest/globals": "^29.7.0",
|
|
1151
1297
|
"@netlify/remix-adapter": "^2.4.0",
|
|
1152
1298
|
"@netlify/remix-edge-adapter": "3.3.0",
|
|
1153
|
-
"@remix-run/cloudflare": "^2.
|
|
1154
|
-
"@remix-run/cloudflare-pages": "^2.
|
|
1155
|
-
"@remix-run/dev": "^2.
|
|
1156
|
-
"@remix-run/node": "^2.
|
|
1157
|
-
"@remix-run/react": "^2.
|
|
1158
|
-
"@remix-run/server-runtime": "^2.
|
|
1299
|
+
"@remix-run/cloudflare": "^2.10.3",
|
|
1300
|
+
"@remix-run/cloudflare-pages": "^2.10.3",
|
|
1301
|
+
"@remix-run/dev": "^2.10.3",
|
|
1302
|
+
"@remix-run/node": "^2.10.3",
|
|
1303
|
+
"@remix-run/react": "^2.10.3",
|
|
1304
|
+
"@remix-run/server-runtime": "^2.10.3",
|
|
1159
1305
|
"@types/node": "^20.12.7",
|
|
1160
1306
|
"@types/react": "^18.2.70",
|
|
1161
1307
|
"@types/react-dom": "^18.2.25",
|
|
1162
1308
|
"@types/yargs": "^17.0.32",
|
|
1309
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
1163
1310
|
"@webstudio-is/form-handlers": "workspace:*",
|
|
1164
1311
|
"@webstudio-is/jest-config": "workspace:*",
|
|
1165
1312
|
"@webstudio-is/tsconfig": "workspace:*",
|
|
1166
1313
|
react: "18.3.0-canary-14898b6a9-20240318",
|
|
1167
1314
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
1168
|
-
typescript: "5.
|
|
1169
|
-
|
|
1170
|
-
|
|
1315
|
+
typescript: "5.5.2",
|
|
1316
|
+
vike: "^0.4.180",
|
|
1317
|
+
vite: "^5.3.4",
|
|
1318
|
+
wrangler: "^3.63.2"
|
|
1171
1319
|
}
|
|
1172
1320
|
};
|
|
1173
1321
|
|