create-plasmic-app 0.0.167 → 0.0.169
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.internal.md +6 -4
- package/cpa-out/gatsby-codegen-js/package.json +3 -2
- package/cpa-out/gatsby-codegen-js/plasmic.json +5 -8
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicButton.jsx +12 -12
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicDynamicPage.jsx +18 -18
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicHomepage.jsx +12 -16
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicRandomDynamicPageButton.jsx +1 -0
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicStyleTokensProvider.jsx +2 -2
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/{plasmic.module.css → plasmic.css} +89 -73
- package/cpa-out/gatsby-codegen-js/src/components/plasmic/{plasmic__default_style.module.css → plasmic__default_style.css} +16 -0
- package/cpa-out/gatsby-codegen-ts/package.json +3 -2
- package/cpa-out/gatsby-codegen-ts/plasmic.json +5 -8
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicButton.tsx +12 -12
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicDynamicPage.tsx +18 -18
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicHomepage.tsx +12 -16
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicRandomDynamicPageButton.tsx +1 -1
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicStyleTokensProvider.tsx +2 -2
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/{plasmic.module.css → plasmic.css} +89 -73
- package/cpa-out/gatsby-codegen-ts/src/components/plasmic/{plasmic__default_style.module.css → plasmic__default_style.css} +16 -0
- package/cpa-out/gatsby-loader-js/package.json +1 -1
- package/cpa-out/gatsby-loader-ts/package.json +1 -1
- package/cpa-out/nextjs-app-codegen-js/app/dynamic/[slug]/page.jsx +5 -5
- package/cpa-out/nextjs-app-codegen-js/app/robots.js +24 -0
- package/cpa-out/nextjs-app-codegen-js/app/sitemap.js +38 -0
- package/cpa-out/nextjs-app-codegen-js/components/plasmic/create_plasmic_app/PlasmicDynamicPage.jsx +2 -2
- package/cpa-out/nextjs-app-codegen-js/components/plasmic/create_plasmic_app/PlasmicDynamicPageServer.jsx +2 -2
- package/cpa-out/nextjs-app-codegen-js/components/plasmic/create_plasmic_app/plasmic.css +16 -0
- package/cpa-out/nextjs-app-codegen-js/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/nextjs-app-codegen-js/package.json +7 -6
- package/cpa-out/nextjs-app-codegen-js/plasmic.json +3 -6
- package/cpa-out/nextjs-app-codegen-ts/app/dynamic/[slug]/page.tsx +8 -11
- package/cpa-out/nextjs-app-codegen-ts/app/page.tsx +4 -4
- package/cpa-out/nextjs-app-codegen-ts/app/robots.ts +25 -0
- package/cpa-out/nextjs-app-codegen-ts/app/sitemap.ts +41 -0
- package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/PlasmicDynamicPage.tsx +2 -2
- package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/PlasmicDynamicPageServer.tsx +7 -13
- package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/PlasmicHomepageServer.tsx +5 -11
- package/cpa-out/nextjs-app-codegen-ts/components/plasmic/create_plasmic_app/plasmic.css +16 -0
- package/cpa-out/nextjs-app-codegen-ts/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/nextjs-app-codegen-ts/package.json +7 -6
- package/cpa-out/nextjs-app-codegen-ts/plasmic.json +3 -6
- package/cpa-out/nextjs-app-loader-js/app/robots.js +24 -0
- package/cpa-out/nextjs-app-loader-js/app/sitemap.js +29 -0
- package/cpa-out/nextjs-app-loader-js/package.json +5 -5
- package/cpa-out/nextjs-app-loader-ts/app/layout.tsx +1 -5
- package/cpa-out/nextjs-app-loader-ts/app/robots.ts +25 -0
- package/cpa-out/nextjs-app-loader-ts/app/sitemap.ts +30 -0
- package/cpa-out/nextjs-app-loader-ts/package.json +5 -5
- package/cpa-out/nextjs-pages-codegen-js/components/plasmic/create_plasmic_app/PlasmicDynamicPage.jsx +2 -2
- package/cpa-out/nextjs-pages-codegen-js/components/plasmic/create_plasmic_app/plasmic.css +16 -0
- package/cpa-out/nextjs-pages-codegen-js/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/nextjs-pages-codegen-js/package.json +7 -6
- package/cpa-out/nextjs-pages-codegen-js/pages/robots.txt.js +25 -0
- package/cpa-out/nextjs-pages-codegen-js/pages/sitemap.xml.js +53 -0
- package/cpa-out/nextjs-pages-codegen-js/plasmic.json +3 -6
- package/cpa-out/nextjs-pages-codegen-js/styles/Home.module.css +8 -0
- package/cpa-out/nextjs-pages-codegen-ts/components/plasmic/create_plasmic_app/PlasmicDynamicPage.tsx +2 -2
- package/cpa-out/nextjs-pages-codegen-ts/components/plasmic/create_plasmic_app/plasmic.css +16 -0
- package/cpa-out/nextjs-pages-codegen-ts/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/nextjs-pages-codegen-ts/package.json +7 -6
- package/cpa-out/nextjs-pages-codegen-ts/pages/robots.txt.ts +27 -0
- package/cpa-out/nextjs-pages-codegen-ts/pages/sitemap.xml.ts +56 -0
- package/cpa-out/nextjs-pages-codegen-ts/plasmic.json +3 -6
- package/cpa-out/nextjs-pages-codegen-ts/styles/Home.module.css +8 -0
- package/cpa-out/nextjs-pages-loader-js/package.json +5 -5
- package/cpa-out/nextjs-pages-loader-js/pages/robots.txt.js +25 -0
- package/cpa-out/nextjs-pages-loader-js/pages/sitemap.xml.js +46 -0
- package/cpa-out/nextjs-pages-loader-js/styles/Home.module.css +8 -0
- package/cpa-out/nextjs-pages-loader-ts/package.json +5 -5
- package/cpa-out/nextjs-pages-loader-ts/pages/robots.txt.ts +27 -0
- package/cpa-out/nextjs-pages-loader-ts/pages/sitemap.xml.ts +47 -0
- package/cpa-out/nextjs-pages-loader-ts/styles/Home.module.css +8 -0
- package/cpa-out/react-codegen-js/package.json +3 -2
- package/cpa-out/react-codegen-js/plasmic.json +3 -6
- package/cpa-out/react-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicDynamicPage.jsx +2 -2
- package/cpa-out/react-codegen-js/src/components/plasmic/create_plasmic_app/plasmic.css +16 -0
- package/cpa-out/react-codegen-js/src/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/react-codegen-ts/package.json +3 -2
- package/cpa-out/react-codegen-ts/plasmic.json +3 -6
- package/cpa-out/react-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicDynamicPage.tsx +2 -2
- package/cpa-out/react-codegen-ts/src/components/plasmic/create_plasmic_app/plasmic.css +16 -0
- package/cpa-out/react-codegen-ts/src/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/tanstack-codegen-ts/package.json +8 -13
- package/cpa-out/tanstack-codegen-ts/plasmic.json +3 -6
- package/cpa-out/tanstack-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicDynamicPage.tsx +3 -3
- package/cpa-out/tanstack-codegen-ts/src/components/plasmic/plasmic__default_style.css +16 -0
- package/cpa-out/tanstack-codegen-ts/src/routeTree.gen.ts +13 -13
- package/cpa-out/tanstack-codegen-ts/src/routes/dynamic/$slug/index.tsx +2 -2
- package/dist/gatsby/gatsby.js +23 -17
- package/dist/index.js +6 -0
- package/dist/lib.d.ts +2 -1
- package/dist/lib.js +9 -4
- package/dist/nextjs/nextjs.js +30 -6
- package/dist/nextjs/templates/app-seo.d.ts +4 -0
- package/dist/nextjs/templates/app-seo.js +92 -0
- package/dist/nextjs/templates/pages-seo.d.ts +4 -0
- package/dist/nextjs/templates/pages-seo.js +121 -0
- package/dist/react/react.js +9 -4
- package/dist/tanstack/tanstack.js +12 -5
- package/dist/utils/codegen.d.ts +3 -0
- package/dist/utils/codegen.js +17 -4
- package/dist/utils/file-utils.d.ts +2 -2
- package/dist/utils/file-utils.js +2 -1
- package/dist/utils/npm-utils.d.ts +24 -9
- package/dist/utils/npm-utils.js +66 -21
- package/dist/utils/strategy.d.ts +5 -1
- package/dist/utils/types.d.ts +1 -0
- package/package.json +2 -4
- package/run-cpa.ts +17 -6
- package/src/gatsby/gatsby.ts +40 -22
- package/src/index.ts +9 -0
- package/src/lib.ts +18 -6
- package/src/nextjs/nextjs.ts +85 -7
- package/src/nextjs/templates/app-seo.ts +104 -0
- package/src/nextjs/templates/pages-seo.ts +131 -0
- package/src/react/react.ts +11 -4
- package/src/tanstack/tanstack.ts +19 -6
- package/src/utils/codegen.ts +28 -6
- package/src/utils/file-utils.ts +6 -2
- package/src/utils/npm-utils.ts +76 -23
- package/src/utils/strategy.ts +10 -1
- package/src/utils/types.ts +1 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ifTs } from "../../utils/file-utils";
|
|
2
|
+
import { JsOrTs } from "../../utils/types";
|
|
3
|
+
|
|
4
|
+
const getSiteUrl = `// Set NEXT_PUBLIC_SITE_URL to pin the origin and keep this route static;
|
|
5
|
+
// otherwise it is derived per-request, which opts the route out of prerendering.
|
|
6
|
+
async function getSiteUrl() {
|
|
7
|
+
if (process.env.NEXT_PUBLIC_SITE_URL) {
|
|
8
|
+
return process.env.NEXT_PUBLIC_SITE_URL;
|
|
9
|
+
}
|
|
10
|
+
if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {
|
|
11
|
+
return \`https://\${process.env.VERCEL_PROJECT_PRODUCTION_URL}\`;
|
|
12
|
+
}
|
|
13
|
+
const h = await headers();
|
|
14
|
+
const proto = h.get("x-forwarded-proto") ?? "http";
|
|
15
|
+
return \`\${proto}://\${h.get("x-forwarded-host") ?? h.get("host")}\`;
|
|
16
|
+
}`;
|
|
17
|
+
|
|
18
|
+
function makeHeader(jsOrTs: JsOrTs) {
|
|
19
|
+
return `${ifTs(
|
|
20
|
+
jsOrTs,
|
|
21
|
+
`import type { MetadataRoute } from "next";\n`
|
|
22
|
+
)}import { headers } from "next/headers";\n`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function makeSignature(jsOrTs: JsOrTs) {
|
|
26
|
+
return `export default async function sitemap()${ifTs(
|
|
27
|
+
jsOrTs,
|
|
28
|
+
": Promise<MetadataRoute.Sitemap>"
|
|
29
|
+
)} {`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function makeSitemap_app_loader(jsOrTs: JsOrTs): string {
|
|
33
|
+
return `import { PLASMIC } from "@/plasmic-init";
|
|
34
|
+
${makeHeader(jsOrTs)}
|
|
35
|
+
export const revalidate = 60;
|
|
36
|
+
|
|
37
|
+
${getSiteUrl}
|
|
38
|
+
|
|
39
|
+
${makeSignature(jsOrTs)}
|
|
40
|
+
const siteUrl = await getSiteUrl();
|
|
41
|
+
|
|
42
|
+
// fetchPages() drops pages whose path takes a param, e.g. "/blog/[slug]".
|
|
43
|
+
const pages = await PLASMIC.fetchPages();
|
|
44
|
+
|
|
45
|
+
return pages.map((page) => ({
|
|
46
|
+
url: new URL(page.path, siteUrl).toString(),
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function makeSitemap_app_codegen(jsOrTs: JsOrTs): string {
|
|
53
|
+
const projects =
|
|
54
|
+
jsOrTs === "ts"
|
|
55
|
+
? `(plasmicJson.projects as {
|
|
56
|
+
components: { componentType: string; path?: string }[];
|
|
57
|
+
}[])`
|
|
58
|
+
: "plasmicJson.projects";
|
|
59
|
+
|
|
60
|
+
return `${makeHeader(jsOrTs)}import plasmicJson from "../plasmic.json";
|
|
61
|
+
|
|
62
|
+
${getSiteUrl}
|
|
63
|
+
|
|
64
|
+
${makeSignature(jsOrTs)}
|
|
65
|
+
const siteUrl = await getSiteUrl();
|
|
66
|
+
|
|
67
|
+
return ${projects}
|
|
68
|
+
.flatMap((project) => project.components)
|
|
69
|
+
.flatMap((component) =>
|
|
70
|
+
component.componentType === "page" &&
|
|
71
|
+
component.path &&
|
|
72
|
+
!component.path.includes("[")
|
|
73
|
+
? [
|
|
74
|
+
{
|
|
75
|
+
// next.config sets trailingSlash.
|
|
76
|
+
url: new URL(
|
|
77
|
+
component.path.replace(/\\/?$/, "/"),
|
|
78
|
+
siteUrl
|
|
79
|
+
).toString(),
|
|
80
|
+
},
|
|
81
|
+
]
|
|
82
|
+
: []
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function makeRobots_app(jsOrTs: JsOrTs): string {
|
|
89
|
+
return `${makeHeader(jsOrTs)}
|
|
90
|
+
${getSiteUrl}
|
|
91
|
+
|
|
92
|
+
export default async function robots()${ifTs(
|
|
93
|
+
jsOrTs,
|
|
94
|
+
": Promise<MetadataRoute.Robots>"
|
|
95
|
+
)} {
|
|
96
|
+
const siteUrl = await getSiteUrl();
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
rules: { userAgent: "*", allow: "/" },
|
|
100
|
+
sitemap: new URL("/sitemap.xml", siteUrl).toString(),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { ifTs } from "../../utils/file-utils";
|
|
2
|
+
import { JsOrTs } from "../../utils/types";
|
|
3
|
+
|
|
4
|
+
const siteUrl = ` // Set NEXT_PUBLIC_SITE_URL to pin the origin;
|
|
5
|
+
// otherwise it is derived per-request from the request headers.
|
|
6
|
+
const siteUrl =
|
|
7
|
+
process.env.NEXT_PUBLIC_SITE_URL ??
|
|
8
|
+
(process.env.VERCEL_PROJECT_PRODUCTION_URL
|
|
9
|
+
? \`https://\${process.env.VERCEL_PROJECT_PRODUCTION_URL}\`
|
|
10
|
+
: \`\${req.headers["x-forwarded-proto"] ?? "http"}://\${
|
|
11
|
+
req.headers["x-forwarded-host"] ?? req.headers.host
|
|
12
|
+
}\`);`;
|
|
13
|
+
|
|
14
|
+
function makeHeader(jsOrTs: JsOrTs) {
|
|
15
|
+
return ifTs(jsOrTs, `import type { GetServerSideProps } from "next";\n`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function makeSignature(jsOrTs: JsOrTs) {
|
|
19
|
+
return `export const getServerSideProps${ifTs(
|
|
20
|
+
jsOrTs,
|
|
21
|
+
": GetServerSideProps"
|
|
22
|
+
)} = async ({ req, res }) => {`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function makeSitemapXml(jsOrTs: JsOrTs) {
|
|
26
|
+
return `function escapeXml(str${ifTs(jsOrTs, ": string")}) {
|
|
27
|
+
return str
|
|
28
|
+
.replace(/&/g, "&")
|
|
29
|
+
.replace(/</g, "<")
|
|
30
|
+
.replace(/>/g, ">")
|
|
31
|
+
.replace(/"/g, """)
|
|
32
|
+
.replace(/'/g, "'");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function makeSitemapXml(urls${ifTs(jsOrTs, ": string[]")}) {
|
|
36
|
+
const entries = urls.map(
|
|
37
|
+
(url) => \` <url><loc>\${escapeXml(url)}</loc></url>\`
|
|
38
|
+
);
|
|
39
|
+
return \`<?xml version="1.0" encoding="UTF-8"?>
|
|
40
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
41
|
+
\${entries.join("\\n")}
|
|
42
|
+
</urlset>
|
|
43
|
+
\`;
|
|
44
|
+
}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function makeSitemap_pages_loader(jsOrTs: JsOrTs): string {
|
|
48
|
+
return `import { PLASMIC } from "@/plasmic-init";
|
|
49
|
+
${makeHeader(jsOrTs)}
|
|
50
|
+
${makeSitemapXml(jsOrTs)}
|
|
51
|
+
|
|
52
|
+
${makeSignature(jsOrTs)}
|
|
53
|
+
${siteUrl}
|
|
54
|
+
|
|
55
|
+
// fetchPages() drops pages whose path takes a param, e.g. "/blog/[slug]".
|
|
56
|
+
const pages = await PLASMIC.fetchPages();
|
|
57
|
+
const urls = pages.map((page) => new URL(page.path, siteUrl).toString());
|
|
58
|
+
|
|
59
|
+
res.setHeader("Content-Type", "application/xml; charset=utf-8");
|
|
60
|
+
res.write(makeSitemapXml(urls));
|
|
61
|
+
res.end();
|
|
62
|
+
return { props: {} };
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default function Sitemap() {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function makeSitemap_pages_codegen(jsOrTs: JsOrTs): string {
|
|
72
|
+
const projects =
|
|
73
|
+
jsOrTs === "ts"
|
|
74
|
+
? `(plasmicJson.projects as {
|
|
75
|
+
components: { componentType: string; path?: string }[];
|
|
76
|
+
}[])`
|
|
77
|
+
: "plasmicJson.projects";
|
|
78
|
+
|
|
79
|
+
return `${makeHeader(jsOrTs)}import plasmicJson from "../plasmic.json";
|
|
80
|
+
|
|
81
|
+
${makeSitemapXml(jsOrTs)}
|
|
82
|
+
|
|
83
|
+
${makeSignature(jsOrTs)}
|
|
84
|
+
${siteUrl}
|
|
85
|
+
|
|
86
|
+
const urls = ${projects}
|
|
87
|
+
.flatMap((project) => project.components)
|
|
88
|
+
.flatMap((component) =>
|
|
89
|
+
component.componentType === "page" &&
|
|
90
|
+
component.path &&
|
|
91
|
+
!component.path.includes("[")
|
|
92
|
+
? // next.config sets trailingSlash.
|
|
93
|
+
[new URL(component.path.replace(/\\/?$/, "/"), siteUrl).toString()]
|
|
94
|
+
: []
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
res.setHeader("Content-Type", "application/xml; charset=utf-8");
|
|
98
|
+
res.write(makeSitemapXml(urls));
|
|
99
|
+
res.end();
|
|
100
|
+
return { props: {} };
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export default function Sitemap() {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function makeRobots_pages(jsOrTs: JsOrTs): string {
|
|
110
|
+
return `${ifTs(
|
|
111
|
+
jsOrTs,
|
|
112
|
+
`import type { GetServerSideProps } from "next";\n\n`
|
|
113
|
+
)}${makeSignature(jsOrTs)}
|
|
114
|
+
${siteUrl}
|
|
115
|
+
|
|
116
|
+
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
117
|
+
res.write(
|
|
118
|
+
\`User-agent: *\\nAllow: /\\n\\nSitemap: \${new URL(
|
|
119
|
+
"/sitemap.xml",
|
|
120
|
+
siteUrl
|
|
121
|
+
).toString()}\\n\`
|
|
122
|
+
);
|
|
123
|
+
res.end();
|
|
124
|
+
return { props: {} };
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export default function Robots() {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
`;
|
|
131
|
+
}
|
package/src/react/react.ts
CHANGED
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
generateWelcomePage,
|
|
10
10
|
getPlasmicConfig,
|
|
11
11
|
} from "../utils/file-utils";
|
|
12
|
-
import { installUpgrade } from "../utils/npm-utils";
|
|
12
|
+
import { initYarnBerryProject, installUpgrade } from "../utils/npm-utils";
|
|
13
13
|
import { CPAStrategy } from "../utils/strategy";
|
|
14
14
|
|
|
15
15
|
export const reactStrategy: CPAStrategy = {
|
|
16
16
|
create: async (args) => {
|
|
17
|
-
const { projectPath, jsOrTs } = args;
|
|
17
|
+
const { projectPath, jsOrTs, packageManager } = args;
|
|
18
18
|
let { template } = args;
|
|
19
19
|
|
|
20
20
|
/* create-vite package checks if the targetDir doesn't exist then it creates the targetDir in the
|
|
@@ -45,14 +45,19 @@ export const reactStrategy: CPAStrategy = {
|
|
|
45
45
|
|
|
46
46
|
const templateArg = template ? ` --template ${template}` : "";
|
|
47
47
|
await spawnOrFail(`${createCommand}${templateArg}`);
|
|
48
|
+
|
|
49
|
+
if (packageManager === "yarn2") {
|
|
50
|
+
await initYarnBerryProject(fullProjectPath);
|
|
51
|
+
}
|
|
48
52
|
},
|
|
49
|
-
installDeps: async ({ projectPath, scheme }) => {
|
|
53
|
+
installDeps: async ({ projectPath, scheme, packageManager }) => {
|
|
50
54
|
if (scheme === "loader") {
|
|
51
55
|
return await installUpgrade("@plasmicapp/loader-react", {
|
|
52
56
|
workingDir: projectPath,
|
|
57
|
+
packageManager,
|
|
53
58
|
});
|
|
54
59
|
} else {
|
|
55
|
-
return await installCodegenDeps({ projectPath });
|
|
60
|
+
return await installCodegenDeps({ projectPath, packageManager });
|
|
56
61
|
}
|
|
57
62
|
},
|
|
58
63
|
overwriteConfig: async (args) => {
|
|
@@ -81,6 +86,7 @@ export const reactStrategy: CPAStrategy = {
|
|
|
81
86
|
projectId,
|
|
82
87
|
projectPath,
|
|
83
88
|
jsOrTs,
|
|
89
|
+
packageManager,
|
|
84
90
|
}) => {
|
|
85
91
|
if (scheme === "loader") {
|
|
86
92
|
// Nothing to do
|
|
@@ -92,6 +98,7 @@ export const reactStrategy: CPAStrategy = {
|
|
|
92
98
|
projectId,
|
|
93
99
|
projectApiToken,
|
|
94
100
|
projectPath,
|
|
101
|
+
packageManager,
|
|
95
102
|
});
|
|
96
103
|
|
|
97
104
|
// Pick a page for the entry point App.tsx page
|
package/src/tanstack/tanstack.ts
CHANGED
|
@@ -3,14 +3,18 @@ import path from "path";
|
|
|
3
3
|
import { spawnOrFail } from "../utils/cmd-utils";
|
|
4
4
|
import { installCodegenDeps, runCodegenSync } from "../utils/codegen";
|
|
5
5
|
import { deleteGlob } from "../utils/file-utils";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
initYarnBerryProject,
|
|
8
|
+
installUpgrade,
|
|
9
|
+
packageManagerCommand,
|
|
10
|
+
} from "../utils/npm-utils";
|
|
7
11
|
import { CPAStrategy, GenerateFilesArgs } from "../utils/strategy";
|
|
8
12
|
import { makePlasmicHostPage_fileRouter_codegen } from "./templates/file-router/plasmic-host";
|
|
9
13
|
import { makeCustomRoot_file_router_codegen } from "./templates/file-router/root";
|
|
10
14
|
|
|
11
15
|
export const tanstackStrategy: CPAStrategy = {
|
|
12
16
|
create: async (args) => {
|
|
13
|
-
const { projectPath, template } = args;
|
|
17
|
+
const { projectPath, template, packageManager } = args;
|
|
14
18
|
if (template) {
|
|
15
19
|
console.warn(
|
|
16
20
|
`Warning: Ignoring template '${template}' (argument is not supported by TanStack).`
|
|
@@ -39,27 +43,34 @@ export const tanstackStrategy: CPAStrategy = {
|
|
|
39
43
|
"--framework React",
|
|
40
44
|
"--router-only",
|
|
41
45
|
"--no-toolchain",
|
|
42
|
-
|
|
46
|
+
`--package-manager ${packageManagerCommand(packageManager)}`,
|
|
43
47
|
"--git",
|
|
44
48
|
"--no-intent",
|
|
45
49
|
"--no-examples",
|
|
46
50
|
"--yes",
|
|
51
|
+
// Berry must install into the project we set up below, not the default PnP one
|
|
52
|
+
...(packageManager === "yarn2" ? ["--no-install"] : []),
|
|
47
53
|
].join(" ");
|
|
48
54
|
|
|
49
55
|
await spawnOrFail(createCommand);
|
|
50
56
|
|
|
57
|
+
if (packageManager === "yarn2") {
|
|
58
|
+
await initYarnBerryProject(fullProjectPath);
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
// Install peer-dep of @tanstack/react-router-with-query
|
|
52
62
|
await installUpgrade("@tanstack/react-query", {
|
|
53
63
|
workingDir: projectPath,
|
|
64
|
+
packageManager,
|
|
54
65
|
});
|
|
55
66
|
},
|
|
56
|
-
installDeps: async ({ scheme, projectPath }) => {
|
|
67
|
+
installDeps: async ({ scheme, projectPath, packageManager }) => {
|
|
57
68
|
if (scheme === "loader") {
|
|
58
69
|
throw new Error(
|
|
59
70
|
"Plasmic loader scheme is not supported for TanStack platform. Please use the codegen scheme instead."
|
|
60
71
|
);
|
|
61
72
|
} else {
|
|
62
|
-
return await installCodegenDeps({ projectPath });
|
|
73
|
+
return await installCodegenDeps({ projectPath, packageManager });
|
|
63
74
|
}
|
|
64
75
|
},
|
|
65
76
|
overwriteConfig: async (args) => {
|
|
@@ -106,7 +117,8 @@ export const tanstackStrategy: CPAStrategy = {
|
|
|
106
117
|
};
|
|
107
118
|
|
|
108
119
|
async function generateFilesFileRouterTemplate(args: GenerateFilesArgs) {
|
|
109
|
-
const { projectPath, scheme, projectId, projectApiToken } =
|
|
120
|
+
const { projectPath, scheme, projectId, projectApiToken, packageManager } =
|
|
121
|
+
args;
|
|
110
122
|
|
|
111
123
|
// Delete existing pages
|
|
112
124
|
deleteGlob(path.join(projectPath, "src/routes", "*.*"));
|
|
@@ -136,6 +148,7 @@ async function generateFilesFileRouterTemplate(args: GenerateFilesArgs) {
|
|
|
136
148
|
projectId,
|
|
137
149
|
projectApiToken,
|
|
138
150
|
projectPath,
|
|
151
|
+
packageManager,
|
|
139
152
|
});
|
|
140
153
|
}
|
|
141
154
|
}
|
package/src/utils/codegen.ts
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import path from "path";
|
|
1
3
|
import { banner } from "../lib";
|
|
2
4
|
import { spawnOrFail } from "../utils/cmd-utils";
|
|
3
|
-
import { installUpgrade } from "../utils/npm-utils";
|
|
5
|
+
import { installUpgrade, packageManagerExec } from "../utils/npm-utils";
|
|
6
|
+
import { PackageManagerType } from "../utils/types";
|
|
4
7
|
|
|
5
|
-
export async function installCodegenDeps(opts: {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
export async function installCodegenDeps(opts: {
|
|
9
|
+
projectPath: string;
|
|
10
|
+
packageManager: PackageManagerType;
|
|
11
|
+
}) {
|
|
12
|
+
const { projectPath, packageManager } = opts;
|
|
13
|
+
// Generated pages import @plasmicapp/host directly
|
|
14
|
+
return await installUpgrade("@plasmicapp/cli @plasmicapp/host", {
|
|
15
|
+
workingDir: projectPath,
|
|
16
|
+
packageManager,
|
|
17
|
+
});
|
|
8
18
|
}
|
|
9
19
|
|
|
10
20
|
export async function runCodegenSync(opts: {
|
|
11
21
|
projectId: string;
|
|
12
22
|
projectApiToken: string | undefined;
|
|
13
23
|
projectPath: string;
|
|
24
|
+
packageManager: PackageManagerType;
|
|
14
25
|
}) {
|
|
15
|
-
const { projectId, projectApiToken, projectPath } = opts;
|
|
26
|
+
const { projectId, projectApiToken, projectPath, packageManager } = opts;
|
|
16
27
|
|
|
17
28
|
banner("SYNCING PLASMIC COMPONENTS");
|
|
18
29
|
|
|
@@ -20,5 +31,16 @@ export async function runCodegenSync(opts: {
|
|
|
20
31
|
? `${projectId}:${projectApiToken}`
|
|
21
32
|
: projectId;
|
|
22
33
|
|
|
23
|
-
await spawnOrFail(
|
|
34
|
+
await spawnOrFail(
|
|
35
|
+
`${packageManagerExec(packageManager)} plasmic sync --yes -p ${project}`,
|
|
36
|
+
projectPath
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Pin the package manager, so syncs don't have to guess from lockfiles
|
|
40
|
+
const configPath = path.join(projectPath, "plasmic.json");
|
|
41
|
+
const config = JSON.parse(await fs.readFile(configPath, "utf8"));
|
|
42
|
+
await fs.writeFile(
|
|
43
|
+
configPath,
|
|
44
|
+
JSON.stringify({ ...config, packageManager }, undefined, 2) + "\n"
|
|
45
|
+
);
|
|
24
46
|
}
|
package/src/utils/file-utils.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { README } from "../templates/readme";
|
|
|
10
10
|
import { WELCOME_PAGE } from "../templates/welcomePage";
|
|
11
11
|
import { ensure } from "./lang-utils";
|
|
12
12
|
import { installUpgrade } from "./npm-utils";
|
|
13
|
-
import { JsOrTs, PlatformType } from "./types";
|
|
13
|
+
import { JsOrTs, PackageManagerType, PlatformType } from "./types";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Runs the search pattern through `glob` and deletes all resulting files
|
|
@@ -215,12 +215,16 @@ export async function getPlasmicConfig(
|
|
|
215
215
|
|
|
216
216
|
// Create tsconfig.json if it doesn't exist
|
|
217
217
|
// this will force Plasmic to recognize Typescript
|
|
218
|
-
export async function ensureTsconfig(
|
|
218
|
+
export async function ensureTsconfig(
|
|
219
|
+
projectPath: string,
|
|
220
|
+
packageManager: PackageManagerType
|
|
221
|
+
): Promise<void> {
|
|
219
222
|
const tsconfigPath = path.join(projectPath, "tsconfig.json");
|
|
220
223
|
if (!existsSync(tsconfigPath)) {
|
|
221
224
|
await fs.writeFile(tsconfigPath, "");
|
|
222
225
|
const installTsResult = await installUpgrade("typescript @types/react", {
|
|
223
226
|
workingDir: projectPath,
|
|
227
|
+
packageManager,
|
|
224
228
|
});
|
|
225
229
|
if (!installTsResult) {
|
|
226
230
|
throw new Error("Failed to install Typescript");
|
package/src/utils/npm-utils.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
@typescript-eslint/no-var-requires: 0,
|
|
3
3
|
*/
|
|
4
4
|
import * as execa from "execa";
|
|
5
|
-
import {
|
|
5
|
+
import { promises as fs } from "fs";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import * as semver from "semver";
|
|
8
8
|
import updateNotifier from "update-notifier";
|
|
9
|
+
import { PackageManagerType } from "./types";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Call this to check if there's an update available
|
|
@@ -54,6 +55,13 @@ export async function spawn(
|
|
|
54
55
|
return cp.exitCode === 0;
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
interface InstallOpts {
|
|
59
|
+
global?: boolean;
|
|
60
|
+
dev?: boolean;
|
|
61
|
+
workingDir?: string;
|
|
62
|
+
packageManager: PackageManagerType;
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
/**
|
|
58
66
|
* Install a package using either `npm` or `yarn`
|
|
59
67
|
* @param pkg - package name
|
|
@@ -62,7 +70,7 @@ export async function spawn(
|
|
|
62
70
|
*/
|
|
63
71
|
export async function installUpgrade(
|
|
64
72
|
pkg: string,
|
|
65
|
-
opts:
|
|
73
|
+
opts: InstallOpts
|
|
66
74
|
): Promise<boolean> {
|
|
67
75
|
const cmd = installCommand(pkg, opts);
|
|
68
76
|
const r = await spawn(cmd, opts.workingDir);
|
|
@@ -83,11 +91,8 @@ export async function installUpgrade(
|
|
|
83
91
|
* @param opts
|
|
84
92
|
* @returns
|
|
85
93
|
*/
|
|
86
|
-
function installCommand(
|
|
87
|
-
|
|
88
|
-
opts: { global?: boolean; dev?: boolean; workingDir?: string } = {}
|
|
89
|
-
): string {
|
|
90
|
-
const mgr = detectPackageManager(opts.workingDir);
|
|
94
|
+
function installCommand(pkg: string, opts: InstallOpts): string {
|
|
95
|
+
const mgr = opts.packageManager;
|
|
91
96
|
if (mgr === "yarn") {
|
|
92
97
|
if (opts.global) {
|
|
93
98
|
return `yarn global add ${pkg}`;
|
|
@@ -96,6 +101,14 @@ function installCommand(
|
|
|
96
101
|
} else {
|
|
97
102
|
return `yarn add --ignore-scripts -W ${pkg}`;
|
|
98
103
|
}
|
|
104
|
+
} else if (mgr === "yarn2") {
|
|
105
|
+
if (opts.global) {
|
|
106
|
+
return `npm install -g ${pkg}`;
|
|
107
|
+
} else if (opts.dev) {
|
|
108
|
+
return `yarn add -D ${pkg}`;
|
|
109
|
+
} else {
|
|
110
|
+
return `yarn add ${pkg}`;
|
|
111
|
+
}
|
|
99
112
|
} else if (mgr === "pnpm") {
|
|
100
113
|
if (opts.global) {
|
|
101
114
|
return `pnpm add -g ${pkg}`;
|
|
@@ -116,23 +129,63 @@ function installCommand(
|
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
132
|
+
* The package manager to install with: the one requested, else the one we were run
|
|
133
|
+
* with. `npx` overwrites npm_config_user_agent, so this must be read before spawning
|
|
134
|
+
* nested create commands.
|
|
122
135
|
*/
|
|
123
|
-
export function
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
export function resolvePackageManager(
|
|
137
|
+
requested?: PackageManagerType
|
|
138
|
+
): PackageManagerType {
|
|
139
|
+
if (requested) {
|
|
140
|
+
return requested === "yarn"
|
|
141
|
+
? yarnVariant(installedYarnVersion())
|
|
142
|
+
: requested;
|
|
143
|
+
}
|
|
144
|
+
const [name, version] = (process.env.npm_config_user_agent ?? "")
|
|
145
|
+
.split(" ")[0]
|
|
146
|
+
.split("/");
|
|
147
|
+
if (name === "yarn") {
|
|
148
|
+
return yarnVariant(version);
|
|
149
|
+
}
|
|
150
|
+
return name === "pnpm" ? "pnpm" : "npm";
|
|
151
|
+
}
|
|
128
152
|
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return "
|
|
153
|
+
function yarnVariant(version: string | undefined): PackageManagerType {
|
|
154
|
+
const parsed = version ? semver.coerce(version) : null;
|
|
155
|
+
return parsed && parsed.major >= 2 ? "yarn2" : "yarn";
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function installedYarnVersion(): string | undefined {
|
|
159
|
+
try {
|
|
160
|
+
return execa.commandSync("yarn --version").stdout.trim();
|
|
161
|
+
} catch {
|
|
162
|
+
return undefined;
|
|
137
163
|
}
|
|
138
164
|
}
|
|
165
|
+
|
|
166
|
+
/** Scaffolders and run scripts only know the `yarn` command. */
|
|
167
|
+
export function packageManagerCommand(
|
|
168
|
+
mgr: PackageManagerType
|
|
169
|
+
): "npm" | "yarn" | "pnpm" {
|
|
170
|
+
return mgr === "yarn2" ? "yarn" : mgr;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Run a locally installed bin. `npx` can't see Yarn Berry's PnP installs. */
|
|
174
|
+
export function packageManagerExec(mgr: PackageManagerType): string {
|
|
175
|
+
const cmd = packageManagerCommand(mgr);
|
|
176
|
+
return cmd === "yarn" ? "yarn" : cmd === "pnpm" ? "pnpm exec" : "npx";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Make a freshly scaffolded app its own Yarn Berry project. Without a lockfile Berry
|
|
181
|
+
* claims the app for the nearest ancestor project, and its default PnP linker can't
|
|
182
|
+
* load CommonJS from Node 24's ESM resolver (EBADF), which breaks every framework we
|
|
183
|
+
* scaffold. Must run before anything invokes yarn in `projectPath`.
|
|
184
|
+
*/
|
|
185
|
+
export async function initYarnBerryProject(projectPath: string): Promise<void> {
|
|
186
|
+
await fs.writeFile(path.join(projectPath, "yarn.lock"), "");
|
|
187
|
+
await fs.writeFile(
|
|
188
|
+
path.join(projectPath, ".yarnrc.yml"),
|
|
189
|
+
"nodeLinker: node-modules\n"
|
|
190
|
+
);
|
|
191
|
+
}
|
package/src/utils/strategy.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
JsOrTs,
|
|
3
|
+
PackageManagerType,
|
|
4
|
+
PlatformOptions,
|
|
5
|
+
SchemeType,
|
|
6
|
+
} from "./types";
|
|
2
7
|
|
|
3
8
|
export interface CreateArgs {
|
|
4
9
|
projectPath: string;
|
|
10
|
+
projectId: string;
|
|
5
11
|
template?: string;
|
|
6
12
|
jsOrTs: JsOrTs;
|
|
7
13
|
platformOptions: PlatformOptions;
|
|
14
|
+
packageManager: PackageManagerType;
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
export interface ConfigArgs {
|
|
@@ -23,6 +30,7 @@ export interface GenerateFilesArgs {
|
|
|
23
30
|
projectId: string;
|
|
24
31
|
projectApiToken: string | undefined;
|
|
25
32
|
platformOptions: PlatformOptions;
|
|
33
|
+
packageManager: PackageManagerType;
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
export interface BuildArgs {
|
|
@@ -34,6 +42,7 @@ export interface InstallArgs {
|
|
|
34
42
|
scheme: SchemeType;
|
|
35
43
|
projectPath: string;
|
|
36
44
|
jsOrTs: JsOrTs;
|
|
45
|
+
packageManager: PackageManagerType;
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
// TODO: Remove this interface and use a single "create" entry point.
|