@cedarjs/cli 0.0.4

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 (360) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +706 -0
  3. package/dist/commands/build.js +54 -0
  4. package/dist/commands/buildHandler.js +134 -0
  5. package/dist/commands/check.js +28 -0
  6. package/dist/commands/console.js +13 -0
  7. package/dist/commands/consoleHandler.js +68 -0
  8. package/dist/commands/deploy/baremetal/SshExecutor.js +41 -0
  9. package/dist/commands/deploy/baremetal/baremetalHandler.js +558 -0
  10. package/dist/commands/deploy/baremetal.js +89 -0
  11. package/dist/commands/deploy/flightcontrol.js +40 -0
  12. package/dist/commands/deploy/flightcontrolHandler.js +58 -0
  13. package/dist/commands/deploy/helpers/deployBuilder.js +25 -0
  14. package/dist/commands/deploy/helpers/deployHandler.js +31 -0
  15. package/dist/commands/deploy/netlify.js +21 -0
  16. package/dist/commands/deploy/packing/nft.js +61 -0
  17. package/dist/commands/deploy/render.js +37 -0
  18. package/dist/commands/deploy/renderHandler.js +70 -0
  19. package/dist/commands/deploy/serverless.js +51 -0
  20. package/dist/commands/deploy/serverlessHandler.js +211 -0
  21. package/dist/commands/deploy/vercel.js +21 -0
  22. package/dist/commands/deploy.js +21 -0
  23. package/dist/commands/destroy/cell/cell.js +12 -0
  24. package/dist/commands/destroy/cell/cellHandler.js +10 -0
  25. package/dist/commands/destroy/component/component.js +15 -0
  26. package/dist/commands/destroy/component/componentHandler.js +10 -0
  27. package/dist/commands/destroy/directive/directive.js +14 -0
  28. package/dist/commands/destroy/directive/directiveHandler.js +12 -0
  29. package/dist/commands/destroy/function/function.js +20 -0
  30. package/dist/commands/destroy/function/functionHandler.js +10 -0
  31. package/dist/commands/destroy/handlerHelpers.js +34 -0
  32. package/dist/commands/destroy/helpers.js +22 -0
  33. package/dist/commands/destroy/layout/layout.js +12 -0
  34. package/dist/commands/destroy/layout/layoutHandler.js +10 -0
  35. package/dist/commands/destroy/page/page.js +20 -0
  36. package/dist/commands/destroy/page/pageHandler.js +51 -0
  37. package/dist/commands/destroy/scaffold/scaffold.js +16 -0
  38. package/dist/commands/destroy/scaffold/scaffoldHandler.js +105 -0
  39. package/dist/commands/destroy/sdl/sdl.js +16 -0
  40. package/dist/commands/destroy/sdl/sdlHandler.js +33 -0
  41. package/dist/commands/destroy/service/service.js +10 -0
  42. package/dist/commands/destroy/service/serviceHandler.js +17 -0
  43. package/dist/commands/destroy.js +25 -0
  44. package/dist/commands/dev.js +47 -0
  45. package/dist/commands/devHandler.js +202 -0
  46. package/dist/commands/exec.js +38 -0
  47. package/dist/commands/execHandler.js +180 -0
  48. package/dist/commands/experimental/setupInngest.js +28 -0
  49. package/dist/commands/experimental/setupInngestHandler.js +46 -0
  50. package/dist/commands/experimental/setupOpentelemetry.js +34 -0
  51. package/dist/commands/experimental/setupOpentelemetryHandler.js +215 -0
  52. package/dist/commands/experimental/setupReactCompiler.js +28 -0
  53. package/dist/commands/experimental/setupReactCompilerHandler.js +124 -0
  54. package/dist/commands/experimental/setupRsc.js +28 -0
  55. package/dist/commands/experimental/setupRscHandler.js +408 -0
  56. package/dist/commands/experimental/setupStreamingSsr.js +28 -0
  57. package/dist/commands/experimental/setupStreamingSsrHandler.js +208 -0
  58. package/dist/commands/experimental/templates/opentelemetry.ts.template +55 -0
  59. package/dist/commands/experimental/templates/rsc/AboutCounter.tsx.template +20 -0
  60. package/dist/commands/experimental/templates/rsc/AboutPage.css.template +2 -0
  61. package/dist/commands/experimental/templates/rsc/AboutPage.tsx.template +17 -0
  62. package/dist/commands/experimental/templates/rsc/Counter.css.template +7 -0
  63. package/dist/commands/experimental/templates/rsc/Counter.module.css.template +3 -0
  64. package/dist/commands/experimental/templates/rsc/Counter.tsx.template +18 -0
  65. package/dist/commands/experimental/templates/rsc/Document.tsx.template +27 -0
  66. package/dist/commands/experimental/templates/rsc/HomePage.css.template +2 -0
  67. package/dist/commands/experimental/templates/rsc/HomePage.module.css.template +3 -0
  68. package/dist/commands/experimental/templates/rsc/HomePage.tsx.template +19 -0
  69. package/dist/commands/experimental/templates/rsc/NavigationLayout.css.template +32 -0
  70. package/dist/commands/experimental/templates/rsc/NavigationLayout.tsx.template +31 -0
  71. package/dist/commands/experimental/templates/rsc/Routes.tsx.template +29 -0
  72. package/dist/commands/experimental/templates/rsc/entry.client.tsx.template +35 -0
  73. package/dist/commands/experimental/templates/rsc/entry.server.tsx.template +20 -0
  74. package/dist/commands/experimental/templates/rsc/index.css.template +4 -0
  75. package/dist/commands/experimental/templates/streamingSsr/Document.tsx.template +27 -0
  76. package/dist/commands/experimental/templates/streamingSsr/entry.client.tsx.template +40 -0
  77. package/dist/commands/experimental/templates/streamingSsr/entry.server.tsx.template +20 -0
  78. package/dist/commands/experimental/templates/streamingSsr/tsconfig.json.template +54 -0
  79. package/dist/commands/experimental/util.js +69 -0
  80. package/dist/commands/experimental.js +22 -0
  81. package/dist/commands/generate/cell/cell.js +35 -0
  82. package/dist/commands/generate/cell/cellHandler.js +153 -0
  83. package/dist/commands/generate/cell/templates/cell.tsx.template +34 -0
  84. package/dist/commands/generate/cell/templates/cellList.tsx.template +40 -0
  85. package/dist/commands/generate/cell/templates/mock.ts.template +7 -0
  86. package/dist/commands/generate/cell/templates/mockList.ts.template +14 -0
  87. package/dist/commands/generate/cell/templates/stories.tsx.template +35 -0
  88. package/dist/commands/generate/cell/templates/test.js.template +42 -0
  89. package/dist/commands/generate/cell/utils/utils.js +43 -0
  90. package/dist/commands/generate/component/component.js +15 -0
  91. package/dist/commands/generate/component/componentHandler.js +55 -0
  92. package/dist/commands/generate/component/templates/component.tsx.template +10 -0
  93. package/dist/commands/generate/component/templates/stories.jsx.template +17 -0
  94. package/dist/commands/generate/component/templates/stories.tsx.template +26 -0
  95. package/dist/commands/generate/component/templates/test.tsx.template +14 -0
  96. package/dist/commands/generate/dataMigration/dataMigration.js +105 -0
  97. package/dist/commands/generate/dataMigration/templates/dataMigration.js.template +7 -0
  98. package/dist/commands/generate/dataMigration/templates/dataMigration.ts.template +5 -0
  99. package/dist/commands/generate/dbAuth/dbAuth.js +55 -0
  100. package/dist/commands/generate/dbAuth/dbAuthHandler.js +375 -0
  101. package/dist/commands/generate/dbAuth/templates/forgotPassword.tsx.template +94 -0
  102. package/dist/commands/generate/dbAuth/templates/login.tsx.template +130 -0
  103. package/dist/commands/generate/dbAuth/templates/login.webAuthn.tsx.template +264 -0
  104. package/dist/commands/generate/dbAuth/templates/resetPassword.tsx.template +121 -0
  105. package/dist/commands/generate/dbAuth/templates/signup.tsx.template +123 -0
  106. package/dist/commands/generate/directive/directive.js +15 -0
  107. package/dist/commands/generate/directive/directiveHandler.js +159 -0
  108. package/dist/commands/generate/directive/templates/transformer.directive.test.ts.template +18 -0
  109. package/dist/commands/generate/directive/templates/transformer.directive.ts.template +38 -0
  110. package/dist/commands/generate/directive/templates/validator.directive.test.ts.template +17 -0
  111. package/dist/commands/generate/directive/templates/validator.directive.ts.template +39 -0
  112. package/dist/commands/generate/function/function.js +29 -0
  113. package/dist/commands/generate/function/functionHandler.js +131 -0
  114. package/dist/commands/generate/function/templates/function.ts.template +33 -0
  115. package/dist/commands/generate/function/templates/scenarios.ts.template +8 -0
  116. package/dist/commands/generate/function/templates/test.ts.template +30 -0
  117. package/dist/commands/generate/helpers.js +71 -0
  118. package/dist/commands/generate/job/job.js +39 -0
  119. package/dist/commands/generate/job/jobHandler.js +138 -0
  120. package/dist/commands/generate/job/templates/job.ts.template +8 -0
  121. package/dist/commands/generate/job/templates/scenarios.ts.template +8 -0
  122. package/dist/commands/generate/job/templates/test.ts.template +7 -0
  123. package/dist/commands/generate/layout/layout.js +25 -0
  124. package/dist/commands/generate/layout/layoutHandler.js +59 -0
  125. package/dist/commands/generate/layout/templates/layout.tsx.a11y.template +27 -0
  126. package/dist/commands/generate/layout/templates/layout.tsx.template +9 -0
  127. package/dist/commands/generate/layout/templates/stories.tsx.template +13 -0
  128. package/dist/commands/generate/layout/templates/test.tsx.template +14 -0
  129. package/dist/commands/generate/model/model.js +29 -0
  130. package/dist/commands/generate/model/modelHandler.js +63 -0
  131. package/dist/commands/generate/model/templates/model.js.template +3 -0
  132. package/dist/commands/generate/ogImage/ogImage.js +43 -0
  133. package/dist/commands/generate/ogImage/ogImageHandler.js +111 -0
  134. package/dist/commands/generate/ogImage/templates/ogImage.og.tsx.template +13 -0
  135. package/dist/commands/generate/page/page.js +22 -0
  136. package/dist/commands/generate/page/pageHandler.js +227 -0
  137. package/dist/commands/generate/page/templates/page.tsx.template +35 -0
  138. package/dist/commands/generate/page/templates/stories.tsx.parameters.template +13 -0
  139. package/dist/commands/generate/page/templates/stories.tsx.template +13 -0
  140. package/dist/commands/generate/page/templates/test.tsx.template +14 -0
  141. package/dist/commands/generate/realtime/realtime.js +41 -0
  142. package/dist/commands/generate/realtime/realtimeHandler.js +215 -0
  143. package/dist/commands/generate/realtime/templates/liveQueries/blank/blank.sdl.ts.template +27 -0
  144. package/dist/commands/generate/realtime/templates/liveQueries/blank/blank.service.ts.template +73 -0
  145. package/dist/commands/generate/realtime/templates/realtime.ts.template +42 -0
  146. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.sdl.ts.template +20 -0
  147. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.service.ts.template +19 -0
  148. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +58 -0
  149. package/dist/commands/generate/scaffold/scaffold.js +38 -0
  150. package/dist/commands/generate/scaffold/scaffoldHandler.js +663 -0
  151. package/dist/commands/generate/scaffold/templates/assets/scaffold.css.template +398 -0
  152. package/dist/commands/generate/scaffold/templates/assets/scaffold.tailwind.css.template +243 -0
  153. package/dist/commands/generate/scaffold/templates/components/EditNameCell.tsx.template +74 -0
  154. package/dist/commands/generate/scaffold/templates/components/Name.tsx.template +79 -0
  155. package/dist/commands/generate/scaffold/templates/components/NameCell.tsx.template +32 -0
  156. package/dist/commands/generate/scaffold/templates/components/NameForm.tsx.template +123 -0
  157. package/dist/commands/generate/scaffold/templates/components/Names.tsx.template +88 -0
  158. package/dist/commands/generate/scaffold/templates/components/NamesCell.tsx.template +45 -0
  159. package/dist/commands/generate/scaffold/templates/components/NewName.tsx.template +55 -0
  160. package/dist/commands/generate/scaffold/templates/layouts/ScaffoldLayout.tsx.template +37 -0
  161. package/dist/commands/generate/scaffold/templates/lib/formatters.test.tsx.template +192 -0
  162. package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +58 -0
  163. package/dist/commands/generate/scaffold/templates/pages/EditNamePage.tsx.template +11 -0
  164. package/dist/commands/generate/scaffold/templates/pages/NamePage.tsx.template +11 -0
  165. package/dist/commands/generate/scaffold/templates/pages/NamesPage.tsx.template +7 -0
  166. package/dist/commands/generate/scaffold/templates/pages/NewNamePage.tsx.template +7 -0
  167. package/dist/commands/generate/script/script.js +29 -0
  168. package/dist/commands/generate/script/scriptHandler.js +85 -0
  169. package/dist/commands/generate/script/templates/script.ts.template +15 -0
  170. package/dist/commands/generate/script/templates/tsconfig.json.template +33 -0
  171. package/dist/commands/generate/sdl/sdl.js +48 -0
  172. package/dist/commands/generate/sdl/sdlHandler.js +282 -0
  173. package/dist/commands/generate/sdl/templates/sdl.js.template +70 -0
  174. package/dist/commands/generate/sdl/templates/sdl.ts.template +70 -0
  175. package/dist/commands/generate/secret/secret.js +52 -0
  176. package/dist/commands/generate/service/service.js +50 -0
  177. package/dist/commands/generate/service/serviceHandler.js +301 -0
  178. package/dist/commands/generate/service/templates/scenarios.ts.template +7 -0
  179. package/dist/commands/generate/service/templates/service.ts.template +38 -0
  180. package/dist/commands/generate/service/templates/test.ts.template +84 -0
  181. package/dist/commands/generate/yargsCommandHelpers.js +77 -0
  182. package/dist/commands/generate/yargsHandlerHelpers.js +155 -0
  183. package/dist/commands/generate.js +44 -0
  184. package/dist/commands/info.js +36 -0
  185. package/dist/commands/jobs.js +17 -0
  186. package/dist/commands/jobsHandler.js +30 -0
  187. package/dist/commands/lint.js +57 -0
  188. package/dist/commands/prerender.js +34 -0
  189. package/dist/commands/prerenderHandler.js +282 -0
  190. package/dist/commands/prisma.js +17 -0
  191. package/dist/commands/prismaHandler.js +90 -0
  192. package/dist/commands/record/init.js +11 -0
  193. package/dist/commands/record.js +19 -0
  194. package/dist/commands/serve.js +139 -0
  195. package/dist/commands/serveApiHandler.js +15 -0
  196. package/dist/commands/serveBothHandler.js +95 -0
  197. package/dist/commands/serveWebHandler.js +17 -0
  198. package/dist/commands/setup/auth/auth.js +265 -0
  199. package/dist/commands/setup/cache/cache.js +37 -0
  200. package/dist/commands/setup/cache/cacheHandler.js +69 -0
  201. package/dist/commands/setup/cache/templates/memcached.ts.template +30 -0
  202. package/dist/commands/setup/cache/templates/redis.ts.template +24 -0
  203. package/dist/commands/setup/deploy/deploy.js +26 -0
  204. package/dist/commands/setup/deploy/helpers/helpers.js +9 -0
  205. package/dist/commands/setup/deploy/helpers/index.js +110 -0
  206. package/dist/commands/setup/deploy/providers/baremetal.js +9 -0
  207. package/dist/commands/setup/deploy/providers/baremetalHandler.js +64 -0
  208. package/dist/commands/setup/deploy/providers/coherence.js +24 -0
  209. package/dist/commands/setup/deploy/providers/coherenceHandler.js +203 -0
  210. package/dist/commands/setup/deploy/providers/flightcontrol.js +19 -0
  211. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +294 -0
  212. package/dist/commands/setup/deploy/providers/netlify.js +9 -0
  213. package/dist/commands/setup/deploy/providers/netlifyHandler.js +42 -0
  214. package/dist/commands/setup/deploy/providers/render.js +17 -0
  215. package/dist/commands/setup/deploy/providers/renderHandler.js +111 -0
  216. package/dist/commands/setup/deploy/providers/serverless.js +11 -0
  217. package/dist/commands/setup/deploy/providers/serverlessHandler.js +141 -0
  218. package/dist/commands/setup/deploy/providers/vercel.js +9 -0
  219. package/dist/commands/setup/deploy/providers/vercelHandler.js +56 -0
  220. package/dist/commands/setup/deploy/templates/baremetal.js +128 -0
  221. package/dist/commands/setup/deploy/templates/flightcontrol.js +85 -0
  222. package/dist/commands/setup/deploy/templates/netlify.js +32 -0
  223. package/dist/commands/setup/deploy/templates/render.js +72 -0
  224. package/dist/commands/setup/deploy/templates/serverless/api.js +78 -0
  225. package/dist/commands/setup/deploy/templates/serverless/web.js +32 -0
  226. package/dist/commands/setup/docker/docker.js +26 -0
  227. package/dist/commands/setup/docker/dockerHandler.js +265 -0
  228. package/dist/commands/setup/docker/templates/Dockerfile +154 -0
  229. package/dist/commands/setup/docker/templates/docker-compose.dev.yml +58 -0
  230. package/dist/commands/setup/docker/templates/docker-compose.prod.yml +63 -0
  231. package/dist/commands/setup/docker/templates/dockerignore +18 -0
  232. package/dist/commands/setup/generator/generator.js +49 -0
  233. package/dist/commands/setup/generator/generatorHandler.js +55 -0
  234. package/dist/commands/setup/graphql/features/fragments/appGqlConfigTransform.js +117 -0
  235. package/dist/commands/setup/graphql/features/fragments/appImportTransform.js +20 -0
  236. package/dist/commands/setup/graphql/features/fragments/fragments.js +25 -0
  237. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +89 -0
  238. package/dist/commands/setup/graphql/features/trustedDocuments/graphqlTransform.js +51 -0
  239. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +25 -0
  240. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +74 -0
  241. package/dist/commands/setup/graphql/graphql.js +18 -0
  242. package/dist/commands/setup/i18n/i18n.js +25 -0
  243. package/dist/commands/setup/i18n/i18nHandler.js +169 -0
  244. package/dist/commands/setup/i18n/templates/en.json.template +11 -0
  245. package/dist/commands/setup/i18n/templates/fr.json.template +11 -0
  246. package/dist/commands/setup/i18n/templates/i18n.js.template +52 -0
  247. package/dist/commands/setup/i18n/templates/storybook.preview.tsx.template +43 -0
  248. package/dist/commands/setup/jobs/jobs.js +31 -0
  249. package/dist/commands/setup/jobs/jobsHandler.js +122 -0
  250. package/dist/commands/setup/jobs/templates/jobs.ts.template +32 -0
  251. package/dist/commands/setup/mailer/mailer.js +30 -0
  252. package/dist/commands/setup/mailer/mailerHandler.js +106 -0
  253. package/dist/commands/setup/mailer/templates/mailer.ts.template +30 -0
  254. package/dist/commands/setup/mailer/templates/re-example.tsx.template +40 -0
  255. package/dist/commands/setup/middleware/middleware.js +17 -0
  256. package/dist/commands/setup/middleware/ogImage/__codemod_tests__/middleware.js +15 -0
  257. package/dist/commands/setup/middleware/ogImage/__codemod_tests__/vitePlugin.js +6 -0
  258. package/dist/commands/setup/middleware/ogImage/codemodMiddleware.js +97 -0
  259. package/dist/commands/setup/middleware/ogImage/codemodVitePlugin.js +65 -0
  260. package/dist/commands/setup/middleware/ogImage/ogImage.js +27 -0
  261. package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +121 -0
  262. package/dist/commands/setup/monitoring/monitoring.js +17 -0
  263. package/dist/commands/setup/monitoring/sentry/sentry.js +25 -0
  264. package/dist/commands/setup/monitoring/sentry/sentryHandler.js +163 -0
  265. package/dist/commands/setup/monitoring/sentry/templates/sentryApi.ts.template +15 -0
  266. package/dist/commands/setup/monitoring/sentry/templates/sentryWeb.ts.template +31 -0
  267. package/dist/commands/setup/package/package.js +33 -0
  268. package/dist/commands/setup/package/packageHandler.js +134 -0
  269. package/dist/commands/setup/realtime/realtime.js +37 -0
  270. package/dist/commands/setup/realtime/realtimeHandler.js +309 -0
  271. package/dist/commands/setup/realtime/templates/defer/fastAndSlowFields/fastAndSlowFields.sdl.template +14 -0
  272. package/dist/commands/setup/realtime/templates/defer/fastAndSlowFields/fastAndSlowFields.ts.template +14 -0
  273. package/dist/commands/setup/realtime/templates/liveQueries/auctions/auctions.sdl.ts.template +27 -0
  274. package/dist/commands/setup/realtime/templates/liveQueries/auctions/auctions.ts.template +73 -0
  275. package/dist/commands/setup/realtime/templates/realtime.ts.template +46 -0
  276. package/dist/commands/setup/realtime/templates/stream/alphabet/alphabet.sdl.template +9 -0
  277. package/dist/commands/setup/realtime/templates/stream/alphabet/alphabet.ts.template +31 -0
  278. package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +58 -0
  279. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +57 -0
  280. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/rooms.sdl.ts.template +20 -0
  281. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/rooms.ts.template +20 -0
  282. package/dist/commands/setup/server-file/serverFile.js +31 -0
  283. package/dist/commands/setup/server-file/serverFileHandler.js +56 -0
  284. package/dist/commands/setup/server-file/templates/server.ts.template +13 -0
  285. package/dist/commands/setup/tsconfig/tsconfig.js +25 -0
  286. package/dist/commands/setup/tsconfig/tsconfigHandler.js +59 -0
  287. package/dist/commands/setup/ui/helpers/helpers.js +9 -0
  288. package/dist/commands/setup/ui/libraries/chakra-ui.js +24 -0
  289. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +98 -0
  290. package/dist/commands/setup/ui/libraries/mantine.js +32 -0
  291. package/dist/commands/setup/ui/libraries/mantineHandler.js +138 -0
  292. package/dist/commands/setup/ui/libraries/tailwindcss.js +26 -0
  293. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +386 -0
  294. package/dist/commands/setup/ui/templates/chakra.storybook.preview.tsx.template +20 -0
  295. package/dist/commands/setup/ui/templates/mantine-postcss.config.js.template +35 -0
  296. package/dist/commands/setup/ui/templates/mantine.storybook.preview.tsx.template +18 -0
  297. package/dist/commands/setup/ui/templates/postcss.config.js.template +9 -0
  298. package/dist/commands/setup/ui/ui.js +17 -0
  299. package/dist/commands/setup/uploads/dbCodemod.js +28 -0
  300. package/dist/commands/setup/uploads/templates/signedUrl.ts.template +21 -0
  301. package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +25 -0
  302. package/dist/commands/setup/uploads/uploads.js +26 -0
  303. package/dist/commands/setup/uploads/uploadsHandler.js +147 -0
  304. package/dist/commands/setup/vite/templates/vite.config.ts.template +19 -0
  305. package/dist/commands/setup/vite/vite.js +38 -0
  306. package/dist/commands/setup/vite/viteHandler.js +83 -0
  307. package/dist/commands/setup.js +33 -0
  308. package/dist/commands/studio.js +23 -0
  309. package/dist/commands/studioHandler.js +61 -0
  310. package/dist/commands/test.js +44 -0
  311. package/dist/commands/testHandler.js +138 -0
  312. package/dist/commands/ts-to-js.js +20 -0
  313. package/dist/commands/type-check.js +41 -0
  314. package/dist/commands/type-checkHandler.js +71 -0
  315. package/dist/commands/upgrade.js +441 -0
  316. package/dist/index.d.js +0 -0
  317. package/dist/index.js +146 -0
  318. package/dist/lib/background.js +45 -0
  319. package/dist/lib/colors.js +18 -0
  320. package/dist/lib/configureStorybook.js +50 -0
  321. package/dist/lib/exec.js +85 -0
  322. package/dist/lib/exit.js +44 -0
  323. package/dist/lib/extendFile.js +114 -0
  324. package/dist/lib/generatePrismaClient.js +60 -0
  325. package/dist/lib/index.js +485 -0
  326. package/dist/lib/loadEnvFiles.js +12 -0
  327. package/dist/lib/locking.js +60 -0
  328. package/dist/lib/merge/algorithms.js +30 -0
  329. package/dist/lib/merge/index.js +163 -0
  330. package/dist/lib/merge/semanticIdentity.js +18 -0
  331. package/dist/lib/merge/strategy.js +136 -0
  332. package/dist/lib/mockTelemetry.js +7 -0
  333. package/dist/lib/packages.js +77 -0
  334. package/dist/lib/plugin.js +206 -0
  335. package/dist/lib/pluralHelpers.js +50 -0
  336. package/dist/lib/ports.js +17 -0
  337. package/dist/lib/project.js +30 -0
  338. package/dist/lib/rollback.js +72 -0
  339. package/dist/lib/runTransform.js +66 -0
  340. package/dist/lib/rwPluralize.js +56 -0
  341. package/dist/lib/schemaHelpers.js +95 -0
  342. package/dist/lib/templates/storybook.preview.tsx.template +19 -0
  343. package/dist/lib/test.js +106 -0
  344. package/dist/lib/updateCheck.js +202 -0
  345. package/dist/lib/updateCheckExecute.js +2 -0
  346. package/dist/middleware/checkNodeVersion.js +23 -0
  347. package/dist/middleware/detectProjectRxVersion.js +12 -0
  348. package/dist/plugin.js +223 -0
  349. package/dist/rwfw.js +47 -0
  350. package/dist/telemetry/exporter.js +63 -0
  351. package/dist/telemetry/index.js +84 -0
  352. package/dist/telemetry/resource.js +98 -0
  353. package/dist/telemetry/send.js +80 -0
  354. package/dist/testLib/cells.js +188 -0
  355. package/dist/testLib/fetchFileFromTemplate.js +9 -0
  356. package/dist/testLib/getFilesWithPattern.js +21 -0
  357. package/dist/testLib/getRootPackageJSON.js +14 -0
  358. package/dist/testLib/isTSProject.js +9 -0
  359. package/dist/testLib/runTransform.js +42 -0
  360. package/package.json +102 -0
