create-plasmic-app 0.0.30 → 0.0.34

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/dist/lib.js CHANGED
@@ -85,8 +85,10 @@ function create(args) {
85
85
  useTypescript,
86
86
  template,
87
87
  });
88
- // Ensure that
89
- if (useTypescript) {
88
+ // Ensure that we have a empty tsconfig and @types packages
89
+ // Gatsby by default supports typescript handling internally
90
+ // tsconfig so we don't have to ensure it
91
+ if (useTypescript && platform !== "gatsby") {
90
92
  yield file_utils_1.ensureTsconfig(resolvedProjectPath);
91
93
  }
92
94
  // Install dependency
@@ -127,7 +129,10 @@ function create(args) {
127
129
  });
128
130
  }
129
131
  if (scheme === "loader") {
130
- yield cpaStrategy.overwriteFiles({ projectPath: resolvedProjectPath });
132
+ yield cpaStrategy.overwriteFiles({
133
+ projectPath: resolvedProjectPath,
134
+ useTypescript,
135
+ });
131
136
  }
132
137
  else if (scheme === "codegen") {
133
138
  // The loader files to be overwritten are handled by cpaStrategy
@@ -1,4 +1,23 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
22
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
23
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -8,12 +27,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
27
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
28
  });
10
29
  };
30
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
31
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
32
+ var m = o[Symbol.asyncIterator], i;
33
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
34
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
35
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
36
+ };
11
37
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
38
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
39
  };
14
40
  Object.defineProperty(exports, "__esModule", { value: true });
15
41
  const fs_1 = require("fs");
16
42
  const path_1 = __importDefault(require("path"));
43
+ const readline = __importStar(require("readline"));
17
44
  const gatsby_1 = require("../templates/gatsby");
18
45
  const cmd_utils_1 = require("../utils/cmd-utils");
19
46
  const file_utils_1 = require("../utils/file-utils");
@@ -23,29 +50,64 @@ const gatsbyStrategy = {
23
50
  const { projectPath, template } = args;
24
51
  const createCommand = `npx -p gatsby gatsby new ${projectPath}`;
25
52
  const templateArg = template ? ` ${template}` : "";
26
- // Default Gatsby starter already supports Typescript
27
- // See where we `touch tsconfig.json` later on
28
53
  yield cmd_utils_1.spawnOrFail(`${createCommand}${templateArg}`);
29
54
  }),
30
55
  configLoader: (args) => __awaiter(void 0, void 0, void 0, function* () {
31
- const { projectId, projectPath, projectApiToken } = args;
56
+ var e_1, _a;
57
+ const { projectId, projectPath, projectApiToken, useTypescript } = args;
32
58
  const installResult = yield npm_utils_1.installUpgrade("@plasmicapp/loader-gatsby", {
33
59
  workingDir: projectPath,
34
60
  });
35
61
  if (!installResult) {
36
62
  throw new Error("Failed to install the Plasmic dependency");
37
63
  }
38
- yield file_utils_1.modifyDefaultGatsbyConfig(projectPath, projectId, projectApiToken);
64
+ // create-gatsby will create a default gatsby-config.js that we need to modify
65
+ const gatsbyConfigFile = path_1.default.join(projectPath, "gatsby-config.js");
66
+ const rl = readline.createInterface({
67
+ input: fs_1.createReadStream(gatsbyConfigFile),
68
+ crlfDelay: Infinity,
69
+ });
70
+ let result = "";
71
+ try {
72
+ for (var rl_1 = __asyncValues(rl), rl_1_1; rl_1_1 = yield rl_1.next(), !rl_1_1.done;) {
73
+ const line = rl_1_1.value;
74
+ result += line + "\n";
75
+ // Prepend PlasmicLoader to list of plugins
76
+ if (line.includes("plugins:")) {
77
+ result += gatsby_1.GATSBY_PLUGIN_CONFIG(projectId, projectApiToken, useTypescript);
78
+ }
79
+ }
80
+ }
81
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
82
+ finally {
83
+ try {
84
+ if (rl_1_1 && !rl_1_1.done && (_a = rl_1.return)) yield _a.call(rl_1);
85
+ }
86
+ finally { if (e_1) throw e_1.error; }
87
+ }
88
+ yield fs_1.promises.writeFile(gatsbyConfigFile, result);
39
89
  }),
40
90
  overwriteFiles: (args) => __awaiter(void 0, void 0, void 0, function* () {
41
91
  // in gatsby we can delete all existing pages/components, since all pages are going
42
92
  // to be handled by templates/defaultPlasmicPage
43
- const { projectPath } = args;
44
- file_utils_1.deleteGlob(path_1.default.join(projectPath, "src/@(pages|components)/*.*"));
93
+ const { projectPath, useTypescript } = args;
94
+ const extension = useTypescript ? "ts" : "js";
95
+ file_utils_1.deleteGlob(path_1.default.join(projectPath, "src/@(pages|components|templates)/*.*"));
45
96
  // Create a very basic 404 page - `gatsby build` fails without it.
46
- // We've deleted the components that the default 404 page depended
47
- // on, so
48
- yield fs_1.promises.writeFile(path_1.default.join(projectPath, "src/pages/404.js"), gatsby_1.GATSBY_404);
97
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, `src/pages/404.js`), gatsby_1.GATSBY_404);
98
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, `src/plasmic-init.${extension}`), gatsby_1.makeGatsbyPlasmicInit(extension));
99
+ // Add plasmic-host page
100
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, `src/pages/plasmic-host.${extension}x`), gatsby_1.makeGatsbyHostPage(extension));
101
+ // Start with an empty gatsby-node.js
102
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "gatsby-node.js"), "");
103
+ // Updates `gatsby-ssr` to include script tag for preamble
104
+ yield fs_1.promises.writeFile(path_1.default.join(projectPath, "gatsby-ssr.js"), gatsby_1.GATSBY_SSR_CONFIG);
105
+ const templatesFolder = path_1.default.join(projectPath, "src/templates");
106
+ const defaultPagePath = path_1.default.join(templatesFolder, `defaultPlasmicPage.${extension}x`);
107
+ if (!fs_1.existsSync(templatesFolder)) {
108
+ yield fs_1.promises.mkdir(templatesFolder);
109
+ }
110
+ yield fs_1.promises.writeFile(defaultPagePath, gatsby_1.makeGatsbyDefaultPage(extension));
49
111
  }),
