webstudio 0.167.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/README.md +1 -1
- package/bin.js +1 -1
- package/lib/cli.js +310 -153
- package/package.json +33 -26
- 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 +76 -71
- 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 {
|
|
@@ -367,6 +364,7 @@ var convertStyleString = (style) => {
|
|
|
367
364
|
}
|
|
368
365
|
return JSON.stringify(res);
|
|
369
366
|
};
|
|
367
|
+
var escape = (value) => JSON.stringify(value);
|
|
370
368
|
var toAttrString = (name, value) => {
|
|
371
369
|
const attName = name.toLowerCase();
|
|
372
370
|
const jsxName = attName === "class" ? "className" : attName;
|
|
@@ -376,7 +374,7 @@ var toAttrString = (name, value) => {
|
|
|
376
374
|
if (attName === "style") {
|
|
377
375
|
return `${jsxName}={${convertStyleString(value)}}`;
|
|
378
376
|
}
|
|
379
|
-
return `${jsxName}=
|
|
377
|
+
return `${jsxName}={${escape(value)}}`;
|
|
380
378
|
};
|
|
381
379
|
var attributesToString = (attributes) => attributes.map(([attName, value]) => ` ${toAttrString(attName, value)}`).join("");
|
|
382
380
|
var convertTagName = (tagName) => {
|
|
@@ -389,15 +387,14 @@ var convertTagName = (tagName) => {
|
|
|
389
387
|
}
|
|
390
388
|
return tag;
|
|
391
389
|
};
|
|
392
|
-
var escapeValue = (value) => value.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
393
390
|
var htmlToJsx = (html) => {
|
|
394
391
|
const parsedHtml = parseFragment(html, { scriptingEnabled: false });
|
|
395
392
|
let result = "";
|
|
396
393
|
for (const walkNode of walkChildNodes(parsedHtml)) {
|
|
397
394
|
switch (walkNode.type) {
|
|
398
395
|
case "text": {
|
|
399
|
-
const escapedValue =
|
|
400
|
-
result += escapedValue ? "{
|
|
396
|
+
const escapedValue = escape(walkNode.value);
|
|
397
|
+
result += escapedValue ? "{" + escapedValue + "}" : "";
|
|
401
398
|
break;
|
|
402
399
|
}
|
|
403
400
|
case "element-start": {
|
|
@@ -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,24 +622,34 @@ 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"))) {
|
|
638
|
+
await mergeJsonInto(
|
|
639
|
+
join6(templatePath, "package.json"),
|
|
640
|
+
join6(cwd3(), "package.json")
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
if (existsSync(join6(templatePath, "tsconfig.json"))) {
|
|
487
644
|
await mergeJsonInto(
|
|
488
|
-
|
|
489
|
-
|
|
645
|
+
join6(templatePath, "tsconfig.json"),
|
|
646
|
+
join6(cwd3(), "tsconfig.json")
|
|
490
647
|
);
|
|
491
648
|
}
|
|
492
649
|
};
|
|
650
|
+
var importFrom = (importee, importer) => {
|
|
651
|
+
return relative(dirname2(importer), importee).replaceAll("\\", "/");
|
|
652
|
+
};
|
|
493
653
|
var prebuild = async (options) => {
|
|
494
654
|
if (options.template.length === 0) {
|
|
495
655
|
log2.error(
|
|
@@ -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,18 +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();
|
|
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");
|
|
523
684
|
for (const template of options.template) {
|
|
524
|
-
if (template === "vanilla") {
|
|
685
|
+
if (template === "vanilla" || template === "ssg") {
|
|
525
686
|
continue;
|
|
526
687
|
}
|
|
527
688
|
await copyTemplates(template);
|
|
528
689
|
}
|
|
529
|
-
|
|
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);
|
|
530
697
|
const { assetBaseUrl } = constants2;
|
|
531
698
|
const siteData = await loadJSONFile(LOCAL_DATA_FILE);
|
|
532
699
|
if (siteData === null) {
|
|
@@ -538,27 +705,14 @@ Please check webstudio --help for more details`
|
|
|
538
705
|
if (domain === void 0) {
|
|
539
706
|
throw new Error(`Project domain is missing from the project data`);
|
|
540
707
|
}
|
|
541
|
-
const
|
|
542
|
-
|
|
543
|
-
)
|
|
544
|
-
(
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
new Set(Object.keys(radixComponentMetas))
|
|
550
|
-
);
|
|
551
|
-
return r;
|
|
552
|
-
},
|
|
553
|
-
{}
|
|
554
|
-
);
|
|
555
|
-
const metas = new Map(
|
|
556
|
-
Object.entries({
|
|
557
|
-
...baseComponentMetas,
|
|
558
|
-
...radixComponentNamespacedMetas,
|
|
559
|
-
...remixComponentMetas
|
|
560
|
-
})
|
|
561
|
-
);
|
|
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
|
+
}
|
|
562
716
|
const projectMetas = /* @__PURE__ */ new Map();
|
|
563
717
|
const componentsByPage = {};
|
|
564
718
|
const siteDataByPage = {};
|
|
@@ -576,7 +730,9 @@ Please check webstudio --help for more details`
|
|
|
576
730
|
props: siteData.build.props.map(([_id, prop]) => prop),
|
|
577
731
|
assetBaseUrl,
|
|
578
732
|
assets: new Map(siteData.assets.map((asset) => [asset.id, asset])),
|
|
579
|
-
|
|
733
|
+
uploadingImageAssets: [],
|
|
734
|
+
pages: siteData.build.pages,
|
|
735
|
+
source: "prebuild"
|
|
580
736
|
});
|
|
581
737
|
const props = [];
|
|
582
738
|
for (const prop of normalizedProps) {
|
|
@@ -676,7 +832,7 @@ Please check webstudio --help for more details`
|
|
|
676
832
|
}
|
|
677
833
|
}
|
|
678
834
|
const assets = new Map(siteData.assets.map((asset) => [asset.id, asset]));
|
|
679
|
-
const { cssText,
|
|
835
|
+
const { cssText, classes } = generateCss({
|
|
680
836
|
instances: new Map(siteData.build.instances),
|
|
681
837
|
props: new Map(siteData.build.props),
|
|
682
838
|
assets,
|
|
@@ -688,17 +844,7 @@ Please check webstudio --help for more details`
|
|
|
688
844
|
assetBaseUrl,
|
|
689
845
|
atomic: siteData.build.pages.compiler?.atomicStyles ?? true
|
|
690
846
|
});
|
|
691
|
-
await createFileIfNotExists(
|
|
692
|
-
const routeTemplatesDir = join4(cwd3(), "app/route-templates");
|
|
693
|
-
const routeTemplatePath = normalize(join4(routeTemplatesDir, "html.tsx"));
|
|
694
|
-
const routeXmlTemplatePath = normalize(join4(routeTemplatesDir, "xml.tsx"));
|
|
695
|
-
const defaultSiteMapXmlPath = normalize(
|
|
696
|
-
join4(routeTemplatesDir, "default-sitemap.tsx")
|
|
697
|
-
);
|
|
698
|
-
const routeFileTemplate = await readFile4(routeTemplatePath, "utf8");
|
|
699
|
-
const routeXmlFileTemplate = await readFile4(routeXmlTemplatePath, "utf8");
|
|
700
|
-
const defaultSiteMapTemplate = await readFile4(defaultSiteMapXmlPath, "utf8");
|
|
701
|
-
await rm(routeTemplatesDir, { recursive: true, force: true });
|
|
847
|
+
await createFileIfNotExists(join6(generatedDir, "index.css"), cssText);
|
|
702
848
|
for (const [pageId, pageComponents] of Object.entries(componentsByPage)) {
|
|
703
849
|
const scope = createScope([
|
|
704
850
|
// manually maintained list of occupied identifiers
|
|
@@ -709,18 +855,10 @@ Please check webstudio --help for more details`
|
|
|
709
855
|
"_props"
|
|
710
856
|
]);
|
|
711
857
|
const namespaces = /* @__PURE__ */ new Map();
|
|
712
|
-
const BASE_NAMESPACE = "@webstudio-is/sdk-components-react";
|
|
713
|
-
const REMIX_NAMESPACE = "@webstudio-is/sdk-components-react-remix";
|
|
714
858
|
for (const component of pageComponents) {
|
|
715
|
-
const
|
|
716
|
-
let [namespace] = parsed;
|
|
717
|
-
const [_namespace, shortName] = parsed;
|
|
859
|
+
const namespace = componentSources.get(component);
|
|
718
860
|
if (namespace === void 0) {
|
|
719
|
-
|
|
720
|
-
namespace = REMIX_NAMESPACE;
|
|
721
|
-
} else {
|
|
722
|
-
namespace = BASE_NAMESPACE;
|
|
723
|
-
}
|
|
861
|
+
continue;
|
|
724
862
|
}
|
|
725
863
|
if (namespaces.has(namespace) === false) {
|
|
726
864
|
namespaces.set(
|
|
@@ -728,6 +866,7 @@ Please check webstudio --help for more details`
|
|
|
728
866
|
/* @__PURE__ */ new Set()
|
|
729
867
|
);
|
|
730
868
|
}
|
|
869
|
+
const [_namespace, shortName] = parseComponentName(component);
|
|
731
870
|
namespaces.get(namespace)?.add([shortName, component]);
|
|
732
871
|
}
|
|
733
872
|
let componentImports = "";
|
|
@@ -768,6 +907,11 @@ Please check webstudio --help for more details`
|
|
|
768
907
|
const props = new Map(pageData.build.props);
|
|
769
908
|
const dataSources = new Map(pageData.build.dataSources);
|
|
770
909
|
const resources = new Map(pageData.build.resources);
|
|
910
|
+
replaceFormActionsWithResources({
|
|
911
|
+
instances,
|
|
912
|
+
resources,
|
|
913
|
+
props
|
|
914
|
+
});
|
|
771
915
|
const pageComponent = generateWebstudioComponent({
|
|
772
916
|
scope,
|
|
773
917
|
name: "Page",
|
|
@@ -784,7 +928,7 @@ Please check webstudio --help for more details`
|
|
|
784
928
|
instances,
|
|
785
929
|
props,
|
|
786
930
|
dataSources,
|
|
787
|
-
classesMap,
|
|
931
|
+
classesMap: classes,
|
|
788
932
|
indexesWithinAncestors: getIndexesWithinAncestors(
|
|
789
933
|
projectMetas,
|
|
790
934
|
instances,
|
|
@@ -796,12 +940,8 @@ Please check webstudio --help for more details`
|
|
|
796
940
|
// fallback to user email when contact email is empty string
|
|
797
941
|
projectMeta?.contactEmail || siteData.user?.email || void 0
|
|
798
942
|
);
|
|
799
|
-
const pageMeta = pageData.page.meta;
|
|
800
943
|
const favIconAsset = assets.get(projectMeta?.faviconAssetId ?? "");
|
|
801
|
-
const socialImageAsset = assets.get(pageMeta.socialImageAssetId ?? "");
|
|
802
944
|
const pagePath = getPagePath(pageData.page.id, siteData.build.pages);
|
|
803
|
-
const remixRoute = generateRemixRoute(pagePath);
|
|
804
|
-
const fileName = `${remixRoute}.tsx`;
|
|
805
945
|
const pageExports = `/* eslint-disable */
|
|
806
946
|
/* This is a auto generated file for building the project */
|
|
807
947
|
|
|
@@ -816,9 +956,6 @@ Please check webstudio --help for more details`
|
|
|
816
956
|
export const favIconAsset: ImageAsset | undefined =
|
|
817
957
|
${JSON.stringify(favIconAsset)};
|
|
818
958
|
|
|
819
|
-
export const socialImageAsset: ImageAsset | undefined =
|
|
820
|
-
${JSON.stringify(socialImageAsset)};
|
|
821
|
-
|
|
822
959
|
// Font assets on current page (can be preloaded)
|
|
823
960
|
export const pageFontAssets: FontAsset[] =
|
|
824
961
|
${JSON.stringify(pageFontAssets)}
|
|
@@ -826,7 +963,7 @@ Please check webstudio --help for more details`
|
|
|
826
963
|
export const pageBackgroundImageAssets: ImageAsset[] =
|
|
827
964
|
${JSON.stringify(pageBackgroundImageAssets)}
|
|
828
965
|
|
|
829
|
-
${
|
|
966
|
+
${pagePath === "/" ? `
|
|
830
967
|
${projectMeta?.code ? `
|
|
831
968
|
const Script = ({children, ...props}: Record<string, string | boolean>) => {
|
|
832
969
|
if (children == null) {
|
|
@@ -860,47 +997,59 @@ Please check webstudio --help for more details`
|
|
|
860
997
|
|
|
861
998
|
|
|
862
999
|
import type { PageMeta } from "@webstudio-is/sdk";
|
|
863
|
-
${
|
|
1000
|
+
${generateResources({
|
|
864
1001
|
scope,
|
|
865
1002
|
page: pageData.page,
|
|
866
1003
|
dataSources,
|
|
1004
|
+
props,
|
|
867
1005
|
resources
|
|
868
1006
|
})}
|
|
869
1007
|
|
|
870
1008
|
${generatePageMeta({
|
|
871
1009
|
globalScope: scope,
|
|
872
1010
|
page: pageData.page,
|
|
873
|
-
dataSources
|
|
1011
|
+
dataSources,
|
|
1012
|
+
assets
|
|
874
1013
|
})}
|
|
875
1014
|
|
|
876
|
-
${generateFormsProperties(props)}
|
|
877
|
-
|
|
878
1015
|
${generateRemixParams(pageData.page.path)}
|
|
879
1016
|
|
|
880
1017
|
export const projectId = "${siteData.build.projectId}";
|
|
881
1018
|
|
|
882
1019
|
export const contactEmail = ${JSON.stringify(contactEmail)};
|
|
883
1020
|
`;
|
|
884
|
-
const
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
)
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
)
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
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)
|
|
896
1048
|
);
|
|
1049
|
+
await createFileIfNotExists(file, content);
|
|
897
1050
|
}
|
|
898
1051
|
await createFileIfNotExists(
|
|
899
|
-
|
|
900
|
-
defaultSiteMapTemplate.replace(/".*\/__generated__\//, `"../__generated__/`)
|
|
901
|
-
);
|
|
902
|
-
await createFileIfNotExists(
|
|
903
|
-
join4(generatedDir, "$resources.sitemap.xml.ts"),
|
|
1052
|
+
join6(generatedDir, "$resources.sitemap.xml.ts"),
|
|
904
1053
|
`
|
|
905
1054
|
export const sitemap = ${JSON.stringify(
|
|
906
1055
|
getStaticSiteMapXml(siteData.build.pages, siteData.build.updatedAt),
|
|
@@ -912,15 +1061,23 @@ Please check webstudio --help for more details`
|
|
|
912
1061
|
const redirects = siteData.build.pages?.redirects;
|
|
913
1062
|
if (redirects !== void 0 && redirects.length > 0) {
|
|
914
1063
|
for (const redirect of redirects) {
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
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
|
+
}
|
|
924
1081
|
}
|
|
925
1082
|
}
|
|
926
1083
|
if (assetsToDownload.length > 0) {
|
|
@@ -945,9 +1102,9 @@ var buildOptions = (yargs) => yargs.option("assets", {
|
|
|
945
1102
|
type: "array",
|
|
946
1103
|
string: true,
|
|
947
1104
|
default: [],
|
|
948
|
-
describe: `Template to use for the build [choices: ${PROJECT_TEMPALTES.
|
|
949
|
-
|
|
950
|
-
)}]`
|
|
1105
|
+
describe: `Template to use for the build [choices: ${PROJECT_TEMPALTES.map(
|
|
1106
|
+
(item) => item.value
|
|
1107
|
+
).join(", ")}]`
|
|
951
1108
|
});
|
|
952
1109
|
var build = async (options) => {
|
|
953
1110
|
try {
|
|
@@ -966,7 +1123,7 @@ var build = async (options) => {
|
|
|
966
1123
|
|
|
967
1124
|
// src/commands/init-flow.ts
|
|
968
1125
|
import { chdir, cwd as cwd4 } from "node:process";
|
|
969
|
-
import { join as
|
|
1126
|
+
import { join as join7 } from "node:path";
|
|
970
1127
|
import pc2 from "picocolors";
|
|
971
1128
|
import {
|
|
972
1129
|
cancel as cancel2,
|
|
@@ -978,7 +1135,6 @@ import {
|
|
|
978
1135
|
text as text2
|
|
979
1136
|
} from "@clack/prompts";
|
|
980
1137
|
import { $ } from "execa";
|
|
981
|
-
import { titleCase } from "title-case";
|
|
982
1138
|
var exitIfCancelled = (value) => {
|
|
983
1139
|
if (isCancel2(value)) {
|
|
984
1140
|
cancel2("Project initialization is cancelled");
|
|
@@ -1009,8 +1165,8 @@ var initFlow = async (options) => {
|
|
|
1009
1165
|
}
|
|
1010
1166
|
})
|
|
1011
1167
|
);
|
|
1012
|
-
await createFolderIfNotExists(
|
|
1013
|
-
chdir(
|
|
1168
|
+
await createFolderIfNotExists(join7(cwd4(), folderName));
|
|
1169
|
+
chdir(join7(cwd4(), folderName));
|
|
1014
1170
|
}
|
|
1015
1171
|
const shareLink = exitIfCancelled(
|
|
1016
1172
|
await text2({
|
|
@@ -1022,10 +1178,7 @@ var initFlow = async (options) => {
|
|
|
1022
1178
|
projectTemplate = exitIfCancelled(
|
|
1023
1179
|
await select({
|
|
1024
1180
|
message: "Where would you like to deploy your project?",
|
|
1025
|
-
options: PROJECT_TEMPALTES
|
|
1026
|
-
value: template,
|
|
1027
|
-
label: titleCase(template)
|
|
1028
|
-
}))
|
|
1181
|
+
options: PROJECT_TEMPALTES
|
|
1029
1182
|
})
|
|
1030
1183
|
);
|
|
1031
1184
|
shouldInstallDeps = exitIfCancelled(
|
|
@@ -1039,10 +1192,7 @@ var initFlow = async (options) => {
|
|
|
1039
1192
|
projectTemplate = exitIfCancelled(
|
|
1040
1193
|
await select({
|
|
1041
1194
|
message: "Where would you like to deploy your project?",
|
|
1042
|
-
options: PROJECT_TEMPALTES
|
|
1043
|
-
value: template,
|
|
1044
|
-
label: titleCase(template)
|
|
1045
|
-
}))
|
|
1195
|
+
options: PROJECT_TEMPALTES
|
|
1046
1196
|
})
|
|
1047
1197
|
);
|
|
1048
1198
|
}
|
|
@@ -1092,7 +1242,7 @@ import makeCLI from "yargs";
|
|
|
1092
1242
|
// package.json
|
|
1093
1243
|
var package_default = {
|
|
1094
1244
|
name: "webstudio",
|
|
1095
|
-
version: "0.
|
|
1245
|
+
version: "0.173.0",
|
|
1096
1246
|
description: "Webstudio CLI",
|
|
1097
1247
|
author: "Webstudio <github@webstudio.is>",
|
|
1098
1248
|
homepage: "https://webstudio.is",
|
|
@@ -1101,6 +1251,12 @@ var package_default = {
|
|
|
1101
1251
|
"webstudio-cli": "./bin.js",
|
|
1102
1252
|
webstudio: "./bin.js"
|
|
1103
1253
|
},
|
|
1254
|
+
imports: {
|
|
1255
|
+
"#cli": {
|
|
1256
|
+
webstudio: "./src/cli.ts",
|
|
1257
|
+
default: "./lib/cli.js"
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1104
1260
|
files: [
|
|
1105
1261
|
"lib/*",
|
|
1106
1262
|
"templates/*",
|
|
@@ -1109,13 +1265,13 @@ var package_default = {
|
|
|
1109
1265
|
],
|
|
1110
1266
|
scripts: {
|
|
1111
1267
|
typecheck: "tsc",
|
|
1112
|
-
checks: "pnpm typecheck",
|
|
1113
1268
|
build: "rm -rf lib && esbuild src/cli.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
1114
|
-
"local-run": "tsx --no-warnings ./src/bin.ts",
|
|
1115
|
-
dev: "esbuild src/cli.ts --watch --bundle --format=esm --packages=external --outdir=./lib",
|
|
1116
1269
|
test: "NODE_OPTIONS=--experimental-vm-modules jest"
|
|
1117
1270
|
},
|
|
1118
1271
|
license: "AGPL-3.0-or-later",
|
|
1272
|
+
engines: {
|
|
1273
|
+
node: ">=20.12"
|
|
1274
|
+
},
|
|
1119
1275
|
dependencies: {
|
|
1120
1276
|
"@clack/prompts": "^0.7.0",
|
|
1121
1277
|
"@webstudio-is/http-client": "workspace:*",
|
|
@@ -1125,15 +1281,14 @@ var package_default = {
|
|
|
1125
1281
|
"@webstudio-is/sdk-components-react": "workspace:*",
|
|
1126
1282
|
"@webstudio-is/sdk-components-react-radix": "workspace:*",
|
|
1127
1283
|
"@webstudio-is/sdk-components-react-remix": "workspace:*",
|
|
1128
|
-
"change-case": "^5.
|
|
1284
|
+
"change-case": "^5.4.4",
|
|
1129
1285
|
deepmerge: "^4.3.1",
|
|
1130
1286
|
"env-paths": "^3.0.0",
|
|
1131
1287
|
execa: "^7.2.0",
|
|
1132
|
-
parse5: "7.1.2",
|
|
1133
1288
|
"p-limit": "^4.0.0",
|
|
1289
|
+
parse5: "7.1.2",
|
|
1134
1290
|
picocolors: "^1.0.1",
|
|
1135
1291
|
"strip-indent": "^4.0.0",
|
|
1136
|
-
"title-case": "^4.1.0",
|
|
1137
1292
|
yargs: "^17.7.2",
|
|
1138
1293
|
zod: "^3.22.4"
|
|
1139
1294
|
},
|
|
@@ -1141,24 +1296,26 @@ var package_default = {
|
|
|
1141
1296
|
"@jest/globals": "^29.7.0",
|
|
1142
1297
|
"@netlify/remix-adapter": "^2.4.0",
|
|
1143
1298
|
"@netlify/remix-edge-adapter": "3.3.0",
|
|
1144
|
-
"@remix-run/cloudflare": "^2.
|
|
1145
|
-
"@remix-run/cloudflare-pages": "^2.
|
|
1146
|
-
"@remix-run/dev": "^2.
|
|
1147
|
-
"@remix-run/node": "^2.
|
|
1148
|
-
"@remix-run/react": "^2.
|
|
1149
|
-
"@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",
|
|
1150
1305
|
"@types/node": "^20.12.7",
|
|
1151
1306
|
"@types/react": "^18.2.70",
|
|
1152
1307
|
"@types/react-dom": "^18.2.25",
|
|
1153
1308
|
"@types/yargs": "^17.0.32",
|
|
1309
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
1154
1310
|
"@webstudio-is/form-handlers": "workspace:*",
|
|
1155
1311
|
"@webstudio-is/jest-config": "workspace:*",
|
|
1156
1312
|
"@webstudio-is/tsconfig": "workspace:*",
|
|
1157
1313
|
react: "18.3.0-canary-14898b6a9-20240318",
|
|
1158
1314
|
"react-dom": "18.3.0-canary-14898b6a9-20240318",
|
|
1159
|
-
typescript: "5.
|
|
1160
|
-
|
|
1161
|
-
|
|
1315
|
+
typescript: "5.5.2",
|
|
1316
|
+
vike: "^0.4.180",
|
|
1317
|
+
vite: "^5.3.4",
|
|
1318
|
+
wrangler: "^3.63.2"
|
|
1162
1319
|
}
|
|
1163
1320
|
};
|
|
1164
1321
|
|