create-plasmic-app 0.0.63 → 0.0.64

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.
Files changed (209) hide show
  1. package/README.internal.md +6 -2
  2. package/cpa-out/.gitignore +15 -0
  3. package/cpa-out/gatsby-codegen-js/gatsby-browser.jsx +11 -0
  4. package/cpa-out/gatsby-codegen-js/gatsby-config.js +9 -0
  5. package/cpa-out/gatsby-codegen-js/gatsby-node.js +0 -0
  6. package/cpa-out/gatsby-codegen-js/gatsby-ssr.jsx +11 -0
  7. package/cpa-out/gatsby-codegen-js/package.json +26 -0
  8. package/cpa-out/gatsby-codegen-js/plasmic.json +79 -0
  9. package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.jsx +29 -0
  10. package/cpa-out/gatsby-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicHomepage.jsx +206 -0
  11. package/cpa-out/gatsby-codegen-js/src/pages/404.js +4 -0
  12. package/cpa-out/gatsby-codegen-js/src/pages/index.jsx +39 -0
  13. package/cpa-out/gatsby-codegen-ts/gatsby-browser.tsx +11 -0
  14. package/cpa-out/gatsby-codegen-ts/gatsby-config.ts +14 -0
  15. package/cpa-out/gatsby-codegen-ts/gatsby-node.ts +0 -0
  16. package/cpa-out/gatsby-codegen-ts/gatsby-ssr.tsx +11 -0
  17. package/cpa-out/gatsby-codegen-ts/package.json +34 -0
  18. package/cpa-out/gatsby-codegen-ts/plasmic.json +79 -0
  19. package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.tsx +30 -0
  20. package/cpa-out/gatsby-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicHomepage.tsx +290 -0
  21. package/cpa-out/gatsby-codegen-ts/src/pages/404.js +4 -0
  22. package/cpa-out/gatsby-codegen-ts/src/pages/index.tsx +41 -0
  23. package/cpa-out/gatsby-codegen-ts/tsconfig.json +102 -0
  24. package/cpa-out/gatsby-loader-js/gatsby-config.js +25 -0
  25. package/cpa-out/gatsby-loader-js/gatsby-node.js +0 -0
  26. package/cpa-out/gatsby-loader-js/gatsby-ssr.jsx +44 -0
  27. package/cpa-out/gatsby-loader-js/package.json +24 -0
  28. package/cpa-out/gatsby-loader-js/src/pages/404.js +4 -0
  29. package/cpa-out/gatsby-loader-js/src/pages/plasmic-host.jsx +19 -0
  30. package/cpa-out/gatsby-loader-js/src/plasmic-init.js +18 -0
  31. package/cpa-out/gatsby-loader-js/src/templates/defaultPlasmicPage.jsx +44 -0
  32. package/cpa-out/gatsby-loader-ts/gatsby-config.ts +31 -0
  33. package/cpa-out/gatsby-loader-ts/gatsby-node.ts +0 -0
  34. package/cpa-out/gatsby-loader-ts/gatsby-ssr.tsx +44 -0
  35. package/cpa-out/gatsby-loader-ts/package.json +32 -0
  36. package/cpa-out/gatsby-loader-ts/src/pages/404.ts +4 -0
  37. package/cpa-out/gatsby-loader-ts/src/pages/plasmic-host.tsx +24 -0
  38. package/cpa-out/gatsby-loader-ts/src/plasmic-init.ts +19 -0
  39. package/cpa-out/gatsby-loader-ts/src/templates/defaultPlasmicPage.tsx +52 -0
  40. package/cpa-out/gatsby-loader-ts/tsconfig.json +102 -0
  41. package/cpa-out/nextjs-app-loader-js/app/[[...catchall]]/page.jsx +56 -0
  42. package/cpa-out/nextjs-app-loader-js/app/head.js +10 -0
  43. package/cpa-out/nextjs-app-loader-js/app/layout.js +14 -0
  44. package/cpa-out/nextjs-app-loader-js/app/plasmic-host/page.jsx +6 -0
  45. package/cpa-out/nextjs-app-loader-js/next.config.js +13 -0
  46. package/cpa-out/nextjs-app-loader-js/package.json +20 -0
  47. package/cpa-out/nextjs-app-loader-js/pages/api/hello.js +5 -0
  48. package/cpa-out/nextjs-app-loader-js/plasmic-init-client.jsx +65 -0
  49. package/cpa-out/nextjs-app-loader-js/plasmic-init.js +16 -0
  50. package/cpa-out/nextjs-app-loader-ts/app/[[...catchall]]/page.tsx +59 -0
  51. package/cpa-out/nextjs-app-loader-ts/app/head.tsx +10 -0
  52. package/cpa-out/nextjs-app-loader-ts/app/layout.tsx +18 -0
  53. package/cpa-out/nextjs-app-loader-ts/app/plasmic-host/page.tsx +6 -0
  54. package/cpa-out/nextjs-app-loader-ts/next.config.js +13 -0
  55. package/cpa-out/nextjs-app-loader-ts/package.json +24 -0
  56. package/cpa-out/nextjs-app-loader-ts/pages/api/hello.ts +13 -0
  57. package/cpa-out/nextjs-app-loader-ts/plasmic-init-client.tsx +65 -0
  58. package/cpa-out/nextjs-app-loader-ts/plasmic-init.ts +16 -0
  59. package/cpa-out/nextjs-app-loader-ts/tsconfig.json +29 -0
  60. package/cpa-out/nextjs-pages-codegen-js/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.jsx +29 -0
  61. package/cpa-out/nextjs-pages-codegen-js/components/plasmic/create_plasmic_app/PlasmicHomepage.jsx +205 -0
  62. package/cpa-out/nextjs-pages-codegen-js/next.config.js +10 -0
  63. package/cpa-out/nextjs-pages-codegen-js/package.json +22 -0
  64. package/cpa-out/nextjs-pages-codegen-js/pages/_app.jsx +11 -0
  65. package/cpa-out/nextjs-pages-codegen-js/pages/api/hello.js +5 -0
  66. package/cpa-out/nextjs-pages-codegen-js/pages/index.jsx +35 -0
  67. package/cpa-out/nextjs-pages-codegen-js/pages/plasmic-host.jsx +15 -0
  68. package/cpa-out/nextjs-pages-codegen-js/plasmic.json +79 -0
  69. package/cpa-out/nextjs-pages-codegen-ts/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.tsx +30 -0
  70. package/cpa-out/nextjs-pages-codegen-ts/components/plasmic/create_plasmic_app/PlasmicHomepage.tsx +287 -0
  71. package/cpa-out/nextjs-pages-codegen-ts/next.config.js +10 -0
  72. package/cpa-out/nextjs-pages-codegen-ts/package.json +26 -0
  73. package/cpa-out/nextjs-pages-codegen-ts/pages/_app.tsx +12 -0
  74. package/cpa-out/nextjs-pages-codegen-ts/pages/api/hello.ts +13 -0
  75. package/cpa-out/nextjs-pages-codegen-ts/pages/index.tsx +37 -0
  76. package/cpa-out/nextjs-pages-codegen-ts/pages/plasmic-host.tsx +15 -0
  77. package/cpa-out/nextjs-pages-codegen-ts/plasmic.json +79 -0
  78. package/cpa-out/nextjs-pages-codegen-ts/tsconfig.json +24 -0
  79. package/cpa-out/nextjs-pages-loader-js/next.config.js +10 -0
  80. package/cpa-out/nextjs-pages-loader-js/package.json +20 -0
  81. package/cpa-out/nextjs-pages-loader-js/pages/[[...catchall]].jsx +66 -0
  82. package/cpa-out/nextjs-pages-loader-js/pages/api/hello.js +5 -0
  83. package/cpa-out/nextjs-pages-loader-js/pages/plasmic-host.jsx +7 -0
  84. package/cpa-out/nextjs-pages-loader-js/plasmic-init.js +25 -0
  85. package/cpa-out/nextjs-pages-loader-ts/next.config.js +10 -0
  86. package/cpa-out/nextjs-pages-loader-ts/package.json +24 -0
  87. package/cpa-out/nextjs-pages-loader-ts/pages/[[...catchall]].tsx +70 -0
  88. package/cpa-out/nextjs-pages-loader-ts/pages/api/hello.ts +13 -0
  89. package/cpa-out/nextjs-pages-loader-ts/pages/plasmic-host.tsx +7 -0
  90. package/cpa-out/nextjs-pages-loader-ts/plasmic-init.ts +25 -0
  91. package/cpa-out/nextjs-pages-loader-ts/tsconfig.json +24 -0
  92. package/cpa-out/react-codegen-js/package.json +41 -0
  93. package/cpa-out/react-codegen-js/plasmic.json +76 -0
  94. package/cpa-out/react-codegen-js/src/App.jsx +9 -0
  95. package/cpa-out/react-codegen-js/src/components/Homepage.jsx +26 -0
  96. package/cpa-out/react-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.jsx +29 -0
  97. package/cpa-out/react-codegen-js/src/components/plasmic/create_plasmic_app/PlasmicHomepage.jsx +196 -0
  98. package/cpa-out/react-codegen-js/src/index.js +17 -0
  99. package/cpa-out/react-codegen-js/src/reportWebVitals.js +13 -0
  100. package/cpa-out/react-codegen-js/src/setupTests.js +5 -0
  101. package/cpa-out/react-codegen-ts/package.json +46 -0
  102. package/cpa-out/react-codegen-ts/plasmic.json +76 -0
  103. package/cpa-out/react-codegen-ts/src/App.tsx +9 -0
  104. package/cpa-out/react-codegen-ts/src/components/Homepage.tsx +45 -0
  105. package/cpa-out/react-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.tsx +30 -0
  106. package/cpa-out/react-codegen-ts/src/components/plasmic/create_plasmic_app/PlasmicHomepage.tsx +280 -0
  107. package/cpa-out/react-codegen-ts/src/index.tsx +19 -0
  108. package/cpa-out/react-codegen-ts/src/react-app-env.d.ts +1 -0
  109. package/cpa-out/react-codegen-ts/src/reportWebVitals.ts +15 -0
  110. package/cpa-out/react-codegen-ts/src/setupTests.ts +5 -0
  111. package/cpa-out/react-codegen-ts/tsconfig.json +26 -0
  112. package/cpa-out/react-loader-js/package.json +41 -0
  113. package/cpa-out/react-loader-js/plasmic.json +76 -0
  114. package/cpa-out/react-loader-js/src/App.jsx +9 -0
  115. package/cpa-out/react-loader-js/src/components/Homepage.jsx +26 -0
  116. package/cpa-out/react-loader-js/src/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.jsx +29 -0
  117. package/cpa-out/react-loader-js/src/components/plasmic/create_plasmic_app/PlasmicHomepage.jsx +196 -0
  118. package/cpa-out/react-loader-js/src/index.js +17 -0
  119. package/cpa-out/react-loader-js/src/reportWebVitals.js +13 -0
  120. package/cpa-out/react-loader-js/src/setupTests.js +5 -0
  121. package/cpa-out/react-loader-ts/package.json +46 -0
  122. package/cpa-out/react-loader-ts/plasmic.json +76 -0
  123. package/cpa-out/react-loader-ts/src/App.tsx +9 -0
  124. package/cpa-out/react-loader-ts/src/components/Homepage.tsx +45 -0
  125. package/cpa-out/react-loader-ts/src/components/plasmic/create_plasmic_app/PlasmicGlobalVariant__Screen.tsx +30 -0
  126. package/cpa-out/react-loader-ts/src/components/plasmic/create_plasmic_app/PlasmicHomepage.tsx +280 -0
  127. package/cpa-out/react-loader-ts/src/index.tsx +19 -0
  128. package/cpa-out/react-loader-ts/src/react-app-env.d.ts +1 -0
  129. package/cpa-out/react-loader-ts/src/reportWebVitals.ts +15 -0
  130. package/cpa-out/react-loader-ts/src/setupTests.ts +5 -0
  131. package/cpa-out/react-loader-ts/tsconfig.json +26 -0
  132. package/dist/gatsby/gatsby.d.ts +6 -0
  133. package/dist/{strategies → gatsby}/gatsby.js +26 -29
  134. package/dist/gatsby/template.d.ts +11 -0
  135. package/dist/{templates/gatsby.js → gatsby/template.js} +34 -42
  136. package/dist/index.d.ts +1 -1
  137. package/dist/index.js +57 -27
  138. package/dist/lib.d.ts +3 -4
  139. package/dist/lib.js +22 -12
  140. package/dist/nextjs/nextjs.d.ts +2 -0
  141. package/dist/nextjs/nextjs.js +155 -0
  142. package/dist/nextjs/templates/app-loader/catchall-page.d.ts +2 -0
  143. package/dist/nextjs/templates/app-loader/catchall-page.js +67 -0
  144. package/dist/nextjs/templates/app-loader/plasmic-host.d.ts +1 -0
  145. package/dist/nextjs/templates/app-loader/plasmic-host.js +13 -0
  146. package/dist/nextjs/templates/app-loader/plasmic-init-client.d.ts +2 -0
  147. package/dist/nextjs/templates/app-loader/plasmic-init-client.js +73 -0
  148. package/dist/nextjs/templates/app-loader/plasmic-init.d.ts +1 -0
  149. package/dist/nextjs/templates/app-loader/plasmic-init.js +23 -0
  150. package/dist/nextjs/templates/pages-codegen/app.d.ts +2 -0
  151. package/dist/nextjs/templates/pages-codegen/app.js +20 -0
  152. package/dist/nextjs/templates/pages-codegen/plasmic-host.d.ts +1 -0
  153. package/dist/nextjs/templates/pages-codegen/plasmic-host.js +22 -0
  154. package/dist/nextjs/templates/pages-loader/catchall-page.d.ts +2 -0
  155. package/dist/nextjs/templates/pages-loader/catchall-page.js +77 -0
  156. package/dist/nextjs/templates/pages-loader/plasmic-host.d.ts +1 -0
  157. package/dist/nextjs/templates/pages-loader/plasmic-host.js +14 -0
  158. package/dist/nextjs/templates/pages-loader/plasmic-init.d.ts +1 -0
  159. package/dist/nextjs/templates/pages-loader/plasmic-init.js +32 -0
  160. package/dist/react/react.d.ts +2 -0
  161. package/dist/{strategies → react}/react.js +10 -10
  162. package/dist/templates/readme.d.ts +2 -2
  163. package/dist/templates/readme.js +5 -4
  164. package/dist/templates/welcomePage.d.ts +2 -2
  165. package/dist/templates/welcomePage.js +5 -5
  166. package/dist/{strategies/common.d.ts → utils/codegen.d.ts} +0 -0
  167. package/dist/{strategies/common.js → utils/codegen.js} +0 -0
  168. package/dist/utils/file-utils.d.ts +2 -2
  169. package/dist/utils/file-utils.js +3 -3
  170. package/dist/{strategies/types.d.ts → utils/strategy.d.ts} +16 -14
  171. package/dist/{strategies/types.js → utils/strategy.js} +0 -0
  172. package/dist/utils/types.d.ts +9 -0
  173. package/dist/utils/types.js +7 -0
  174. package/package.json +4 -3
  175. package/run-cpa.ts +151 -0
  176. package/src/{strategies → gatsby}/gatsby.ts +28 -46
  177. package/src/{templates/gatsby.ts → gatsby/template.ts} +41 -51
  178. package/src/index.ts +86 -56
  179. package/src/lib.ts +30 -15
  180. package/src/nextjs/nextjs.ts +180 -0
  181. package/src/nextjs/templates/app-loader/catchall-page.ts +71 -0
  182. package/src/nextjs/templates/app-loader/plasmic-host.ts +9 -0
  183. package/src/nextjs/templates/app-loader/plasmic-init-client.ts +74 -0
  184. package/src/nextjs/templates/app-loader/plasmic-init.ts +22 -0
  185. package/src/nextjs/templates/pages-codegen/app.ts +24 -0
  186. package/src/nextjs/templates/pages-codegen/plasmic-host.ts +18 -0
  187. package/src/nextjs/templates/pages-loader/catchall-page.ts +81 -0
  188. package/src/nextjs/templates/pages-loader/plasmic-host.ts +10 -0
  189. package/src/nextjs/templates/pages-loader/plasmic-init.ts +31 -0
  190. package/src/{strategies → react}/react.ts +8 -10
  191. package/src/templates/readme.ts +5 -5
  192. package/src/templates/welcomePage.ts +6 -7
  193. package/src/{strategies/common.ts → utils/codegen.ts} +0 -0
  194. package/src/utils/file-utils.ts +4 -4
  195. package/src/utils/strategy.ts +48 -0
  196. package/src/utils/types.ts +12 -0
  197. package/dist/strategies/gatsby.d.ts +0 -7
  198. package/dist/strategies/index.d.ts +0 -2
  199. package/dist/strategies/index.js +0 -22
  200. package/dist/strategies/nextjs.d.ts +0 -3
  201. package/dist/strategies/nextjs.js +0 -104
  202. package/dist/strategies/react.d.ts +0 -3
  203. package/dist/templates/gatsby.d.ts +0 -11
  204. package/dist/templates/nextjs.d.ts +0 -5
  205. package/dist/templates/nextjs.js +0 -162
  206. package/src/strategies/index.ts +0 -21
  207. package/src/strategies/nextjs.ts +0 -131
  208. package/src/strategies/types.ts +0 -42
  209. package/src/templates/nextjs.ts +0 -170