package/README.md ADDED
@@ -0,0 +1,706 @@
1
+ # RedwoodJS CLI
2
+
3
+ <!-- toc -->
4
+
5
+ - [Purpose and Vision](#purpose-and-vision)
6
+ - [Package Leads](#package-leads)
7
+ - [Roadmap](#roadmap)
8
+ - [Coming Soon](#coming-soon)
9
+ - [Coming Later](#coming-later)
10
+ - [Contributing](#contributing)
11
+ - [Overview](#overview)
12
+ - [Best Practices](#best-practices)
13
+ - [Adding a Command](#adding-a-command)
14
+ - [command](#command)
15
+ - [description](#description)
16
+ - [builder](#builder)
17
+ - [handler](#handler)
18
+ - [Adding an Entry Point Command](#adding-an-entry-point-command)
19
+ - [Adding a Generator](#adding-a-generator)
20
+ - [createYargsForComponentGeneration](#createyargsforcomponentgeneration)
21
+ - [getYargsDefaults](#getyargsdefaults)
22
+ - [Testing Generators](#testing-generators)
23
+ - [Adding a Destroyer](#adding-a-destroyer)
24
+ - [Adding a Provider to the Auth Generator](#adding-a-provider-to-the-auth-generator)
25
+ - [dbCommands](#dbcommands)
26
+ - [Converting to TypeScript](#converting-to-typescript)
27
+ - [Generators](#generators)
28
+ - [What about...](#what-about)
29
+ - [index.js](#indexjs)
30
+ - [src/lib/colors.js](#srclibcolorsjs)
31
+ - [FAQ](#faq)
32
+ - [I want to alias `yarn rw`](#i-want-to-alias-yarn-rw)
33
+ - [Can I customize the generators?](#can-i-customize-the-generators)
34
+
35
+ ## Purpose and Vision
36
+
37
+ Redwood provides a first-class CLI that helps you at every stage of development, from your first commit to your first deploy. And it comes with Redwood, which means no extra software to install!
38
+
39
+ Redwood uses [yarn workspaces](https://yarnpkg.com/features/workspaces) to separate your app's sides, generators to give you a smooth DX, and [Prisma](https://www.prisma.io/) to manage your database. We have a generator for nearly everything, on both sides of the app, from components to functions.
40
+
41
+ Since the CLI is the entry point to Redwood, as Redwood continues to grow&mdash;especially as we add more sides and targets&mdash;so will the CLI.
42
+
43
+ ## Package Leads
44
+
45
+ - [@cannikin](https://github.com/cannikin)
46
+ - [@peterp](https://github.com/peterp)
47
+ - [@thedavidprice](https://github.com/thedavidprice)
48
+
49
+ ## Roadmap
50
+
51
+ ### Coming Soon
52
+
53
+ - [Generators refactor (plopjs)](https://github.com/redwoodjs/redwood/issues/653)
54
+
55
+ ### Coming Later
56
+
57
+ - [Multiple database support](https://github.com/redwoodjs/redwood/issues/507)
58
+ - [Support for dynamic sides and targets](https://github.com/redwoodjs/redwood/pull/355)
59
+
60
+ ## Contributing
61
+
62
+ Redwood's CLI is built with [Yargs](http://yargs.js.org/).
63
+ If you aren't familiar with it, we walk you through what you need to know in the [Adding a Command](#adding-a-command) section. But if you already are, know that we use the [advanced api](https://github.com/yargs/yargs/blob/master/docs/advanced.md). This means that instead of seeing things written as a method chain, with the `command` method doing most of the work, like:
64
+
65
+ ```javascript
66
+ yargs
67
+ .command(
68
+ 'get',
69
+ 'make a get HTTP request',
70
+ function (yargs) {
71
+ return yargs.option('u', {
72
+ alias: 'url',
73
+ describe: 'the URL to make an HTTP request to',
74
+ })
75
+ },
76
+ function (argv) {
77
+ console.log(argv.url)
78
+ },
79
+ )
80
+ .help().argv
81
+ ```
82
+
83
+ you'll see the arguments to the `command` method spread across exported constants, like:
84
+
85
+ ```javascript
86
+ export const command = 'get'
87
+ export const description = 'make a get HTTP request'
88
+ export const builder = (yargs) => {
89
+ return yargs.option('u', {
90
+ alias: 'url',
91
+ describe: 'the URL to make an HTTP request to',
92
+ })
93
+ }
94
+ export const handler = (argv) => {
95
+ console.log(argv.url)
96
+ }
97
+ ```
98
+
99
+ ### Overview
100
+
101
+ Contributing to `@redwoodjs/cli` usually means adding a command or modifying an existing one. We've organized this doc around adding a command since if you know how to do this you'll know how to modify one too.
102
+
103
+ #### Quickstart
104
+
105
+ RedwoodJS CLI is usually run in a project, this is problematic for contributors, because the transpiled files are not in a project, but in the RedwoodJS framework repo. Luckily the path can be modified at run-time via an env-var: `RWJS_CWD=../path/to/project`.
106
+
107
+ We've added a handy yarn alias to test your modified changes to the Redwood CLI against the "example-todo-main" fixture (`__fixtures__/example-todo-main`) you can do the following:
108
+
109
+ ```terminal
110
+ cd packages/cli
111
+ yarn dev <command>
112
+ ```
113
+
114
+ > **Note:** If you are implementing a command and wish to run via `yarn dev <command>` be sure to `yarn build:clean-dist` beforehand to run the latest version.
115
+
116
+ > **Important:** If your command alters the `example-todo-main` project (adds a package, modifies redwood.toml, etc) be sure not to commit and push those changes as part of your PR.
117
+
118
+ ### Best Practices
119
+
120
+ There's a few best practices we follow that you should be aware of:
121
+
122
+ - **Use `description` instead of `desc` or `describe`:** While yargs accepts any of these, for consistency, use `description`
123
+ - **descriptions shouldn't end in periods:** Again, just a stylistic choice&mdash;but stick to it!
124
+ - **`builder` should be a function:** This enables the positional api (more on that [later](#builder))
125
+ - **Update the docs and test:** By docs, we mean the content on redwoodjs.com. We know this can be a lot, so don't feel like you have to do it all yourself. We're more than happy to help&mdash;just ask us!
126
+
127
+ If none of these make sense yet, don't worry! You'll see them come up in the next section, where we walk you through adding a command.
128
+
129
+ ### Adding a Command
130
+
131
+ You can add a command by creating a file in [./src/commands](https://github.com/redwoodjs/redwood/tree/main/packages/cli/src/commands). Although it's not necessary, for consistency, the file should be named after the command that invokes it. For example, the build command, which is invoked with
132
+
133
+ ```terminal
134
+ yarn rw build
135
+ ```
136
+
137
+ lives in [./src/commands/build.js](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/commands/build.js).
138
+
139
+ To make a command using the advanced api, yargs requires that you export [four constants](https://github.com/yargs/yargs/blob/master/docs/advanced.md#providing-a-command-module):
140
+
141
+ | Constant | Type | Description |
142
+ | :------------ | :------- | :---------------------------------------------------------------------------- |
143
+ | `command` | string | A yargs command definition. You specify the command's name and arguments here |
144
+ | `description` | string | A description of the command; shown in the help message |
145
+ | `builder` | function | Effectively "builds" the command's arguments/options |
146
+ | `handler` | function | The function invoked by the command; does all the work |
147
+
148
+ We'll continue to use the build command as an example as we discuss each of these individually.
149
+
150
+ #### command
151
+
152
+ `command` is a string that represents the command at the CLI and effectively maps it to the handler that does the work.
153
+
154
+ The command for `build` is:
155
+
156
+ ```javascript
157
+ export const command = 'build [side..]'
158
+ ```
159
+
160
+ `'build'` specifies the name of the command and `'[side..]'` indicates that `build` takes an optional positional argument (named `side`&mdash;relevant for `builder` and `handler`). The dots (`..`) trailing `side` indicate that you can provide an array of strings (see [Variadic Positional Arguments](https://github.com/yargs/yargs/blob/master/docs/advanced.md#variadic-positional-arguments)):
161
+
162
+ ```terminal
163
+ yarn rw build api web
164
+ ```
165
+
166
+ See [Positional Arguments](https://github.com/yargs/yargs/blob/master/docs/advanced.md#positional-arguments) for all your options when it comes specifying arguments for commands.
167
+
168
+ #### description
169
+
170
+ `description` is a string that's shown in the help output. `build`'s description is
171
+
172
+ ```javascript
173
+ export const description = 'Build for production'
174
+ ```
175
+
176
+ Running `yarn rw build help` displays:
177
+
178
+ ```terminal
179
+ rw build [side..]
180
+
181
+ Build for production
182
+
183
+ ...
184
+ ```
185
+
186
+ Other than that, there's not much more to it. You should of course make the description descriptive. And for consistency, don't punctuate it. I.e., we prefer this
187
+
188
+ ```javascript
189
+ export const description = 'Build for production'
190
+ ```
191
+
192
+ to this
193
+
194
+ ```javascript
195
+ export const description = 'Build for production.'
196
+ ```
197
+
198
+ #### builder
199
+
200
+ `builder` configures the positional arguments and options for the command.
201
+
202
+ While `builder` can be an object, the [positional argument api](https://yargs.js.org/docs/#api-positionalkey-opt) is only available if builder is a function. But that doesn't mean we can't use an object to "build" `builder`. As you'll see in [getYargsDefaults()](#getyargsdefaults), this is what we do with commands that share a lot of options.
203
+
204
+ Here's an excerpt of `build`'s `builder`:
205
+
206
+ ```javascript
207
+ // ./src/commands/build.js
208
+
209
+ export const builder = (yargs) => {
210
+ yargs
211
+ .positional('side', {
212
+ choices: ['api', 'web'],
213
+ default: optionDefault(apiExists, webExists),
214
+ description: 'Which side(s) to build',
215
+ type: 'array',
216
+ })
217
+
218
+ ...
219
+ ```
220
+
221
+ Using `positional`, you can configure `side` (which was was "defined" earlier in [command](#command)): what values the user's allowed to pass (`choices`), what `side` defaults to if the user passes nothing (`default`), etc.
222
+
223
+ You should always specify `description` and `type`. The rest depends. But generally, if you can specify more, you should.
224
+ For the full list of what properties you can use to compose the options object, see [.positional(key, opt)](https://yargs.js.org/docs/#api-positionalkey-opt). But know that besides `alias` and `choices`, we haven't had the occasion to use anything else.
225
+
226
+ While `side` would've worked in a bare-bones sort of way if we didn't use `positional`, `builder` is the only way to let the command know about its options (only showing the relevant bits here):
227
+
228
+ ```javascript
229
+ // ./src/commands/build.js
230
+
231
+ export const builder = (yargs) => {
232
+ yargs
233
+
234
+ ...
235
+
236
+ .option('stats', {
237
+ default: false,
238
+ description: `Use ${terminalLink(
239
+ 'Webpack Bundle Analyzer',
240
+ 'https://github.com/webpack-contrib/webpack-bundle-analyzer'
241
+ )}`,
242
+ type: 'boolean',
243
+ })
244
+ .option('verbose', {
245
+ alias: 'v',
246
+ default: false,
247
+ description: 'Print more',
248
+ type: 'boolean',
249
+ })
250
+
251
+ ...
252
+
253
+ }
254
+ ```
255
+
256
+ These two calls to `options` configure this command to have options `--stats` and `--verbose`:
257
+
258
+ ```terminal
259
+ yarn rw build --stats
260
+ yarn rw build --verbose
261
+ ```
262
+
263
+ For the full list of what properties you can use to compose the options object, see [options(key, [opt])](https://yargs.js.org/docs/#api-optionskey-opt).
264
+
265
+ #### handler
266
+
267
+ `handler`'s what actually does the work of the command. It's where all the logic goes.
268
+
269
+ More concretely, `handler`'s a function that gets passed the positional arguments and options specified and configured in `command` and `builder`&mdash;the parsed `argv`.
270
+
271
+ While `build`'s `handler` is too long to reproduce here in full, to get the point across, here's the signature:
272
+
273
+ ```javascript
274
+ // ./src/cli/commands/build.js
275
+
276
+ export const handler = async ({
277
+ side = ['api', 'web'],
278
+ verbose = false,
279
+ stats = false,
280
+ }) => {
281
+
282
+ ...
283
+
284
+ }
285
+ ```
286
+
287
+ The logic that goes in a command's `handler` varies too much to comment on generally. But you'll see similarities among commands that do similar things, like generators.
288
+
289
+ ### Adding an Entry Point Command
290
+
291
+ If you're adding a command that serves as an entry point to more commands, like `db`, `destroy`, and `generate`, you'll want to create
292
+
293
+ 1. a file for the command in `./src/commands`, like in [Adding a Command](#adding-a-command), and
294
+ 2. a directory to store all the commands it serves as an entry point to.
295
+
296
+ Although it's not necessary, for consistency, the file and directory should be named after the command that invokes them. Using the generate command as an example, in `./src/commands`, there's the file [generate.js](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/commands/generate.js) and the directory [generate](https://github.com/redwoodjs/redwood/tree/main/packages/cli/src/commands/generate).
297
+
298
+ Files for entry-point commands typically aren't too complicated. Here's the contents of `generate.js` in its entirety:
299
+
300
+ ```javascript
301
+ export const command = 'generate <type>'
302
+ export const aliases = ['g']
303
+ export const description = 'Save time by generating boilerplate code'
304
+ import terminalLink from 'terminal-link'
305
+
306
+ export const builder = (yargs) =>
307
+ yargs
308
+ .commandDir('./generate', { recurse: true })
309
+ .demandCommand()
310
+ .epilogue(
311
+ `Also see the ${terminalLink(
312
+ 'Redwood CLI Reference',
313
+ 'https://redwoodjs.com/docs/cli-commands#generate-alias-g',
314
+ )}`,
315
+ )
316
+ ```
317
+
318
+ The call to `commandDir` is what makes this command an entry point. You can read more about `commandDir` [here](https://github.com/yargs/yargs/blob/master/docs/advanced.md#commanddirdirectory-opts). The second argument to `commandDir`, `{ recurse: true }`, is specific to the `generate` command because each of the commands in the `generate` directory is in its own directory to keep things organized&mdash;more on this in [Adding a Generator](#adding-a-generator).
319
+
320
+ Now all the commands in the `generate` directory will be arguments to the `generate` command:
321
+
322
+ ```
323
+ ./src/commands/generate
324
+ ├── auth
325
+ ├── cell
326
+ ├── component
327
+ ├── function
328
+ ├── helpers.js
329
+ ├── layout
330
+ ├── page
331
+ ├── README.md
332
+ ├── scaffold
333
+ ├── sdl
334
+ ├── service
335
+ └── __tests__
336
+ ```
337
+
338
+ There are files and directories here that aren't yargs related (`README.md`, `helper.js`, and `__tests__`), but because yargs will only use the files that export the appropriate constants, that's ok.
339
+
340
+ ### Adding a Generator
341
+
342
+ > We're about to refactor generators out of @redwoodjs/cli and into their own package, so some of this section will probably change soon.
343
+
344
+ You can add a generator by creating a directory and a file in that directory in [./src/commands/generate](https://github.com/redwoodjs/redwood/tree/main/packages/cli/src/commands/generate).
345
+ Although it's not necessary, for consistency, the directory and file should be named after the command that invokes them.
346
+ For example, the page generator, which is invoked with
347
+
348
+ ```
349
+ yarn redwood generate page
350
+ ```
351
+
352
+ lives in [./src/commands/generate/page/page.js](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/commands/generate/page/page.js), where the `page` directory has the following structure:
353
+
354
+ ```terminal
355
+ src/commands/generate/page
356
+ ├── page.js
357
+ ├── templates
358
+ └── __tests__
359
+ ```
360
+
361
+ Since a typical generator writes files, needs templates to do so, and needs tests to ensure it works, we use this command-in-a-directory structure to keep things organized.
362
+
363
+ The templates for the files created by generators go in `templates`. They should be named after the file they create and end in `.template` to avoid being compiled by Babel:
364
+
365
+ ```terminal
366
+ src/commands/generate/page/template
367
+ ├── page.js.template
368
+ └── test.js.template
369
+ ```
370
+
371
+ The templates are processed with lodash's [template](https://lodash.com/docs#template) function. You can use ES template literal delimiters (`${}`) as interpolation delimiters:
372
+
373
+ ```javascript
374
+ // ./src/commands/generate/page/template/page.js.template
375
+
376
+ const ${singularPascalName}Page = () => {
377
+
378
+ ...
379
+ ```
380
+
381
+ The variables referenced in the template must be named the same as what's passed to the `generateTemplate` function, which is usually wrapped in a few functions, but accessible via the respective generator's `files` function.
382
+
383
+ The `files` function is what actually generates the files. Every generator has one. They use a helper, `templateForComponentFiles`, which takes care of the logic around creating an output path and contents.
384
+
385
+ The `...rest` parameter from `files` gets passed to this function's `templateVars` parameter which gets passed to `generateTemplate` for interpolation:
386
+
387
+ ```javascript
388
+ // ./src/commands/generate/page/page.js
389
+
390
+ export const files = ({ name, ...rest }) => {
391
+ const pageFile = templateForComponentFile({
392
+ name,
393
+ suffix: COMPONENT_SUFFIX,
394
+ webPathSection: REDWOOD_WEB_PATH_NAME,
395
+ generator: 'page',
396
+ templatePath: 'page.js.template',
397
+ templateVars: rest,
398
+ })
399
+ ```
400
+
401
+ For the actual writing of files to disk, generators call on a function from [src/lib/index.js](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/lib/index.js): [writeFilesTask](https://github.com/redwoodjs/redwood/tree/main/packages/cli/src/lib/index.js#L252-L263).
402
+
403
+ More complicated generators, like auth, will have a little more logic in their directories:
404
+
405
+ ```terminal
406
+ src/commands/setup/auth
407
+ ├── auth.js
408
+ ├── providers
409
+ ├── templates
410
+ └── __tests__
411
+ ```
412
+
413
+ #### createYargsForComponentGeneration
414
+
415
+ There's another helper you'll see being used fairly often: [createYargsForComponentGeneration](https://github.com/redwoodjs/redwood/tree/main/packages/cli/src/commands/generate/helpers.js#L67-L131).
416
+
417
+ This function takes care of some of the boilerplate around yargs commands by creating the four constants&mdash;`command`, `description`, `builder`, and `handler`&mdash;for you.
418
+
419
+ It has four parameters:
420
+
421
+ - `componentName`: a string, like `'page'`
422
+ - `filesFn`: a function, usually the one called `files`
423
+ - `optionsObj`: an object, used to construct `options` for yargs. Defaults to [getYargsDefaults()](#getyargsdefaults)
424
+ - `positionalsObj`: an object, used to construct `positionals` for yargs.
425
+
426
+ The idea here's to export as many constants as you can straight from `createYargsForComponentGeneration`'s returns:
427
+
428
+ ```javascript
429
+ // src/commands/generate/cell/cell.js
430
+
431
+ export const { command, description, builder, handler } =
432
+ createYargsForComponentGeneration({
433
+ componentName: 'cell',
434
+ filesFn: files,
435
+ })
436
+ ```
437
+
438
+ But you can use `createYargsForComponentGeneration` even if you don't plan on using all its return values. For example, the component generator uses `command`, `builder`, and `handler`, but doesn't destructure `description` and exports its own instead:
439
+
440
+ ```javascript
441
+ // ./src/commands/generate/component/component.js
442
+
443
+ export const description = 'Generate a component'
444
+
445
+ export const { command, builder, handler } = createYargsForComponentGeneration({
446
+ componentName: 'component',
447
+ filesFn: files,
448
+ })
449
+ ```
450
+
451
+ #### getYargsDefaults
452
+
453
+ If you find yourself not using the `builder` from `createYargsForComponentGeneration` (or just not using `createYargsForComponentGeneration` at all), you should use `getYargsDefaults()`.
454
+
455
+ <!-- [todo] -->
456
+ <!-- Link when merged -->
457
+
458
+ `getYargsDefaults()` is a function that returns an object that contains all the options common to generate commands. It's defined in `generate.js`, the generator entry-point command. So importing it usually looks like:
459
+
460
+ ```javascript
461
+ import { getYargsDefaults } from '../../generate'
462
+ ```
463
+
464
+ <!-- kind of a bad name -->
465
+
466
+ We use `getYargsDefaults` to "build" the builder. The generate sdl command is a good example. In sdl.js (which is in the generate directory in ./src/commands) `getYargsDefaults` is spread into another object, `defaults` (the name of this object is another convention):
467
+
468
+ ```javascript
469
+ // ./src/commands/generate/sdl/sdl.js
470
+
471
+ export const getDefaults = () => {
472
+ return {
473
+ ...getYargsDefaults(),
474
+ crud: {
475
+ default: true,
476
+ description: 'Also generate mutations',
477
+ type: 'boolean',
478
+ },
479
+ }
480
+ }
481
+ ```
482
+
483
+ This way we can define an option specific to the sdl generator (`crud`) while still getting all the options common to generators.
484
+
485
+ But `defaults` isn't `builder`&mdash;`builder` has to be a function (and named `builder`), so in `builder`, you can use the following pattern to incorporate `defaults`:
486
+
487
+ ```javascript
488
+ export const builder = (yargs) => {
489
+ yargs
490
+ .positional('model', {
491
+ description: 'Model to generate the sdl for',
492
+ type: 'string',
493
+ })
494
+ .epilogue(
495
+ `Also see the ${terminalLink(
496
+ 'Redwood CLI Reference',
497
+ 'https://redwoodjs.com/docs/cli-commands#generate-sdl',
498
+ )}`,
499
+ )
500
+ Object.entries(defaults).forEach(([option, config]) => {
501
+ yargs.option(option, config)
502
+ })
503
+ }
504
+ ```
505
+
506
+ #### Testing Generators
507
+
508
+ If you're adding a generator or modifying an existing one, you're gonna wanna test it. (Well, at least we want you to.)
509
+
510
+ Along with a command file and a `templates` directory, most generators have a `__tests__` directory:
511
+
512
+ ```terminal
513
+ src/commands/generate/page
514
+ ├── page.js
515
+ ├── templates
516
+ └── __tests__
517
+ ```
518
+
519
+ Generally, `__tests__` has at least one test file and a `fixtures` directory. For example, `pages/__tests__` has `page.test.js` and `fixtures`:
520
+
521
+ ```terminal
522
+ src/commands/generate/page/__tests__
523
+ ├── page.test.js
524
+ └── fixtures
525
+ ```
526
+
527
+ Fixtures are necessary because generators create files, and to test commands that create files, we need something to compare them to.
528
+
529
+ You can use `loadGeneratorFixture` to load the appropriate fixture to test against.
530
+ It takes two arguments: the name of the generator and the name of the fixture. We usually use it to check to see that the files are equal:
531
+
532
+ ```javascript
533
+ // ./src/packages/cli/src/commands/generate/page/__tests__/page.test.js
534
+
535
+ test('creates a page component', () => {
536
+ expect(
537
+ singleWordFiles[
538
+ path.normalize('/path/to/project/web/src/pages/HomePage/HomePage.js')
539
+ ],
540
+ ).toEqual(loadGeneratorFixture('page', 'singleWordPage.js'))
541
+ })
542
+ ```
543
+
544
+ #### Adding a Destroyer
545
+
546
+ If you're adding a generator, it'd be great if you added its evil twin, a destroyer, too.
547
+
548
+ Destroyers rollback the changes made by generators. They're one-to-one, in that, for a cell generator there's a cell destroyer.
549
+
550
+ Just like generators, destroyers have helpers that minimize the amount of boilerplate you have to write so you can get straight to the custom, creative logic. They're similarly named too: `createYargsForComponentDestroy` is one that, like for generators, you should use if permitting. And you probably will for `builder` at least, since, so far, destroyers don't have any options.
551
+
552
+ And just like generators, destroyers have tests. Right now, the way we test destroyers is by comparing the files that the generator produces with the files the destroyer attempts to delete. But because we don't actually want to write files to disk, we mock the api required to run the generator's `files` function, which is what you'll see going in the top-level [`__mocks__`](https://github.com/redwoodjs/redwood/blob/main/packages/cli/__mocks__/fs.js) directory. To do this, we use Jest's [manual mocking](https://jestjs.io/docs/en/manual-mocks.html) to mock NodeJS's `fs` module.
553
+
554
+ ### Adding a Provider to the Auth Generator
555
+
556
+ Adding a provider to the auth generator is as easy as adding a file in [./src/commands/setup/auth/providers](https://github.com/redwoodjs/redwood/tree/main/packages/cli/src/commands/setup/auth/providers) that exports the four constants: `config`, `webPackages`, `apiPackages` and `notes`.
557
+
558
+ > Note that the provider you are about to add has to have already been implemented in `@redwoodjs/auth`. For example, the provider in the example below, Netlify Identity, is implemented [here](https://github.com/redwoodjs/redwood/blob/main/packages/auth/src/authClients/netlify.ts).
559
+ >
560
+ > So if you haven't done that yet, start with [this doc](https://github.com/redwoodjs/redwood/blob/main/packages/auth/README.md#contributing), then come back to this section afterwards.
561
+
562
+ We'll use the [Netlify Identity](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/commands/setup/auth/providers/netlify.js) provider as an example to discuss these requirements:
563
+
564
+ ```javascript
565
+ // ./src/commands/setup/auth/providers/netlify.js
566
+
567
+ // the lines that need to be added to App.{jsx,tsx}
568
+ export const config = {
569
+ imports: [
570
+ `import netlifyIdentity from 'netlify-identity-widget'`,
571
+ `import { isBrowser } from '@cedarjs/prerender/browserUtils'`,
572
+ ],
573
+ init: 'isBrowser && netlifyIdentity.init()',
574
+ authProvider: {
575
+ client: 'netlifyIdentity',
576
+ type: 'netlify',
577
+ },
578
+ }
579
+
580
+ // required packages to install
581
+ export const webPackages = ['netlify-identity-widget']
582
+ export const apiPackages = []
583
+
584
+ // any notes to print out when the job is done
585
+ export const notes = [
586
+ 'You will need to enable Identity on your Netlify site and configure the API endpoint.',
587
+ 'See: https://github.com/netlify/netlify-identity-widget#localhost',
588
+ ]
589
+ ```
590
+
591
+ `config` is an object that contains everything that needs to be inserted into a Redwood app's `./web/src/index.js` to setup the auth provider and make it available to the router. It has three properties: `imports`, `init`, and `authProvider`.
592
+
593
+ `imports` is an array of strings that lists any imports that need to be added to the top of `./web/src/index.js`. Any initialization code that needs to go after the `import` statements goes in `init`. And `authProvider` is an object that contains exactly two keys, `client` and `type` that will be passed as props to `<AuthProvider>`.
594
+
595
+ The next required exports, `webPackages` and `apiPackages` each contain an array of strings of the packages that need to be added to the web, respectively api workspace's `package.json`.
596
+
597
+ Lastly, `notes` is an array of strings to output after the generator has finished, instructing the user through any further required setup (like setting ENV vars). Each string in the array will output on its own line.
598
+
599
+ ### dbCommands
600
+
601
+ <!-- TODO -->
602
+ <!-- This might need updated soon... -->
603
+ <!-- https://github.com/redwoodjs/redwood/pull/661#issuecomment-644146059 -->
604
+
605
+ Most of the commands in `dbCommands` are just wrappers around [Prisma commands](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-cli/command-reference),
606
+ the exception being `seed`, which runs a Redwood app's [./api/prisma/seed.js](https://github.com/redwoodjs/create-cedar-app/blob/master/api/prisma/seeds.js).
607
+
608
+ Adding or modifying a command here's no different&mdash;there's still a `command`, `description`, `builder`, and `handler`. But there's a pattern to `handler`: it usually uses [runCommandTask](https://github.com/redwoodjs/redwood/blob/d51ade08118c17459cebcdb496197ea52485364a/packages/cli/src/lib/index.js#L349-L377), a Redwood-defined function.
609
+
610
+ This is because most `dbCommands` are really just running prisma commands, so they really just have to output something like `yarn prisma ...`.
611
+
612
+ #### Generators
613
+
614
+ If you're converting a generator, read the _Goals_ section of tracking issue [#523](https://github.com/redwoodjs/redwood/issues/523); it details some specs you should comply with.
615
+
616
+ Some of the generators have already been converted; use them as a reference (linking to the PRs here):
617
+
618
+ - [component](https://github.com/redwoodjs/redwood/pull/632)
619
+ - [sdl](https://github.com/redwoodjs/redwood/pull/515)
620
+ - [services](https://github.com/redwoodjs/redwood/pull/515)
621
+
622
+ For most of the generate commands, the option (in the builder) for generating a typescript file is already there, either in the builder returned from `createYargsForComponentGeneration` or in `getYargsDefaults` (the former actually uses the latter).
623
+
624
+ ### What about...
625
+
626
+ Because it's where most of the action is, most of this doc has been about the `src/commands` directory. But what about all those other files?
627
+
628
+ ```
629
+ redwood/packages/cli
630
+ ├── jest.config.js
631
+ ├── __mocks__
632
+ ├── package.json
633
+ ├── README.md
634
+ └── src
635
+ ├── commands
636
+ ├── index.d.ts
637
+ ├── index.js
638
+ └── lib
639
+ ```
640
+
641
+ #### index.js
642
+
643
+ [index.js](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/index.js) is the `rw` in `yarn rw`. It's the entry-point command to all commands, and like other entry-point commands, it's not too complicated.
644
+
645
+ But it's distinct from the others in that it's the only one that has a shebang at the top and `argv` at the bottom:
646
+
647
+ ```javascript
648
+ // ./src/index.js
649
+
650
+ #!/usr/bin/env node
651
+
652
+ ...
653
+
654
+ .demandCommand()
655
+ .strict().argv
656
+ ```
657
+
658
+ We also use methods that we want to affect all commands here, like `demandCommand` and `strict`.
659
+
660
+ #### lib/colors.js
661
+
662
+ [colors.js](https://github.com/redwoodjs/redwood/blob/main/packages/cli/src/lib/colors.js) provides a declarative way of coloring output to the console using [chalk](https://github.com/chalk/chalk#styles). You'll see it imported like:
663
+
664
+ ```javascript
665
+ import c from '../lib/colors'
666
+ ```
667
+
668
+ And used mainly in catch statements, like:
669
+
670
+ ```javascript
671
+ try {
672
+ await t.run()
673
+ } catch (e) {
674
+ console.log(c.error(e.message))
675
+ }
676
+ ```
677
+
678
+ We only use `error` right now, like in the example above, but you can use `warning`, `green`, and `info` as well:
679
+
680
+ ![rw-colors](https://user-images.githubusercontent.com/32992335/84069820-fedc1b80-a97f-11ea-9f26-c81946064a99.png)
681
+
682
+ Adding a new color is as simple as adding a new property to the default export:
683
+
684
+ ```javascript
685
+ // ./src/lib/colors.js
686
+
687
+ export default {
688
+ error: chalk.bold.red,
689
+ warning: chalk.keyword('orange'),
690
+ green: chalk.green,
691
+ info: chalk.grey,
692
+ }
693
+ ```
694
+
695
+ ## FAQ
696
+
697
+ ### I want to alias `yarn rw`
698
+
699
+ You're not the only one. See the discussion [here](https://github.com/redwoodjs/redwood/issues/328).
700
+
701
+ ### Can I customize the generators?
702
+
703
+ Not yet, but we're talking about it! See the ongoing discussions in these issues:
704
+
705
+ - Investigate integrating or replacing generators with Plop [#653](https://github.com/redwoodjs/redwood/issues/653)
706
+ - BYO Components to Scaffold Generator [#473](https://github.com/redwoodjs/redwood/issues/473)