50
112
  build: (args) => __awaiter(void 0, void 0, void 0, function* () {
51
113
  const { npmRunCmd, projectPath } = args;
@@ -40,7 +40,10 @@ const nextjsStrategy = {
40
40
  // all the files from pages/ since we have inserted a optional catch all
41
41
  const { projectPath } = args;
42
42
  const pagesPath = path_1.default.join(projectPath, "pages");
43
- file_utils_1.deleteGlob(path_1.default.join(pagesPath, `*.*`), ["[[...plasmicLoaderPage]]"]);
43
+ file_utils_1.deleteGlob(path_1.default.join(pagesPath, `*.*`), [
44
+ "[[...catchall]]",
45
+ "plasmic-host",
46
+ ]);
44
47
  }),
45
48
  build: (args) => __awaiter(void 0, void 0, void 0, function* () {
46
49
  const { npmRunCmd, projectPath } = args;
@@ -11,6 +11,7 @@ interface ConfigArgs {
11
11
  }
12
12
  interface OverwriteFilesArgs {
13
13
  projectPath: string;
14
+ useTypescript: boolean;
14
15
  }
15
16
  interface BuildArgs {
16
17
  projectPath: string;
@@ -1,3 +1,6 @@
1
- export declare const GATSBY_DEFAULT_PAGE: string;
1
+ export declare const makeGatsbyDefaultPage: (format: "ts" | "js") => string;
2
2
  export declare const GATSBY_404: string;
3
- export declare const GATSBY_PLUGIN_CONFIG: (projectId: string, projectApiToken: string) => string;
3
+ export declare const GATSBY_PLUGIN_CONFIG: (projectId: string, projectApiToken: string, useTypescript: boolean) => string;
4
+ export declare const makeGatsbyHostPage: (format: "ts" | "js") => string;
5
+ export declare const GATSBY_SSR_CONFIG: string;
6
+ export declare const makeGatsbyPlasmicInit: (format: "ts" | "js") => string;
@@ -1,14 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GATSBY_PLUGIN_CONFIG = exports.GATSBY_404 = exports.GATSBY_DEFAULT_PAGE = void 0;
4
- exports.GATSBY_DEFAULT_PAGE = `
3
+ exports.makeGatsbyPlasmicInit = exports.GATSBY_SSR_CONFIG = exports.makeGatsbyHostPage = exports.GATSBY_PLUGIN_CONFIG = exports.GATSBY_404 = exports.makeGatsbyDefaultPage = void 0;
4
+ const file_utils_1 = require("../utils/file-utils");
5
+ const makeGatsbyDefaultPage = (format) => {
6
+ const ts = format === "ts";
7
+ return `
5
8
  import React from "react";
9
+ import Helmet from "react-helmet";
6
10
  import {
7
- initPlasmicLoader,
8
11
  PlasmicComponent,
9
- PlasmicRootProvider,
12
+ PlasmicRootProvider,${file_utils_1.ifTs(ts, `
13
+ InitOptions,
14
+ ComponentRenderData,`)}
10
15
  } from "@plasmicapp/loader-gatsby";
11
16
  import { graphql } from "gatsby";
17
+ import { initPlasmicLoaderWithRegistrations } from "../plasmic-init";
12
18
 
13
19
  export const query = graphql\`
14
20
  query ($path: String) {
@@ -17,33 +23,47 @@ export const query = graphql\`
17
23
  }
18
24
  \`;
19
25
 
20
- const removeTrailingSlash = path =>
21
- path === "/" ? "/" : path.replace(/\\/+$/, "");
22
-
23
- const PlasmicGatsbyPage = ({ data, location }) => {
26
+ ${file_utils_1.ifTs(ts, `interface PlasmicGatsbyPageProps {
27
+ data: {
28
+ plasmicOptions: InitOptions
29
+ plasmicComponents: ComponentRenderData
30
+ }
31
+ }
32
+ `)}
33
+ const PlasmicGatsbyPage = ({ data }${file_utils_1.ifTs(ts, ": PlasmicGatsbyPageProps")}) => {
24
34
  const {
25
35
  plasmicComponents,
26
36
  plasmicOptions,
27
37
  } = data;
38
+ const pageMeta = plasmicComponents.entryCompMetas[0];
39
+ const pageMetadata = pageMeta.pageMetadata;
28
40
  return (
29
41
  <PlasmicRootProvider
30
- loader={initPlasmicLoader(plasmicOptions)}
42
+ loader={initPlasmicLoaderWithRegistrations(plasmicOptions)}
31
43
  prefetchedData={plasmicComponents}
32
44
  >
33
- <PlasmicComponent component={removeTrailingSlash(location.pathname)} />
45
+ <Helmet>
46
+ {pageMetadata.title && <title>{pageMetadata.title}</title>}
47
+ {pageMetadata.title && <meta property="og:title" content={pageMetadata.title} /> }
48
+ {pageMetadata.description && <meta property="og:description" content={pageMetadata.description} />}
49
+ {pageMetadata.openGraphImageUrl && <meta property="og:image" content={pageMetadata.openGraphImageUrl} />}
50
+ </Helmet>
51
+ <PlasmicComponent component={pageMeta.name} />
34
52
  </PlasmicRootProvider>
35
53
  );
36
54
  };
37
55
 
38
56
  export default PlasmicGatsbyPage;
39
57
  `.trim();
58
+ };
59
+ exports.makeGatsbyDefaultPage = makeGatsbyDefaultPage;
40
60
  exports.GATSBY_404 = `
41
61
  const NotFound = () => {
42
62
  return "Not Found";
43
63
  };
44
64
  export default NotFound;
45
65
  `.trim();
46
- const GATSBY_PLUGIN_CONFIG = (projectId, projectApiToken) => `
66
+ const GATSBY_PLUGIN_CONFIG = (projectId, projectApiToken, useTypescript) => `
47
67
  {
48
68
  resolve: "@plasmicapp/loader-gatsby",
49
69
  options: {
@@ -53,8 +73,98 @@ const GATSBY_PLUGIN_CONFIG = (projectId, projectApiToken) => `
53
73
  token: "${projectApiToken}",
54
74
  },
55
75
  ], // An array of project ids.
56
- defaultPlasmicPage: require.resolve("./src/templates/defaultPlasmicPage.js"),
76
+ defaultPlasmicPage: require.resolve("./src/templates/defaultPlasmicPage.${useTypescript ? "tsx" : "jsx"}"),
57
77
  },
58
78
  },
59
79
  `;
60
80
  exports.GATSBY_PLUGIN_CONFIG = GATSBY_PLUGIN_CONFIG;
81
+ const makeGatsbyHostPage = (format) => {
82
+ const ts = format === "ts";
83
+ return `
84
+ import * as React from "react"
85
+ import {
86
+ PlasmicCanvasHost,${file_utils_1.ifTs(ts, `
87
+ InitOptions,`)}
88
+ } from "@plasmicapp/loader-gatsby"
89
+ import { graphql } from "gatsby"
90
+ import { initPlasmicLoaderWithRegistrations } from "../plasmic-init"
91
+
92
+ export const query = graphql\`
93
+ query {
94
+ plasmicOptions
95
+ }
96
+ \`
97
+
98
+ ${file_utils_1.ifTs(ts, `interface HostProps {
99
+ data: {
100
+ plasmicOptions: InitOptions;
101
+ }
102
+ }
103
+ `)}
104
+ export default function Host({ data }${file_utils_1.ifTs(ts, ": HostProps")}) {
105
+ const { plasmicOptions } = data
106
+ initPlasmicLoaderWithRegistrations(plasmicOptions)
107
+ return <PlasmicCanvasHost />
108
+ }
109
+ `.trim();
110
+ };
111
+ exports.makeGatsbyHostPage = makeGatsbyHostPage;
112
+ exports.GATSBY_SSR_CONFIG = `
113
+ /**
114
+ * Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
115
+ *
116
+ * See: https://www.gatsbyjs.com/docs/ssr-apis/
117
+ */
118
+
119
+ const React = require("react")
120
+
121
+ /**
122
+ * Add preamble to allow functional code components in studio.
123
+ *
124
+ * See: https://docs.plasmic.app/learn/functional-code-components/
125
+ */
126
+ const HeadComponents = [
127
+ <script
128
+ key="plasmic-preamble"
129
+ src="https://static1.plasmic.app/preamble.js"
130
+ />,
131
+ ]
132
+
133
+ const isProduction = process.env.NODE_ENV === "production"
134
+
135
+ exports.onRenderBody = ({ pathname, setHeadComponents }) => {
136
+ /**
137
+ * We add the preamble tag script to all pages during development mode
138
+ * because during development all pages are dynamically rendered based
139
+ * on \`/\` route, during production we add it only in \`/plasmic-host/\`
140
+ */
141
+ if (!isProduction || pathname === "/plasmic-host/") {
142
+ setHeadComponents(HeadComponents)
143
+ }
144
+ }
145
+ `.trim();
146
+ const makeGatsbyPlasmicInit = (format) => {
147
+ const ts = format === "ts";
148
+ return `
149
+ import {
150
+ initPlasmicLoader,${file_utils_1.ifTs(ts, `
151
+ InitOptions,`)}
152
+ } from "@plasmicapp/loader-gatsby";
153
+
154
+ export function initPlasmicLoaderWithRegistrations(plasmicOptions${file_utils_1.ifTs(ts, ": InitOptions")}) {
155
+ const PLASMIC = initPlasmicLoader(plasmicOptions);
156
+
157
+ // You can register any code components that you want to use here; see
158
+ // https://docs.plasmic.app/learn/code-components-ref/
159
+ // And configure your Plasmic project to use the host url pointing at
160
+ // the /plasmic-host page of your nextjs app (for example,
161
+ // http://localhost:8000/plasmic-host). See
162
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
163
+
164
+ // PLASMIC.registerComponent(...);
165
+
166
+ return PLASMIC;
167
+ }
168
+ `.trim();
169
+ };
170
+ exports.makeGatsbyPlasmicInit = makeGatsbyPlasmicInit;
@@ -1,3 +1,3 @@
1
- export declare const NEXTJS_INIT: (projectId: string, projectApiToken: string) => string;
2
- export declare const NEXTJS_DEFAULT_PAGE_TS: string;
3
- export declare const NEXTJS_DEFAULT_PAGE_JS: string;
1
+ export declare const makeNextjsInitPage: (projectId: string, projectApiToken: string) => string;
2
+ export declare function makeNextjsCatchallPage(format: "ts" | "js"): string;
3
+ export declare function makeNextjsHostPage(): string;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NEXTJS_DEFAULT_PAGE_JS = exports.NEXTJS_DEFAULT_PAGE_TS = exports.NEXTJS_INIT = void 0;
4
- const NEXTJS_INIT = (projectId, projectApiToken) => `
3
+ exports.makeNextjsHostPage = exports.makeNextjsCatchallPage = exports.makeNextjsInitPage = void 0;
4
+ const file_utils_1 = require("../utils/file-utils");
5
+ const makeNextjsInitPage = (projectId, projectApiToken) => `
5
6
  import { initPlasmicLoader } from "@plasmicapp/loader-nextjs";
6
7
 
7
8
  export const PLASMIC = initPlasmicLoader({
@@ -11,23 +12,40 @@ export const PLASMIC = initPlasmicLoader({
11
12
  token: "${projectApiToken}",
12
13
  },
13
14
  ],
15
+
16
+ // By default Plasmic will use the last published version of your project.
17
+ // For development, you can set preview to true, which will use the unpublished
18
+ // project, allowing you to see your designs without publishing. Please
19
+ // only use this for development, as this is significantly slower.
20
+ preview: false,
14
21
  });
22
+
23
+ // You can register any code components that you want to use here; see
24
+ // https://docs.plasmic.app/learn/code-components-ref/
25
+ // And configure your Plasmic project to use the host url pointing at
26
+ // the /plasmic-host page of your nextjs app (for example,
27
+ // http://localhost:3000/plasmic-host). See
28
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
29
+
30
+ // PLASMIC.registerComponent(...);
15
31
  `.trim();
16
- exports.NEXTJS_INIT = NEXTJS_INIT;
17
- exports.NEXTJS_DEFAULT_PAGE_TS = `
32
+ exports.makeNextjsInitPage = makeNextjsInitPage;
33
+ function makeNextjsCatchallPage(format) {
34
+ const ts = format === "ts";
35
+ return `
18
36
  import * as React from "react";
19
37
  import { PlasmicComponent } from "@plasmicapp/loader-nextjs";
20
- import { GetStaticPaths, GetStaticProps } from "next";
38
+ ${file_utils_1.ifTs(ts, `import { GetStaticPaths, GetStaticProps } from "next";\n`)}
21
39
  import {
22
40
  ComponentRenderData,
23
41
  PlasmicRootProvider,
24
42
  } from "@plasmicapp/loader-react";
25
43
  import Error from "next/error";
26
- import { PLASMIC } from "../init";
44
+ import { PLASMIC } from "../plasmic-init";
27
45
 
28
- export default function PlasmicLoaderPage(props: {
29
- plasmicData?: ComponentRenderData
30
- }) {
46
+ export default function PlasmicLoaderPage(props${file_utils_1.ifTs(ts, `: {
47
+ plasmicData?: ComponentRenderData;
48
+ }`)}) {
31
49
  const { plasmicData } = props;
32
50
  if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
33
51
  return <Error statusCode={404} />;
@@ -42,13 +60,16 @@ export default function PlasmicLoaderPage(props: {
42
60
  );
43
61
  }
44
62
 
45
- export const getStaticProps: GetStaticProps = async (context) => {
46
- const { plasmicLoaderPage } = context.params ?? {};
47
- const plasmicPath = typeof plasmicLoaderPage === 'string' ? plasmicLoaderPage : Array.isArray(plasmicLoaderPage) ? \`/\${plasmicLoaderPage.join('/')}\` : '/';
63
+ export const getStaticProps${file_utils_1.ifTs(ts, `: GetStaticProps`)} = async (context) => {
64
+ const { catchall } = context.params ?? {};
65
+ const plasmicPath = typeof catchall === 'string' ? catchall : Array.isArray(catchall) ? \`/\${catchall.join('/')}\` : '/';
48
66
  const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
49
67
  if (plasmicData) {
50
68
  return {
51
69
  props: { plasmicData },
70
+
71
+ // Use revalidate if you want incremental static regeneration
72
+ revalidate: 60
52
73
  };
53
74
  }
54
75
  return {
@@ -57,64 +78,38 @@ export const getStaticProps: GetStaticProps = async (context) => {
57
78
  };
58
79
  }
59
80
 
60
- export const getStaticPaths: GetStaticPaths = async () => {
81
+ export const getStaticPaths${file_utils_1.ifTs(ts, `: GetStaticPaths`)} = async () => {
61
82
  const pageModules = await PLASMIC.fetchPages();
62
83
  return {
63
84
  paths: pageModules.map((mod) => ({
64
85
  params: {
65
- plasmicLoaderPage: mod.path.substring(1).split("/"),
86
+ catchall: mod.path.substring(1).split("/"),
66
87
  },
67
88
  })),
68
- fallback: false,
89
+ fallback: "blocking"
69
90
  };
70
91
  }
71
- `.trim();
72
- exports.NEXTJS_DEFAULT_PAGE_JS = `
73
- import * as React from "react";
74
- import { initPlasmicLoader, PlasmicComponent } from "@plasmicapp/loader-nextjs";
75
- import { PlasmicRootProvider } from "@plasmicapp/loader-react";
76
- import Error from "next/error";
77
- import { PLASMIC } from "../init";
78
-
79
- export default function PlasmicLoaderPage(props) {
80
- const { plasmicData } = props;
81
- if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
82
- return <Error statusCode={404} />;
83
- }
84
- return (
85
- <PlasmicRootProvider
86
- loader={PLASMIC}
87
- prefetchedData={plasmicData}
88
- >
89
- <PlasmicComponent component={plasmicData.entryCompMetas[0].name} />
90
- </PlasmicRootProvider>
91
- );
92
+ `.trim();
92
93
  }
94
+ exports.makeNextjsCatchallPage = makeNextjsCatchallPage;
95
+ function makeNextjsHostPage() {
96
+ return `
97
+ import * as React from 'react';
98
+ import { PlasmicCanvasHost } from '@plasmicapp/loader-nextjs';
99
+ import Script from 'next/script';
100
+ import { PLASMIC } from '../plasmic-init';
93
101
 
94
- export const getStaticProps = async (context) => {
95
- const { plasmicLoaderPage } = context.params ?? {};
96
- const plasmicPath = typeof plasmicLoaderPage === 'string' ? plasmicLoaderPage : Array.isArray(plasmicLoaderPage) ? \`/\${plasmicLoaderPage.join('/')}\` : '/';
97
- const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
98
- if (plasmicData) {
99
- return {
100
- props: { plasmicData },
101
- };
102
- }
103
- return {
104
- // non-Plasmic catch-all
105
- props: {},
106
- };
102
+ export default function Host() {
103
+ return PLASMIC && (
104
+ <div>
105
+ <Script
106
+ src="https://static1.plasmic.app/preamble.js"
107
+ strategy="beforeInteractive"
108
+ />
109
+ <PlasmicCanvasHost />
110
+ </div>
111
+ );
107
112
  }
108
-
109
- export const getStaticPaths = async () => {
110
- const pageModules = await PLASMIC.fetchPages();
111
- return {
112
- paths: pageModules.map((mod) => ({
113
- params: {
114
- plasmicLoaderPage: mod.path.substring(1).split("/"),
115
- },
116
- })),
117
- fallback: false,
118
- };
113
+ `.trim();
119
114
  }
120
- `.trim();
115
+ exports.makeNextjsHostPage = makeNextjsHostPage;
@@ -15,13 +15,6 @@ export declare function stripExtension(filename: string, removeComposedPath?: bo
15
15
  */
16
16
  export declare function writeDefaultNextjsConfig(projectDir: string, projectId: string, loader: boolean, projectApiToken?: string, useTypescript?: boolean): Promise<void>;
17
17
  export declare function writePlasmicLoaderJson(projectDir: string, projectId: string, projectApiToken: string): Promise<void>;
18
- /**
19
- * create-gatsby will create a default gatsby-config.js that we need to modify
20
- * @param absPath
21
- * @param projectId
22
- * @returns
23
- */
24
- export declare function modifyDefaultGatsbyConfig(projectDir: string, projectId: string, projectApiToken: string): Promise<void>;
25
18
  /**
26
19
  * - [nextjs|gatsby, loader, '/' page exists] - remove index file
27
20
  * - [nextjs|gatsby, loader, '/' Page DNE] - replace index file with Welcome page
@@ -40,3 +33,4 @@ export declare function overwriteIndex(projectPath: string, platform: string, sc
40
33
  export declare function overwriteReadme(projectPath: string, platform: PlatformType, buildCommand: string): Promise<void>;
41
34
  export declare function ensureTsconfig(projectPath: string): Promise<void>;
42
35
  export declare function wrapAppRoot(projectPath: string, platform: string, scheme: string): Promise<void>;
36
+ export declare function ifTs(ts: boolean, str: string): string;
@@ -27,22 +27,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
27
27
  step((generator = generator.apply(thisArg, _arguments || [])).next());
28
28
  });
29
29
  };
30
- var __asyncValues = (this && this.__asyncValues) || function (o) {
31
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
32
- var m = o[Symbol.asyncIterator], i;
33
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
34
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
35
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
36
- };
37
30
  var __importDefault = (this && this.__importDefault) || function (mod) {
38
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
39
32
  };
40
33
  Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.wrapAppRoot = exports.ensureTsconfig = exports.overwriteReadme = exports.overwriteIndex = exports.modifyDefaultGatsbyConfig = exports.writePlasmicLoaderJson = exports.writeDefaultNextjsConfig = exports.stripExtension = exports.deleteGlob = void 0;
34
+ exports.ifTs = exports.wrapAppRoot = exports.ensureTsconfig = exports.overwriteReadme = exports.overwriteIndex = exports.writePlasmicLoaderJson = exports.writeDefaultNextjsConfig = exports.stripExtension = exports.deleteGlob = void 0;
42
35
  const fs_1 = require("fs");
43
36
  const glob_1 = __importDefault(require("glob"));
44
37
  const lodash_1 = __importDefault(require("lodash"));
45
- const readline = __importStar(require("readline"));
46
38
  const path = __importStar(require("upath"));
47
39
  const gatsby_1 = require("../templates/gatsby");
48
40
  const nextjs_1 = require("../templates/nextjs");
@@ -95,11 +87,13 @@ module.exports = {
95
87
  return;
96
88
  }
97
89
  if (loader && projectApiToken) {
98
- const initFile = path.join(projectDir, "init.js");
99
- yield fs_1.promises.writeFile(initFile, nextjs_1.NEXTJS_INIT(projectId, projectApiToken));
90
+ const initFile = path.join(projectDir, `plasmic-init.${useTypescript ? "ts" : "js"}`);
91
+ yield fs_1.promises.writeFile(initFile, nextjs_1.makeNextjsInitPage(projectId, projectApiToken));
100
92
  const pagesFolder = path.join(projectDir, "pages");
101
- const loaderPage = path.join(pagesFolder, `[[...plasmicLoaderPage]].${useTypescript ? "tsx" : "jsx"}`);
102
- yield fs_1.promises.writeFile(loaderPage, useTypescript ? nextjs_1.NEXTJS_DEFAULT_PAGE_TS : nextjs_1.NEXTJS_DEFAULT_PAGE_JS);
93
+ const loaderPage = path.join(pagesFolder, `[[...catchall]].${useTypescript ? "tsx" : "jsx"}`);
94
+ yield fs_1.promises.writeFile(loaderPage, nextjs_1.makeNextjsCatchallPage(useTypescript ? "ts" : "js"));
95
+ const hostPage = path.join(pagesFolder, `plasmic-host.${useTypescript ? "tsx" : "jsx"}`);
96
+ yield fs_1.promises.writeFile(hostPage, nextjs_1.makeNextjsHostPage());
103
97
  }
104
98
  });
105
99
  }
@@ -119,46 +113,6 @@ function writePlasmicLoaderJson(projectDir, projectId, projectApiToken) {
119
113
  });
120
114
  }
121
115
  exports.writePlasmicLoaderJson = writePlasmicLoaderJson;
122
- /**
123
- * create-gatsby will create a default gatsby-config.js that we need to modify
124
- * @param absPath
125
- * @param projectId
126
- * @returns
127
- */
128
- function modifyDefaultGatsbyConfig(projectDir, projectId, projectApiToken) {
129
- var e_1, _a;
130
- return __awaiter(this, void 0, void 0, function* () {
131
- const gatsbyConfigFile = path.join(projectDir, "gatsby-config.js");
132
- const rl = readline.createInterface({
133
- input: fs_1.createReadStream(gatsbyConfigFile),
134
- crlfDelay: Infinity,
135
- });
136
- let result = "";
137
- try {
138
- for (var rl_1 = __asyncValues(rl), rl_1_1; rl_1_1 = yield rl_1.next(), !rl_1_1.done;) {
139
- const line = rl_1_1.value;
140
- result += line + "\n";
141
- // Prepend PlasmicLoader to list of plugins
142
- if (line.includes("plugins:")) {
143
- result += gatsby_1.GATSBY_PLUGIN_CONFIG(projectId, projectApiToken);
144
- }
145
- }
146
- }
147
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
148
- finally {
149
- try {
150
- if (rl_1_1 && !rl_1_1.done && (_a = rl_1.return)) yield _a.call(rl_1);
151
- }
152
- finally { if (e_1) throw e_1.error; }
153
- }
154
- yield fs_1.promises.writeFile(gatsbyConfigFile, result);
155
- const templatesFolder = path.join(projectDir, "src/templates");
156
- const defaultPagePath = path.join(templatesFolder, "defaultPlasmicPage.js");
157
- yield fs_1.promises.mkdir(templatesFolder);
158
- yield fs_1.promises.writeFile(defaultPagePath, gatsby_1.GATSBY_DEFAULT_PAGE);
159
- });
160
- }
161
- exports.modifyDefaultGatsbyConfig = modifyDefaultGatsbyConfig;
162
116
  /**
163
117
  * - [nextjs|gatsby, loader, '/' page exists] - remove index file
164
118
  * - [nextjs|gatsby, loader, '/' Page DNE] - replace index file with Welcome page
@@ -372,3 +326,7 @@ export const wrapRootElement = ({ element }) => {
372
326
  });
373
327
  }
374
328
  exports.wrapAppRoot = wrapAppRoot;
329
+ function ifTs(ts, str) {
330
+ return ts ? str : "";
331
+ }
332
+ exports.ifTs = ifTs;
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-plasmic-app",
3
- "version": "0.0.30",
3
+ "version": "0.0.34",
4
4
  "description": "Create Plasmic-powered React apps",
5
5
  "main": "./dist/lib.js",
6
6
  "types": "./dist/lib.d.ts",
@@ -40,7 +40,7 @@
40
40
  "typescript": "^4.2.3"
41
41
  },
42
42
  "dependencies": {
43
- "@plasmicapp/cli": "^0.1.161",
43
+ "@plasmicapp/cli": "^0.1.166",
44
44
  "@sentry/node": "^6.2.2",
45
45
  "chalk": "^4.1.0",
46
46
  "execa": "^5.0.0",
package/src/lib.ts CHANGED
@@ -84,8 +84,10 @@ export async function create(args: CreatePlasmicAppArgs): Promise<void> {
84
84
  template,
85
85
  });
86
86
 
87
- // Ensure that
88
- if (useTypescript) {
87
+ // Ensure that we have a empty tsconfig and @types packages
88
+ // Gatsby by default supports typescript handling internally
89
+ // tsconfig so we don't have to ensure it
90
+ if (useTypescript && platform !== "gatsby") {
89
91
  await ensureTsconfig(resolvedProjectPath);
90
92
  }
91
93
 
@@ -136,7 +138,10 @@ export async function create(args: CreatePlasmicAppArgs): Promise<void> {
136
138
  }
137
139
 
138
140
  if (scheme === "loader") {
139
- await cpaStrategy.overwriteFiles({ projectPath: resolvedProjectPath });
141
+ await cpaStrategy.overwriteFiles({
142
+ projectPath: resolvedProjectPath,
143
+ useTypescript,
144
+ });
140
145
  } else if (scheme === "codegen") {
141
146
  // The loader files to be overwritten are handled by cpaStrategy
142
147
  // but for codegen we still have to run it
@@ -1,8 +1,16 @@
1
- import { promises as fs } from "fs";
1
+ import { createReadStream, existsSync, promises as fs } from "fs";
2
2
  import path from "path";
3
- import { GATSBY_404 } from "../templates/gatsby";
3
+ import * as readline from "readline";
4
+ import {
5
+ GATSBY_404,
6
+ GATSBY_PLUGIN_CONFIG,
7
+ GATSBY_SSR_CONFIG,
8
+ makeGatsbyDefaultPage,
9
+ makeGatsbyHostPage,
10
+ makeGatsbyPlasmicInit,
11
+ } from "../templates/gatsby";
4
12
  import { spawnOrFail } from "../utils/cmd-utils";
5
- import { deleteGlob, modifyDefaultGatsbyConfig } from "../utils/file-utils";
13
+ import { deleteGlob } from "../utils/file-utils";
6
14
  import { installUpgrade } from "../utils/npm-utils";
7
15
  import { CPAStrategy } from "./types";
8
16
 
@@ -12,12 +20,10 @@ const gatsbyStrategy: CPAStrategy = {
12
20
  const createCommand = `npx -p gatsby gatsby new ${projectPath}`;
13
21
  const templateArg = template ? ` ${template}` : "";
14
22
 
15
- // Default Gatsby starter already supports Typescript
16
- // See where we `touch tsconfig.json` later on
17
23
  await spawnOrFail(`${createCommand}${templateArg}`);
18
24
  },
19
25
  configLoader: async (args) => {
20
- const { projectId, projectPath, projectApiToken } = args;
26
+ const { projectId, projectPath, projectApiToken, useTypescript } = args;
21
27
 
22
28
  const installResult = await installUpgrade("@plasmicapp/loader-gatsby", {
23
29
  workingDir: projectPath,
@@ -27,19 +33,68 @@ const gatsbyStrategy: CPAStrategy = {
27
33
  throw new Error("Failed to install the Plasmic dependency");
28
34
  }
29
35
 
30
- await modifyDefaultGatsbyConfig(projectPath, projectId, projectApiToken);
36
+ // create-gatsby will create a default gatsby-config.js that we need to modify
37
+ const gatsbyConfigFile = path.join(projectPath, "gatsby-config.js");
38
+ const rl = readline.createInterface({
39
+ input: createReadStream(gatsbyConfigFile),
40
+ crlfDelay: Infinity,
41
+ });
42
+ let result = "";
43
+ for await (const line of rl) {
44
+ result += line + "\n";
45
+ // Prepend PlasmicLoader to list of plugins
46
+ if (line.includes("plugins:")) {
47
+ result += GATSBY_PLUGIN_CONFIG(
48
+ projectId,
49
+ projectApiToken,
50
+ useTypescript
51
+ );
52
+ }
53
+ }
54
+ await fs.writeFile(gatsbyConfigFile, result);
31
55
  },
32
56
  overwriteFiles: async (args) => {
33
57
  // in gatsby we can delete all existing pages/components, since all pages are going
34
58
  // to be handled by templates/defaultPlasmicPage
35
- const { projectPath } = args;
59
+ const { projectPath, useTypescript } = args;
60
+
61
+ const extension = useTypescript ? "ts" : "js";
36
62
 
37
- deleteGlob(path.join(projectPath, "src/@(pages|components)/*.*"));
63
+ deleteGlob(path.join(projectPath, "src/@(pages|components|templates)/*.*"));
38
64
 
39
65
  // Create a very basic 404 page - `gatsby build` fails without it.
40
- // We've deleted the components that the default 404 page depended
41
- // on, so
42
- await fs.writeFile(path.join(projectPath, "src/pages/404.js"), GATSBY_404);
66
+ await fs.writeFile(path.join(projectPath, `src/pages/404.js`), GATSBY_404);
67
+
68
+ await fs.writeFile(
69
+ path.join(projectPath, `src/plasmic-init.${extension}`),
70
+ makeGatsbyPlasmicInit(extension)
71
+ );
72
+
73
+ // Add plasmic-host page
74
+ await fs.writeFile(
75
+ path.join(projectPath, `src/pages/plasmic-host.${extension}x`),
76
+ makeGatsbyHostPage(extension)
77
+ );
78
+
79
+ // Start with an empty gatsby-node.js
80
+ await fs.writeFile(path.join(projectPath, "gatsby-node.js"), "");
81
+
82
+ // Updates `gatsby-ssr` to include script tag for preamble
83
+ await fs.writeFile(
84
+ path.join(projectPath, "gatsby-ssr.js"),
85
+ GATSBY_SSR_CONFIG
86
+ );
87
+
88
+ const templatesFolder = path.join(projectPath, "src/templates");
89
+ const defaultPagePath = path.join(
90
+ templatesFolder,
91
+ `defaultPlasmicPage.${extension}x`
92
+ );
93
+
94
+ if (!existsSync(templatesFolder)) {
95
+ await fs.mkdir(templatesFolder);
96
+ }
97
+ await fs.writeFile(defaultPagePath, makeGatsbyDefaultPage(extension));
43
98
  },
44
99
  build: async (args) => {
45
100
  const { npmRunCmd, projectPath } = args;
@@ -41,7 +41,10 @@ const nextjsStrategy: CPAStrategy = {
41
41
  const { projectPath } = args;
42
42
 
43
43
  const pagesPath = path.join(projectPath, "pages");
44
- deleteGlob(path.join(pagesPath, `*.*`), ["[[...plasmicLoaderPage]]"]);
44
+ deleteGlob(path.join(pagesPath, `*.*`), [
45
+ "[[...catchall]]",
46
+ "plasmic-host",
47
+ ]);
45
48
  },
46
49
  build: async (args) => {
47
50
  const { npmRunCmd, projectPath } = args;
@@ -13,6 +13,7 @@ interface ConfigArgs {
13
13
 
14
14
  interface OverwriteFilesArgs {
15
15
  projectPath: string;
16
+ useTypescript: boolean;
16
17
  }
17
18
 
18
19
  interface BuildArgs {
@@ -1,11 +1,21 @@
1
- export const GATSBY_DEFAULT_PAGE = `
1
+ import { ifTs } from "../utils/file-utils";
2
+
3
+ export const makeGatsbyDefaultPage = (format: "ts" | "js"): string => {
4
+ const ts = format === "ts";
5
+ return `
2
6
  import React from "react";
7
+ import Helmet from "react-helmet";
3
8
  import {
4
- initPlasmicLoader,
5
9
  PlasmicComponent,
6
- PlasmicRootProvider,
10
+ PlasmicRootProvider,${ifTs(
11
+ ts,
12
+ `
13
+ InitOptions,
14
+ ComponentRenderData,`
15
+ )}
7
16
  } from "@plasmicapp/loader-gatsby";
8
17
  import { graphql } from "gatsby";
18
+ import { initPlasmicLoaderWithRegistrations } from "../plasmic-init";
9
19
 
10
20
  export const query = graphql\`
11
21
  query ($path: String) {
@@ -14,26 +24,42 @@ export const query = graphql\`
14
24
  }
15
25
  \`;
16
26
 
17
- const removeTrailingSlash = path =>
18
- path === "/" ? "/" : path.replace(/\\/+$/, "");
19
-
20
- const PlasmicGatsbyPage = ({ data, location }) => {
27
+ ${ifTs(
28
+ ts,
29
+ `interface PlasmicGatsbyPageProps {
30
+ data: {
31
+ plasmicOptions: InitOptions
32
+ plasmicComponents: ComponentRenderData
33
+ }
34
+ }
35
+ `
36
+ )}
37
+ const PlasmicGatsbyPage = ({ data }${ifTs(ts, ": PlasmicGatsbyPageProps")}) => {
21
38
  const {
22
39
  plasmicComponents,
23
40
  plasmicOptions,
24
41
  } = data;
42
+ const pageMeta = plasmicComponents.entryCompMetas[0];
43
+ const pageMetadata = pageMeta.pageMetadata;
25
44
  return (
26
45
  <PlasmicRootProvider
27
- loader={initPlasmicLoader(plasmicOptions)}
46
+ loader={initPlasmicLoaderWithRegistrations(plasmicOptions)}
28
47
  prefetchedData={plasmicComponents}
29
48
  >
30
- <PlasmicComponent component={removeTrailingSlash(location.pathname)} />
49
+ <Helmet>
50
+ {pageMetadata.title && <title>{pageMetadata.title}</title>}
51
+ {pageMetadata.title && <meta property="og:title" content={pageMetadata.title} /> }
52
+ {pageMetadata.description && <meta property="og:description" content={pageMetadata.description} />}
53
+ {pageMetadata.openGraphImageUrl && <meta property="og:image" content={pageMetadata.openGraphImageUrl} />}
54
+ </Helmet>
55
+ <PlasmicComponent component={pageMeta.name} />
31
56
  </PlasmicRootProvider>
32
57
  );
33
58
  };
34
59
 
35
60
  export default PlasmicGatsbyPage;
36
61
  `.trim();
62
+ };
37
63
 
38
64
  export const GATSBY_404 = `
39
65
  const NotFound = () => {
@@ -44,7 +70,8 @@ export default NotFound;
44
70
 
45
71
  export const GATSBY_PLUGIN_CONFIG = (
46
72
  projectId: string,
47
- projectApiToken: string
73
+ projectApiToken: string,
74
+ useTypescript: boolean
48
75
  ): string => `
49
76
  {
50
77
  resolve: "@plasmicapp/loader-gatsby",
@@ -55,7 +82,112 @@ export const GATSBY_PLUGIN_CONFIG = (
55
82
  token: "${projectApiToken}",
56
83
  },
57
84
  ], // An array of project ids.
58
- defaultPlasmicPage: require.resolve("./src/templates/defaultPlasmicPage.js"),
85
+ defaultPlasmicPage: require.resolve("./src/templates/defaultPlasmicPage.${
86
+ useTypescript ? "tsx" : "jsx"
87
+ }"),
59
88
  },
60
89
  },
61
90
  `;
91
+
92
+ export const makeGatsbyHostPage = (format: "ts" | "js"): string => {
93
+ const ts = format === "ts";
94
+ return `
95
+ import * as React from "react"
96
+ import {
97
+ PlasmicCanvasHost,${ifTs(
98
+ ts,
99
+ `
100
+ InitOptions,`
101
+ )}
102
+ } from "@plasmicapp/loader-gatsby"
103
+ import { graphql } from "gatsby"
104
+ import { initPlasmicLoaderWithRegistrations } from "../plasmic-init"
105
+
106
+ export const query = graphql\`
107
+ query {
108
+ plasmicOptions
109
+ }
110
+ \`
111
+
112
+ ${ifTs(
113
+ ts,
114
+ `interface HostProps {
115
+ data: {
116
+ plasmicOptions: InitOptions;
117
+ }
118
+ }
119
+ `
120
+ )}
121
+ export default function Host({ data }${ifTs(ts, ": HostProps")}) {
122
+ const { plasmicOptions } = data
123
+ initPlasmicLoaderWithRegistrations(plasmicOptions)
124
+ return <PlasmicCanvasHost />
125
+ }
126
+ `.trim();
127
+ };
128
+
129
+ export const GATSBY_SSR_CONFIG = `
130
+ /**
131
+ * Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
132
+ *
133
+ * See: https://www.gatsbyjs.com/docs/ssr-apis/
134
+ */
135
+
136
+ const React = require("react")
137
+
138
+ /**
139
+ * Add preamble to allow functional code components in studio.
140
+ *
141
+ * See: https://docs.plasmic.app/learn/functional-code-components/
142
+ */
143
+ const HeadComponents = [
144
+ <script
145
+ key="plasmic-preamble"
146
+ src="https://static1.plasmic.app/preamble.js"
147
+ />,
148
+ ]
149
+
150
+ const isProduction = process.env.NODE_ENV === "production"
151
+
152
+ exports.onRenderBody = ({ pathname, setHeadComponents }) => {
153
+ /**
154
+ * We add the preamble tag script to all pages during development mode
155
+ * because during development all pages are dynamically rendered based
156
+ * on \`/\` route, during production we add it only in \`/plasmic-host/\`
157
+ */
158
+ if (!isProduction || pathname === "/plasmic-host/") {
159
+ setHeadComponents(HeadComponents)
160
+ }
161
+ }
162
+ `.trim();
163
+
164
+ export const makeGatsbyPlasmicInit = (format: "ts" | "js"): string => {
165
+ const ts = format === "ts";
166
+ return `
167
+ import {
168
+ initPlasmicLoader,${ifTs(
169
+ ts,
170
+ `
171
+ InitOptions,`
172
+ )}
173
+ } from "@plasmicapp/loader-gatsby";
174
+
175
+ export function initPlasmicLoaderWithRegistrations(plasmicOptions${ifTs(
176
+ ts,
177
+ ": InitOptions"
178
+ )}) {
179
+ const PLASMIC = initPlasmicLoader(plasmicOptions);
180
+
181
+ // You can register any code components that you want to use here; see
182
+ // https://docs.plasmic.app/learn/code-components-ref/
183
+ // And configure your Plasmic project to use the host url pointing at
184
+ // the /plasmic-host page of your nextjs app (for example,
185
+ // http://localhost:8000/plasmic-host). See
186
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
187
+
188
+ // PLASMIC.registerComponent(...);
189
+
190
+ return PLASMIC;
191
+ }
192
+ `.trim();
193
+ };
@@ -1,4 +1,6 @@
1
- export const NEXTJS_INIT = (
1
+ import { ifTs } from "../utils/file-utils";
2
+
3
+ export const makeNextjsInitPage = (
2
4
  projectId: string,
3
5
  projectApiToken: string
4
6
  ): string =>
@@ -12,23 +14,43 @@ export const PLASMIC = initPlasmicLoader({
12
14
  token: "${projectApiToken}",
13
15
  },
14
16
  ],
17
+
18
+ // By default Plasmic will use the last published version of your project.
19
+ // For development, you can set preview to true, which will use the unpublished
20
+ // project, allowing you to see your designs without publishing. Please
21
+ // only use this for development, as this is significantly slower.
22
+ preview: false,
15
23
  });
24
+
25
+ // You can register any code components that you want to use here; see
26
+ // https://docs.plasmic.app/learn/code-components-ref/
27
+ // And configure your Plasmic project to use the host url pointing at
28
+ // the /plasmic-host page of your nextjs app (for example,
29
+ // http://localhost:3000/plasmic-host). See
30
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
31
+
32
+ // PLASMIC.registerComponent(...);
16
33
  `.trim();
17
34
 
18
- export const NEXTJS_DEFAULT_PAGE_TS = `
35
+ export function makeNextjsCatchallPage(format: "ts" | "js"): string {
36
+ const ts = format === "ts";
37
+ return `
19
38
  import * as React from "react";
20
39
  import { PlasmicComponent } from "@plasmicapp/loader-nextjs";
21
- import { GetStaticPaths, GetStaticProps } from "next";
40
+ ${ifTs(ts, `import { GetStaticPaths, GetStaticProps } from "next";\n`)}
22
41
  import {
23
42
  ComponentRenderData,
24
43
  PlasmicRootProvider,
25
44
  } from "@plasmicapp/loader-react";
26
45
  import Error from "next/error";
27
- import { PLASMIC } from "../init";
46
+ import { PLASMIC } from "../plasmic-init";
28
47
 
29
- export default function PlasmicLoaderPage(props: {
30
- plasmicData?: ComponentRenderData
31
- }) {
48
+ export default function PlasmicLoaderPage(props${ifTs(
49
+ ts,
50
+ `: {
51
+ plasmicData?: ComponentRenderData;
52
+ }`
53
+ )}) {
32
54
  const { plasmicData } = props;
33
55
  if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
34
56
  return <Error statusCode={404} />;
@@ -43,13 +65,19 @@ export default function PlasmicLoaderPage(props: {
43
65
  );
44
66
  }
45
67
 
46
- export const getStaticProps: GetStaticProps = async (context) => {
47
- const { plasmicLoaderPage } = context.params ?? {};
48
- const plasmicPath = typeof plasmicLoaderPage === 'string' ? plasmicLoaderPage : Array.isArray(plasmicLoaderPage) ? \`/\${plasmicLoaderPage.join('/')}\` : '/';
68
+ export const getStaticProps${ifTs(
69
+ ts,
70
+ `: GetStaticProps`
71
+ )} = async (context) => {
72
+ const { catchall } = context.params ?? {};
73
+ const plasmicPath = typeof catchall === 'string' ? catchall : Array.isArray(catchall) ? \`/\${catchall.join('/')}\` : '/';
49
74
  const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
50
75
  if (plasmicData) {
51
76
  return {
52
77
  props: { plasmicData },
78
+
79
+ // Use revalidate if you want incremental static regeneration
80
+ revalidate: 60
53
81
  };
54
82
  }
55
83
  return {
@@ -58,65 +86,37 @@ export const getStaticProps: GetStaticProps = async (context) => {
58
86
  };
59
87
  }
60
88
 
61
- export const getStaticPaths: GetStaticPaths = async () => {
89
+ export const getStaticPaths${ifTs(ts, `: GetStaticPaths`)} = async () => {
62
90
  const pageModules = await PLASMIC.fetchPages();
63
91
  return {
64
92
  paths: pageModules.map((mod) => ({
65
93
  params: {
66
- plasmicLoaderPage: mod.path.substring(1).split("/"),
94
+ catchall: mod.path.substring(1).split("/"),
67
95
  },
68
96
  })),
69
- fallback: false,
97
+ fallback: "blocking"
70
98
  };
71
99
  }
72
- `.trim();
100
+ `.trim();
101
+ }
73
102
 
74
- export const NEXTJS_DEFAULT_PAGE_JS = `
75
- import * as React from "react";
76
- import { initPlasmicLoader, PlasmicComponent } from "@plasmicapp/loader-nextjs";
77
- import { PlasmicRootProvider } from "@plasmicapp/loader-react";
78
- import Error from "next/error";
79
- import { PLASMIC } from "../init";
103
+ export function makeNextjsHostPage(): string {
104
+ return `
105
+ import * as React from 'react';
106
+ import { PlasmicCanvasHost } from '@plasmicapp/loader-nextjs';
107
+ import Script from 'next/script';
108
+ import { PLASMIC } from '../plasmic-init';
80
109
 
81
- export default function PlasmicLoaderPage(props) {
82
- const { plasmicData } = props;
83
- if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
84
- return <Error statusCode={404} />;
85
- }
86
- return (
87
- <PlasmicRootProvider
88
- loader={PLASMIC}
89
- prefetchedData={plasmicData}
90
- >
91
- <PlasmicComponent component={plasmicData.entryCompMetas[0].name} />
92
- </PlasmicRootProvider>
110
+ export default function Host() {
111
+ return PLASMIC && (
112
+ <div>
113
+ <Script
114
+ src="https://static1.plasmic.app/preamble.js"
115
+ strategy="beforeInteractive"
116
+ />
117
+ <PlasmicCanvasHost />
118
+ </div>
93
119
  );
94
120
  }
95
-
96
- export const getStaticProps = async (context) => {
97
- const { plasmicLoaderPage } = context.params ?? {};
98
- const plasmicPath = typeof plasmicLoaderPage === 'string' ? plasmicLoaderPage : Array.isArray(plasmicLoaderPage) ? \`/\${plasmicLoaderPage.join('/')}\` : '/';
99
- const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
100
- if (plasmicData) {
101
- return {
102
- props: { plasmicData },
103
- };
104
- }
105
- return {
106
- // non-Plasmic catch-all
107
- props: {},
108
- };
121
+ `.trim();
109
122
  }
110
-
111
- export const getStaticPaths = async () => {
112
- const pageModules = await PLASMIC.fetchPages();
113
- return {
114
- paths: pageModules.map((mod) => ({
115
- params: {
116
- plasmicLoaderPage: mod.path.substring(1).split("/"),
117
- },
118
- })),
119
- fallback: false,
120
- };
121
- }
122
- `.trim();
@@ -1,18 +1,13 @@
1
- import { createReadStream, existsSync, promises as fs, unlinkSync } from "fs";
1
+ import { existsSync, promises as fs, unlinkSync } from "fs";
2
2
  import glob from "glob";
3
3
  import L from "lodash";
4
- import * as readline from "readline";
5
4
  import * as path from "upath";
6
5
  import { PlatformType } from "../lib";
6
+ import { GATSBY_404 } from "../templates/gatsby";
7
7
  import {
8
- GATSBY_404,
9
- GATSBY_DEFAULT_PAGE,
10
- GATSBY_PLUGIN_CONFIG,
11
- } from "../templates/gatsby";
12
- import {
13
- NEXTJS_DEFAULT_PAGE_JS,
14
- NEXTJS_DEFAULT_PAGE_TS,
15
- NEXTJS_INIT,
8
+ makeNextjsCatchallPage,
9
+ makeNextjsHostPage,
10
+ makeNextjsInitPage,
16
11
  } from "../templates/nextjs";
17
12
  import { README } from "../templates/readme";
18
13
  import { WELCOME_PAGE } from "../templates/welcomePage";
@@ -83,19 +78,31 @@ module.exports = {
83
78
  }
84
79
 
85
80
  if (loader && projectApiToken) {
86
- const initFile = path.join(projectDir, "init.js");
87
- await fs.writeFile(initFile, NEXTJS_INIT(projectId, projectApiToken));
81
+ const initFile = path.join(
82
+ projectDir,
83
+ `plasmic-init.${useTypescript ? "ts" : "js"}`
84
+ );
85
+ await fs.writeFile(
86
+ initFile,
87
+ makeNextjsInitPage(projectId, projectApiToken)
88
+ );
88
89
 
89
90
  const pagesFolder = path.join(projectDir, "pages");
90
91
  const loaderPage = path.join(
91
92
  pagesFolder,
92
- `[[...plasmicLoaderPage]].${useTypescript ? "tsx" : "jsx"}`
93
+ `[[...catchall]].${useTypescript ? "tsx" : "jsx"}`
93
94
  );
94
-
95
95
  await fs.writeFile(
96
96
  loaderPage,
97
- useTypescript ? NEXTJS_DEFAULT_PAGE_TS : NEXTJS_DEFAULT_PAGE_JS
97
+ makeNextjsCatchallPage(useTypescript ? "ts" : "js")
98
98
  );
99
+
100
+ const hostPage = path.join(
101
+ pagesFolder,
102
+ `plasmic-host.${useTypescript ? "tsx" : "jsx"}`
103
+ );
104
+
105
+ await fs.writeFile(hostPage, makeNextjsHostPage());
99
106
  }
100
107
  }
101
108
 
@@ -116,39 +123,6 @@ export async function writePlasmicLoaderJson(
116
123
  await fs.writeFile(plasmicLoaderJson, JSON.stringify(content));
117
124
  }
118
125
 
119
- /**
120
- * create-gatsby will create a default gatsby-config.js that we need to modify
121
- * @param absPath
122
- * @param projectId
123
- * @returns
124
- */
125
- export async function modifyDefaultGatsbyConfig(
126
- projectDir: string,
127
- projectId: string,
128
- projectApiToken: string
129
- ): Promise<void> {
130
- const gatsbyConfigFile = path.join(projectDir, "gatsby-config.js");
131
- const rl = readline.createInterface({
132
- input: createReadStream(gatsbyConfigFile),
133
- crlfDelay: Infinity,
134
- });
135
- let result = "";
136
- for await (const line of rl) {
137
- result += line + "\n";
138
- // Prepend PlasmicLoader to list of plugins
139
- if (line.includes("plugins:")) {
140
- result += GATSBY_PLUGIN_CONFIG(projectId, projectApiToken);
141
- }
142
- }
143
- await fs.writeFile(gatsbyConfigFile, result);
144
-
145
- const templatesFolder = path.join(projectDir, "src/templates");
146
- const defaultPagePath = path.join(templatesFolder, "defaultPlasmicPage.js");
147
-
148
- await fs.mkdir(templatesFolder);
149
- await fs.writeFile(defaultPagePath, GATSBY_DEFAULT_PAGE);
150
- }
151
-
152
126
  /**
153
127
  * - [nextjs|gatsby, loader, '/' page exists] - remove index file
154
128
  * - [nextjs|gatsby, loader, '/' Page DNE] - replace index file with Welcome page
@@ -410,3 +384,7 @@ export const wrapRootElement = ({ element }) => {
410
384
  await fs.writeFile(ssrFilePath, wrapperContent);
411
385
  }
412
386
  }
387
+
388
+ export function ifTs(ts: boolean, str: string) {
389
+ return ts ? str : "";
390
+ }