package/src/index.ts CHANGED
@@ -6,53 +6,58 @@ import inquirer, { DistinctQuestion } from "inquirer";
6
6
  import * as path from "upath";
7
7
  import yargs from "yargs";
8
8
  import * as cpa from "./lib";
9
- import { assert, ensure, ensureString } from "./utils/lang-utils";
9
+ import { ensure } from "./utils/lang-utils";
10
10
  import { checkEngineStrict, updateNotify } from "./utils/npm-utils";
11
+ import { PlatformOptions, PlatformType, SchemeType } from "./utils/types";
11
12
 
12
13
  if (process.env.CPA_DEBUG_CHDIR) {
13
14
  process.chdir(process.env.CPA_DEBUG_CHDIR);
14
15
  }
15
16
 
16
- export type CodeScheme = "codegen" | "loader";
17
-
18
17
  // Check for updates
19
18
  const createPlasmicAppVersion = updateNotify();
20
19
 
21
20
  // Specify command-line args
22
21
  const argv = yargs
23
- .usage("Usage: $0 [options] <project-directory>")
24
- .example([
25
- ["$0 my-plasmic-app", "--- Create the project in `my-plasmic-app/`"],
26
- ])
22
+ .command(
23
+ "$0 [projectName]",
24
+ "Create a Plasmic app with Next.js, Gatsby, or Create React App",
25
+ (yargs) => {
26
+ yargs
27
+ .usage("Usage: $0 [projectName] [options]")
28
+ .positional("projectName", {
29
+ describe: "Project and NPM package name",
30
+ string: true,
31
+ });
32
+ }
33
+ )
27
34
  .option("platform", {
28
35
  describe: "Target platform",
29
36
  choices: ["", "nextjs", "gatsby", "react"],
30
- default: "",
31
37
  })
32
38
  .option("scheme", {
33
39
  describe: "Plasmic integration scheme",
34
40
  choices: ["", "codegen", "loader"],
35
- default: "",
36
41
  })
37
42
  .option("projectId", {
38
43
  describe: "Plasmic project ID",
39
44
  string: true,
40
- default: "",
41
45
  })
42
46
  .option("projectApiToken", {
43
47
  describe: "Plasmic project API token (optional, to bypass standard auth)",
44
48
  string: true,
45
- default: "",
46
49
  })
47
50
  .option("template", {
48
51
  describe: "Specify a template for the created project",
49
52
  string: true,
50
- default: "",
51
53
  })
52
54
  .option("typescript", {
53
- describe: "Use the default Typescript template",
55
+ describe: "Use Typescript?",
56
+ boolean: true,
57
+ })
58
+ .option("appDir", {
59
+ describe: "(Next.js) Use app directory (experimental)?",
54
60
  boolean: true,
55
- default: "",
56
61
  })
57
62
  .strict()
58
63
  .help("h")
@@ -83,7 +88,12 @@ async function maybePrompt<T>(
83
88
 
84
89
  if (checkCliAnswer) {
85
90
  const cliAnswer = argv[name];
86
- if (cliAnswer !== null && cliAnswer !== undefined && cliAnswer !== "") {
91
+ if (
92
+ cliAnswer !== null &&
93
+ cliAnswer !== undefined &&
94
+ cliAnswer !== "" &&
95
+ (!question.validate || question.validate(cliAnswer))
96
+ ) {
87
97
  console.log(`${message}: ${cliAnswer} (specified in CLI arg)`);
88
98
  return cliAnswer as T; // assume it's the correct type
89
99
  }
@@ -94,7 +104,7 @@ async function maybePrompt<T>(
94
104
  }
95
105
 
96
106
  // Keeping these as globals to easily share with our `crash` function
97
- let projectName: string | undefined =
107
+ const projectName: string | undefined =
98
108
  argv._.length > 0 ? argv._[0] + "" : undefined;
99
109
  let resolvedProjectPath: string;
100
110
 
@@ -105,21 +115,18 @@ async function run(): Promise<void> {
105
115
  /**
106
116
  * PROMPT USER
107
117
  */
108
- // User-specified project path/directory
109
- while (!cpa.checkValidName(projectName)) {
110
- projectName = (
111
- await inquirer.prompt({
112
- name: "projectPath",
113
- message: "What is your project named?",
114
- default: "my-app",
115
- })
116
- ).projectPath.trim();
117
- }
118
+ // User-specified project name
119
+ const projectName = await maybePrompt({
120
+ name: "projectName",
121
+ message: "What is your project named?",
122
+ default: "my-app",
123
+ validate: cpa.checkValidName,
124
+ });
118
125
  // Absolute path to the new project
119
126
  resolvedProjectPath = path.resolve(projectName);
120
127
 
121
128
  // Prompt for Typescript
122
- const useTypescript: boolean = await maybePrompt({
129
+ const jsOrTs = (await maybePrompt({
123
130
  name: "typescript",
124
131
  message: "What language do you want to use?",
125
132
  type: "list",
@@ -134,35 +141,35 @@ async function run(): Promise<void> {
134
141
  },
135
142
  ],
136
143
  default: true,
137
- });
144
+ }))
145
+ ? "ts"
146
+ : "js";
138
147
 
139
148
  // Prompt for the platform
140
- const platform = ensureString(
141
- await maybePrompt<string>({
142
- name: "platform",
143
- message: "What React framework do you want to use?",
144
- type: "list",
145
- choices: () => [
146
- {
147
- name: "Next.js",
148
- value: "nextjs",
149
- },
150
- {
151
- name: "Gatsby",
152
- value: "gatsby",
153
- },
154
- {
155
- name: "Create React App",
156
- value: "react",
157
- },
158
- ],
159
- default: "nextjs",
160
- })
161
- );
149
+ const platform = await maybePrompt<PlatformType>({
150
+ name: "platform",
151
+ message: "What React framework do you want to use?",
152
+ type: "list",
153
+ choices: () => [
154
+ {
155
+ name: "Next.js",
156
+ value: "nextjs",
157
+ },
158
+ {
159
+ name: "Gatsby",
160
+ value: "gatsby",
161
+ },
162
+ {
163
+ name: "Create React App",
164
+ value: "react",
165
+ },
166
+ ],
167
+ default: "nextjs",
168
+ });
162
169
 
163
170
  // Scheme to use for Plasmic integration
164
171
  // - loader only available for gatsby/next.js
165
- const scheme: CodeScheme =
172
+ const scheme: SchemeType =
166
173
  platform === "nextjs" || platform === "gatsby"
167
174
  ? await maybePrompt({
168
175
  name: "scheme",
@@ -184,6 +191,32 @@ async function run(): Promise<void> {
184
191
  })
185
192
  : "codegen";
186
193
 
194
+ // TODO: Support nextjs + codegen
195
+ const platformOptions: PlatformOptions = {};
196
+ if (platform === "nextjs" && scheme === "loader") {
197
+ platformOptions.nextjs = {
198
+ appDir: await maybePrompt({
199
+ name: "appDir",
200
+ message:
201
+ "Do you want to use the app/ directory and React Server Components? (see https://beta.nextjs.org/docs/app-directory-roadmap)",
202
+ type: "list",
203
+ choices: () => [
204
+ {
205
+ name: "No, use pages/ directory",
206
+ short: "No",
207
+ value: false,
208
+ },
209
+ {
210
+ name: "Yes, use app/ directory (experimental)",
211
+ short: "Yes",
212
+ value: true,
213
+ },
214
+ ],
215
+ default: false,
216
+ }),
217
+ };
218
+ }
219
+
187
220
  // Get the projectId
188
221
  console.log();
189
222
  let projectId: string | undefined;
@@ -219,10 +252,6 @@ What is the URL of your project?`,
219
252
 
220
253
  // RUN IT
221
254
  console.log();
222
- assert(
223
- platform === "nextjs" || platform === "gatsby" || platform === "react",
224
- "platform must be one of ['nextjs', 'gatsby', 'react']"
225
- );
226
255
 
227
256
  const template = argv["template"];
228
257
  const projectApiToken = argv["projectApiToken"];
@@ -235,8 +264,9 @@ What is the URL of your project?`,
235
264
  resolvedProjectPath,
236
265
  projectId,
237
266
  platform,
267
+ platformOptions,
238
268
  scheme,
239
- useTypescript,
269
+ jsOrTs,
240
270
  projectApiToken,
241
271
  template,
242
272
  });
package/src/lib.ts CHANGED
@@ -2,23 +2,34 @@ import { auth, getProjectApiToken, setMetadataEnv } from "@plasmicapp/cli";
2
2
  import chalk from "chalk";
3
3
  import * as path from "upath";
4
4
  import validateProjectName from "validate-npm-package-name";
5
- import { getCPAStrategy } from "./strategies";
6
5
  import { ensureTsconfig, overwriteReadme } from "./utils/file-utils";
7
6
  import { detectPackageManager } from "./utils/npm-utils";
8
-
9
- export type PlatformType = "nextjs" | "gatsby" | "react";
10
- export type SchemeType = "codegen" | "loader";
11
-
12
- export function toString(s: PlatformType): string {
13
- return s === "nextjs" ? "Next.js" : s === "gatsby" ? "Gatsby" : "React";
7
+ import { CPAStrategy } from "./utils/strategy";
8
+ import {
9
+ JsOrTs,
10
+ PlatformOptions,
11
+ PlatformType,
12
+ SchemeType,
13
+ } from "./utils/types";
14
+
15
+ async function getCPAStrategy(platform: PlatformType): Promise<CPAStrategy> {
16
+ switch (platform) {
17
+ case "nextjs":
18
+ return (await import("./nextjs/nextjs")).nextjsStrategy;
19
+ case "gatsby":
20
+ return (await import("./gatsby/gatsby")).gatsbyStrategy;
21
+ case "react":
22
+ return (await import("./react/react")).reactStrategy;
23
+ }
14
24
  }
15
25
 
16
26
  export interface CreatePlasmicAppArgs {
17
27
  resolvedProjectPath: string;
18
28
  projectId: string;
19
29
  platform: PlatformType;
30
+ platformOptions: PlatformOptions;
20
31
  scheme: SchemeType;
21
- useTypescript: boolean;
32
+ jsOrTs: JsOrTs;
22
33
  projectApiToken?: string;
23
34
  template?: string;
24
35
  }
@@ -28,8 +39,9 @@ export async function create(args: CreatePlasmicAppArgs): Promise<void> {
28
39
  resolvedProjectPath,
29
40
  projectId,
30
41
  platform,
42
+ platformOptions,
31
43
  scheme,
32
- useTypescript,
44
+ jsOrTs,
33
45
  template,
34
46
  } = args;
35
47
  let { projectApiToken } = args;
@@ -68,19 +80,20 @@ export async function create(args: CreatePlasmicAppArgs): Promise<void> {
68
80
  throw new Error(`Unrecognized Plasmic scheme: ${scheme}`);
69
81
  }
70
82
 
71
- const cpaStrategy = getCPAStrategy(platform);
83
+ const cpaStrategy = await getCPAStrategy(platform);
72
84
 
73
85
  // Create project using strategy for platform
74
86
  await cpaStrategy.create({
75
87
  projectPath: resolvedProjectPath,
76
- useTypescript,
88
+ jsOrTs,
77
89
  template,
90
+ platformOptions,
78
91
  });
79
92
 
80
93
  // Ensure that we have a empty tsconfig and @types packages.
81
94
  // Gatsby and Next.js by default support typescript handling internally
82
95
  // tsconfig so we don't have to ensure it.
83
- if (useTypescript && platform === "react") {
96
+ if (jsOrTs === "ts" && platform === "react") {
84
97
  await ensureTsconfig(resolvedProjectPath);
85
98
  }
86
99
 
@@ -97,7 +110,7 @@ export async function create(args: CreatePlasmicAppArgs): Promise<void> {
97
110
  const installResult = await cpaStrategy.installDeps({
98
111
  scheme,
99
112
  projectPath: resolvedProjectPath,
100
- useTypescript,
113
+ jsOrTs,
101
114
  });
102
115
 
103
116
  if (!installResult) {
@@ -109,17 +122,19 @@ export async function create(args: CreatePlasmicAppArgs): Promise<void> {
109
122
  projectId,
110
123
  projectPath: resolvedProjectPath,
111
124
  projectApiToken,
112
- useTypescript,
125
+ jsOrTs,
113
126
  scheme,
127
+ platformOptions,
114
128
  });
115
129
 
116
130
  // Generate files
117
131
  await cpaStrategy.generateFiles({
118
132
  projectPath: resolvedProjectPath,
119
- useTypescript,
133
+ jsOrTs,
120
134
  scheme,
121
135
  projectId,
122
136
  projectApiToken,
137
+ platformOptions,
123
138
  });
124
139
 
125
140
  /**
@@ -0,0 +1,180 @@
1
+ import { promises as fs } from "fs";
2
+ import path from "path";
3
+ import { spawnOrFail } from "../utils/cmd-utils";
4
+ import { installCodegenDeps, runCodegenSync } from "../utils/codegen";
5
+ import { deleteGlob, overwriteIndex } from "../utils/file-utils";
6
+ import { ensure } from "../utils/lang-utils";
7
+ import { installUpgrade } from "../utils/npm-utils";
8
+ import { CPAStrategy, GenerateFilesArgs } from "../utils/strategy";
9
+ import { makeCatchallPage_app_loader } from "./templates/app-loader/catchall-page";
10
+ import { makePlasmicInit_app_loader } from "./templates/app-loader/plasmic-init";
11
+ import { makePlasmicInitClient_app_loader } from "./templates/app-loader/plasmic-init-client";
12
+ import { makeCustomApp_pages_codegen } from "./templates/pages-codegen/app";
13
+ import { makePlasmicHostPage_pages_codegen } from "./templates/pages-codegen/plasmic-host";
14
+ import { makeCatchallPage_pages_loader } from "./templates/pages-loader/catchall-page";
15
+ import { makePlasmicHostPage_app_loader } from "./templates/app-loader/plasmic-host";
16
+ import { makePlasmicHostPage_pages_loader } from "./templates/pages-loader/plasmic-host";
17
+ import { makePlasmicInit_pages_loader } from "./templates/pages-loader/plasmic-init";
18
+
19
+ export const nextjsStrategy: CPAStrategy = {
20
+ create: async (args) => {
21
+ const { projectPath, template, jsOrTs, platformOptions } = args;
22
+ const typescriptArg = `--${jsOrTs}`;
23
+ const experimentalAppArg = platformOptions.nextjs?.appDir
24
+ ? "--experimental-app"
25
+ : "--no-experimental-app";
26
+ const templateArg = template ? ` --template ${template}` : "";
27
+ const createCommand =
28
+ `npx create-next-app@latest ${typescriptArg} ${experimentalAppArg} ${templateArg}` +
29
+ ` --eslint --no-src-dir --import-alias "@/*" ${projectPath}`;
30
+
31
+ // Default Next.js starter already supports Typescript
32
+ // See where we `touch tsconfig.json` later on
33
+ await spawnOrFail(createCommand);
34
+ },
35
+ installDeps: async ({ scheme, projectPath }) => {
36
+ if (scheme === "loader") {
37
+ return await installUpgrade("@plasmicapp/loader-nextjs", {
38
+ workingDir: projectPath,
39
+ });
40
+ } else {
41
+ return await installCodegenDeps({ projectPath });
42
+ }
43
+ },
44
+ overwriteConfig: async (args) => {
45
+ const { projectPath, scheme, platformOptions } = args;
46
+ const nextjsConfigFile = path.join(projectPath, "next.config.js");
47
+ const appDirOption = platformOptions.nextjs?.appDir
48
+ ? `
49
+ experimental: {
50
+ appDir: true,
51
+ }`
52
+ : "";
53
+ if (scheme === "codegen") {
54
+ await fs.writeFile(
55
+ nextjsConfigFile,
56
+ `
57
+ /** @type {import('next').NextConfig} */
58
+ const nextConfig = {
59
+ eslint: {
60
+ ignoreDuringBuilds: true,
61
+ },
62
+ trailingSlash: true,${appDirOption}
63
+ };
64
+
65
+ module.exports = nextConfig;`
66
+ );
67
+ } else {
68
+ await fs.writeFile(
69
+ nextjsConfigFile,
70
+ `
71
+ /** @type {import('next').NextConfig} */
72
+ const nextConfig = {
73
+ // Turn off React StrictMode for now, as react-aria (used by Plasmic)
74
+ // has some troubles with it. See
75
+ // https://github.com/adobe/react-spectrum/labels/strict%20mode
76
+ reactStrictMode: false,${appDirOption}
77
+ };
78
+
79
+ module.exports = nextConfig;`
80
+ );
81
+ }
82
+ },
83
+ generateFiles: (args) => {
84
+ if (args.platformOptions.nextjs?.appDir) {
85
+ return generateFilesAppDir(args);
86
+ } else {
87
+ return generateFilesPagesDir(args);
88
+ }
89
+ },
90
+ build: async (args) => {
91
+ const { npmRunCmd, projectPath } = args;
92
+ await spawnOrFail(`${npmRunCmd} build`, projectPath);
93
+ },
94
+ };
95
+
96
+ async function generateFilesAppDir(args: GenerateFilesArgs) {
97
+ const { projectPath, jsOrTs, projectId, projectApiToken } = args;
98
+
99
+ // Delete existing pages
100
+ deleteGlob(path.join(projectPath, "app", "page.*"));
101
+
102
+ // ./plasmic-init.ts
103
+ await fs.writeFile(
104
+ path.join(projectPath, `plasmic-init.${jsOrTs}`),
105
+ makePlasmicInit_app_loader(projectId, ensure(projectApiToken))
106
+ );
107
+
108
+ // ./plasmic-init-client.ts
109
+ await fs.writeFile(
110
+ path.join(projectPath, `plasmic-init-client.${jsOrTs}x`),
111
+ makePlasmicInitClient_app_loader(jsOrTs)
112
+ );
113
+
114
+ // ./app/plasmic-host/page.tsx
115
+ await fs.mkdir(path.join(projectPath, "app", "plasmic-host"));
116
+ await fs.writeFile(
117
+ path.join(projectPath, "app", "plasmic-host", `page.${jsOrTs}x`),
118
+ makePlasmicHostPage_app_loader()
119
+ );
120
+
121
+ // ./app/[[...catchall]]/page.tsx
122
+ await fs.mkdir(path.join(projectPath, "app", "[[...catchall]]"));
123
+ await fs.writeFile(
124
+ path.join(projectPath, "app", "[[...catchall]]", `page.${jsOrTs}x`),
125
+ makeCatchallPage_app_loader(jsOrTs)
126
+ );
127
+ }
128
+
129
+ async function generateFilesPagesDir(args: GenerateFilesArgs) {
130
+ const { projectPath, scheme, jsOrTs, projectId, projectApiToken } = args;
131
+
132
+ // Delete existing pages
133
+ deleteGlob(path.join(projectPath, "pages", "*.*"));
134
+
135
+ if (scheme === "loader") {
136
+ // ./plasmic-init.ts
137
+ await fs.writeFile(
138
+ path.join(projectPath, `plasmic-init.${jsOrTs}`),
139
+ makePlasmicInit_pages_loader(projectId, ensure(projectApiToken))
140
+ );
141
+
142
+ // ./pages/plasmic-host.tsx
143
+ await fs.writeFile(
144
+ path.join(projectPath, "pages", `plasmic-host.${jsOrTs}x`),
145
+ makePlasmicHostPage_pages_loader()
146
+ );
147
+
148
+ // ./pages/[[...catchall]].tsx
149
+ await fs.writeFile(
150
+ path.join(projectPath, "pages", `[[...catchall]].${jsOrTs}x`),
151
+ makeCatchallPage_pages_loader(jsOrTs)
152
+ );
153
+ } else {
154
+ // ./pages/_app.tsx
155
+ await fs.writeFile(
156
+ path.join(projectPath, "pages", `_app.${jsOrTs}x`),
157
+ makeCustomApp_pages_codegen(jsOrTs)
158
+ );
159
+
160
+ // ./pages/plasmic-host.tsx
161
+ await fs.writeFile(
162
+ path.join(projectPath, "pages", `plasmic-host.${jsOrTs}x`),
163
+ makePlasmicHostPage_pages_codegen()
164
+ );
165
+
166
+ // This should generate
167
+ // ./plasmic.json
168
+ // ./pages/index.tsx
169
+ // ./components/plasmic/**
170
+ await runCodegenSync({
171
+ projectId,
172
+ projectApiToken,
173
+ projectPath,
174
+ });
175
+
176
+ // This should overwrite
177
+ // ./pages/index.tsx
178
+ await overwriteIndex(projectPath, "nextjs", scheme);
179
+ }
180
+ }
@@ -0,0 +1,71 @@
1
+ import { ifTs } from "../../../utils/file-utils";
2
+ import { JsOrTs } from "../../../utils/types";
3
+
4
+ export function makeCatchallPage_app_loader(jsOrTs: JsOrTs): string {
5
+ return `import { PlasmicComponent } from "@plasmicapp/loader-nextjs";
6
+ import { notFound } from "next/navigation";
7
+ import { PLASMIC } from "plasmic-init";
8
+ import { ClientPlasmicRootProvider } from "plasmic-init-client";
9
+
10
+ // Use revalidate if you want incremental static regeneration
11
+ export const revalidate = 60;
12
+
13
+ export default async function PlasmicLoaderPage({
14
+ params,
15
+ searchParams,
16
+ }${ifTs(
17
+ jsOrTs,
18
+ `: {
19
+ params?: { catchall: string[] | undefined };
20
+ searchParams?: Record<string, string | string[]>;
21
+ }`
22
+ )}) {
23
+ const plasmicComponentData = await fetchPlasmicComponentData(params?.catchall);
24
+ if (!plasmicComponentData) {
25
+ notFound();
26
+ }
27
+
28
+ const { prefetchedData } = plasmicComponentData;
29
+ if (prefetchedData.entryCompMetas.length === 0) {
30
+ notFound();
31
+ }
32
+
33
+ const pageMeta = prefetchedData.entryCompMetas[0];
34
+ return (
35
+ <ClientPlasmicRootProvider
36
+ prefetchedData={prefetchedData}
37
+ pageParams={pageMeta.params}
38
+ pageQuery={searchParams}
39
+ >
40
+ <PlasmicComponent
41
+ component={pageMeta.displayName}
42
+ />
43
+ </ClientPlasmicRootProvider>
44
+ );
45
+ }
46
+
47
+ async function fetchPlasmicComponentData(catchall${ifTs(
48
+ jsOrTs,
49
+ ": string[] | undefined"
50
+ )}) {
51
+ const plasmicPath = "/" + (catchall ? catchall.join("/") : "");
52
+ const prefetchedData = await PLASMIC.maybeFetchComponentData(plasmicPath);
53
+ if (!prefetchedData) {
54
+ notFound();
55
+ }
56
+
57
+ return { prefetchedData };
58
+ }
59
+
60
+ export async function generateStaticParams() {
61
+ const pageModules = await PLASMIC.fetchPages();
62
+ return pageModules.map((mod) => {
63
+ const catchall =
64
+ mod.path === "/" ? undefined : mod.path.substring(1).split("/");
65
+ return {
66
+ catchall,
67
+ };
68
+ });
69
+ }
70
+ `;
71
+ }
@@ -0,0 +1,9 @@
1
+ export function makePlasmicHostPage_app_loader(): string {
2
+ return `import { PlasmicCanvasHost } from "@plasmicapp/loader-nextjs";
3
+ import "plasmic-init-client";
4
+
5
+ export default function PlasmicHost() {
6
+ return <PlasmicCanvasHost />;
7
+ }
8
+ `;
9
+ }
@@ -0,0 +1,74 @@
1
+ import { ifTs } from "../../../utils/file-utils";
2
+ import { JsOrTs } from "../../../utils/types";
3
+
4
+ export function makePlasmicInitClient_app_loader(jsOrTs: JsOrTs): string {
5
+ return `"use client";
6
+
7
+ import { PlasmicRootProvider } from "@plasmicapp/loader-nextjs";
8
+ import { PLASMIC } from "plasmic-init";
9
+
10
+ // You can register any code components that you want to use here; see
11
+ // https://docs.plasmic.app/learn/code-components-ref/
12
+ // And configure your Plasmic project to use the host url pointing at
13
+ // the /plasmic-host page of your nextjs app (for example,
14
+ // http://localhost:3000/plasmic-host). See
15
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
16
+
17
+ // PLASMIC.registerComponent(...);
18
+
19
+ /**
20
+ * ClientPlasmicRootProvider is a Client Component that passes in the loader for you.
21
+ *
22
+ * Why? Props passed from Server to Client Components must be serializable.
23
+ * https://beta.nextjs.org/docs/rendering/server-and-client-components#passing-props-from-server-to-client-components-serialization
24
+ * However, PlasmicRootProvider requires a loader, but the loader is NOT serializable.
25
+ *
26
+ * In a Server Component like app/<your-path>/path.tsx, rendering the following would not work:
27
+ *
28
+ * \`\`\`tsx
29
+ * import { PLASMIC } from "plasmic-init";
30
+ * import { PlasmicRootProvider } from "plasmicapp/loader-nextjs";
31
+ * export default function MyPage() {
32
+ * const prefetchedData = await PLASMIC.fetchComponentData("YourPage");
33
+ * return (
34
+ * <PlasmicRootProvider
35
+ * loader={PLASMIC} // ERROR: loader is not serializable
36
+ * prefetchedData={prefetchedData}
37
+ * >
38
+ * {yourContent()}
39
+ * </PlasmicRootProvider>;
40
+ * );
41
+ * }
42
+ * \`\`\`
43
+ *
44
+ * Therefore, we define ClientPlasmicRootProvider as a Client Component (this file is marked "use client").
45
+ * ClientPlasmicRootProvider wraps the PlasmicRootProvider and passes in the loader for you,
46
+ * while allowing your Server Component to pass in prefetched data and other serializable props:
47
+ *
48
+ * \`\`\`tsx
49
+ * import { PLASMIC } from "plasmic-init";
50
+ * import { ClientPlasmicRootProvider } from "plasmic-init-client"; // changed
51
+ * export default function MyPage() {
52
+ * const prefetchedData = await PLASMIC.fetchComponentData("YourPage");
53
+ * return (
54
+ * <ClientPlasmicRootProvider // don't pass in loader
55
+ * prefetchedData={prefetchedData}
56
+ * >
57
+ * {yourContent()}
58
+ * </ClientPlasmicRootProvider>;
59
+ * );
60
+ * }
61
+ * \`\`\`
62
+ */
63
+ export function ClientPlasmicRootProvider(
64
+ props${ifTs(
65
+ jsOrTs,
66
+ ': Omit<React.ComponentProps<typeof PlasmicRootProvider>, "loader">'
67
+ )}
68
+ ) {
69
+ return (
70
+ <PlasmicRootProvider loader={PLASMIC} {...props}></PlasmicRootProvider>
71
+ );
72
+ }
73
+ `;
74
+ }