@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
@@ -0,0 +1,70 @@
1
+ export const schema = gql`
2
+ <% if (docs) { %>
3
+ """${modelDescription}"""
4
+ <% } %>
5
+ type ${singularPascalName} {
6
+ ${query}
7
+ }
8
+
9
+ <% if (enums.length > 0) {%>
10
+ <% enums.forEach((enumDef, idx)=> {
11
+ const enumName = enums[idx].name
12
+ const enumDescription = enums[idx].documentation || `Possible values for ${enums[idx].name}`
13
+ %>
14
+ <% if (docs) { %>
15
+ """${enumDescription}"""
16
+ <% } %>
17
+ enum ${enums[idx].name} {<% enums[idx].values.forEach((enumDefValue, idk)=> { %>
18
+ ${enums[idx].values[idk].name}<% }) %>
19
+ }
20
+ <%}) %><% } %>
21
+ <% if (docs) { %>
22
+ """About queries"""
23
+ <% } %>
24
+ type Query {
25
+ <% if (docs) { %>
26
+ "Fetch ${pluralPascalName}."
27
+ <% } %>${pluralCamelName}: [${singularPascalName}!]! @requireAuth<% if (crud) { %>
28
+ <% if (docs) { %>
29
+ "Fetch a ${singularPascalName} by id."
30
+ <% } %>${singularCamelName}(${idName}: ${idType}!): ${singularPascalName} @requireAuth<% } %>
31
+ }
32
+
33
+ <% if (docs) { %>
34
+ """Autogenerated input type of Input${singularPascalName}."""
35
+ <% } %>
36
+ input Create${singularPascalName}Input {
37
+ ${createInput}
38
+ }
39
+
40
+ <% if (idInput) { %>
41
+ <% if (docs) { %>
42
+ """Autogenerated ID input type of ${singularPascalName}Id."""
43
+ <% } %>
44
+ input ${singularPascalName}IdInput {
45
+ ${idInput}
46
+ }
47
+ <% } %>
48
+
49
+ <% if (docs) { %>
50
+ """Autogenerated input type of Update${singularPascalName}."""
51
+ <% } %>
52
+ input Update${singularPascalName}Input {
53
+ ${updateInput}
54
+ }<% if (crud) { %>
55
+
56
+ <% if (docs) { %>
57
+ """About mutations"""
58
+ <% } %>
59
+ type Mutation {
60
+ <% if (docs) { %>
61
+ "Creates a new ${singularPascalName}."
62
+ <% } %>create${singularPascalName}(input: Create${singularPascalName}Input!): ${singularPascalName}! @requireAuth
63
+ <% if (docs) { %>
64
+ "Updates an existing ${singularPascalName}."
65
+ <% } %>update${singularPascalName}(${idName}: ${idType}!, input: Update${singularPascalName}Input!): ${singularPascalName}! @requireAuth
66
+ <% if (docs) { %>
67
+ "Deletes an existing ${singularPascalName}."
68
+ <% } %>delete${singularPascalName}(${idName}: ${idType}!): ${singularPascalName}! @requireAuth
69
+ }<% } %>
70
+ `
@@ -0,0 +1,52 @@
1
+ import crypto from "node:crypto";
2
+ import terminalLink from "terminal-link";
3
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
4
+ const DEFAULT_LENGTH = 32;
5
+ const generateSecret = (length = DEFAULT_LENGTH) => {
6
+ return crypto.randomBytes(length).toString("base64");
7
+ };
8
+ const command = "secret";
9
+ const description = "Generates a secret key using a cryptographically-secure source of entropy";
10
+ const builder = (yargs) => yargs.option("length", {
11
+ description: "Length of the generated secret",
12
+ type: "integer",
13
+ required: false,
14
+ default: DEFAULT_LENGTH
15
+ }).option("raw", {
16
+ description: "Prints just the raw secret",
17
+ type: "boolean",
18
+ required: false,
19
+ default: false
20
+ }).epilogue(
21
+ `Also see the ${terminalLink(
22
+ "Redwood CLI Reference",
23
+ "https://redwoodjs.com/docs/cli-commands#generate-secret"
24
+ )}`
25
+ );
26
+ const handler = ({ length, raw }) => {
27
+ recordTelemetryAttributes({
28
+ command: "generate secret",
29
+ length,
30
+ raw
31
+ });
32
+ if (raw) {
33
+ console.log(generateSecret(length));
34
+ return;
35
+ }
36
+ console.info("");
37
+ console.info(` ${generateSecret(length)}`);
38
+ console.info("");
39
+ console.info(
40
+ "If you're using this with dbAuth, set a SESSION_SECRET environment variable to this value."
41
+ );
42
+ console.info("");
43
+ console.info("Keep it secret, keep it safe!");
44
+ };
45
+ export {
46
+ DEFAULT_LENGTH,
47
+ builder,
48
+ command,
49
+ description,
50
+ generateSecret,
51
+ handler
52
+ };
@@ -0,0 +1,50 @@
1
+ import terminalLink from "terminal-link";
2
+ import {
3
+ createCommand,
4
+ createDescription,
5
+ createHandler,
6
+ getYargsDefaults
7
+ } from "../yargsCommandHelpers.js";
8
+ const defaults = () => {
9
+ const defaults2 = {
10
+ ...getYargsDefaults(),
11
+ tests: {
12
+ description: "Generate test files",
13
+ type: "boolean"
14
+ },
15
+ crud: {
16
+ default: true,
17
+ description: "Create CRUD functions",
18
+ type: "boolean"
19
+ }
20
+ };
21
+ return defaults2;
22
+ };
23
+ const command = createCommand("service");
24
+ const description = createDescription("service");
25
+ const builder = (yargs) => {
26
+ yargs.positional("name", {
27
+ description: "Name of the service",
28
+ type: "string"
29
+ }).option("rollback", {
30
+ description: "Revert all generator actions if an error occurs",
31
+ type: "boolean",
32
+ default: true
33
+ }).epilogue(
34
+ `Also see the ${terminalLink(
35
+ "Redwood CLI Reference",
36
+ "https://redwoodjs.com/docs/cli-commands#generate-service"
37
+ )}`
38
+ );
39
+ Object.entries(defaults()).forEach(([option, config]) => {
40
+ yargs.option(option, config);
41
+ });
42
+ };
43
+ const handler = createHandler("service");
44
+ export {
45
+ builder,
46
+ command,
47
+ defaults,
48
+ description,
49
+ handler
50
+ };
@@ -0,0 +1,301 @@
1
+ import camelcase from "camelcase";
2
+ import { transformTSToJS } from "../../../lib/index.js";
3
+ import { pluralize, singularize } from "../../../lib/rwPluralize.js";
4
+ import { getSchema, verifyModelName } from "../../../lib/schemaHelpers.js";
5
+ import { relationsForModel } from "../helpers.js";
6
+ import {
7
+ createHandler,
8
+ templateForComponentFile
9
+ } from "../yargsHandlerHelpers.js";
10
+ const DEFAULT_SCENARIO_NAMES = ["one", "two"];
11
+ const parseSchema = async (model) => {
12
+ const schema = await getSchema(model);
13
+ const relations = {};
14
+ let foreignKeys = [];
15
+ let scalarFields = schema.fields.filter((field) => {
16
+ if (field.relationFromFields) {
17
+ if (field.isRequired && field.relationFromFields.length !== 0) {
18
+ relations[field.name] = {
19
+ foreignKey: field.relationFromFields,
20
+ type: field.type
21
+ };
22
+ }
23
+ foreignKeys = foreignKeys.concat(field.relationFromFields);
24
+ }
25
+ return field.isRequired && !field.hasDefaultValue && // don't include fields that the database will default
26
+ !field.relationName;
27
+ });
28
+ return { scalarFields, relations, foreignKeys };
29
+ };
30
+ const scenarioFieldValue = (field) => {
31
+ const randFloat = Math.random() * 1e7;
32
+ const randInt = parseInt(Math.random() * 1e7);
33
+ const randIntArray = [
34
+ parseInt(Math.random() * 300),
35
+ parseInt(Math.random() * 300),
36
+ parseInt(Math.random() * 300)
37
+ ];
38
+ switch (field.type) {
39
+ case "BigInt":
40
+ return `${BigInt(randInt)}n`;
41
+ case "Boolean":
42
+ return true;
43
+ case "DateTime":
44
+ return /* @__PURE__ */ new Date();
45
+ case "Decimal":
46
+ case "Float":
47
+ return randFloat;
48
+ case "Int":
49
+ return randInt;
50
+ case "Json":
51
+ return { foo: "bar" };
52
+ case "String":
53
+ return field.isUnique ? `String${randInt}` : "String";
54
+ case "Bytes":
55
+ return `Buffer.from([${randIntArray}])`;
56
+ default: {
57
+ if (field.kind === "enum" && field.enumValues[0]) {
58
+ return field.enumValues[0].dbName || field.enumValues[0].name;
59
+ }
60
+ }
61
+ }
62
+ };
63
+ const fieldsToScenario = async (scalarFields, relations, foreignKeys) => {
64
+ const data = {};
65
+ scalarFields.forEach((field) => {
66
+ if (!foreignKeys.length || !foreignKeys.includes(field.name)) {
67
+ data[field.name] = scenarioFieldValue(field);
68
+ }
69
+ });
70
+ for (const [relationName, relData] of Object.entries(relations)) {
71
+ const relationModelName = relData.type;
72
+ const {
73
+ scalarFields: relScalarFields,
74
+ relations: relRelations,
75
+ foreignKeys: relForeignKeys
76
+ } = await parseSchema(relationModelName);
77
+ data[relationName] = {
78
+ create: await fieldsToScenario(
79
+ relScalarFields,
80
+ relRelations,
81
+ relForeignKeys
82
+ )
83
+ };
84
+ }
85
+ return data;
86
+ };
87
+ const buildScenario = async (model) => {
88
+ const scenarioModelName = camelcase(model);
89
+ const standardScenario = {
90
+ [scenarioModelName]: {}
91
+ };
92
+ const { scalarFields, relations, foreignKeys } = await parseSchema(model);
93
+ for (const name of DEFAULT_SCENARIO_NAMES) {
94
+ standardScenario[scenarioModelName][name] = {};
95
+ const scenarioData = await fieldsToScenario(
96
+ scalarFields,
97
+ relations,
98
+ foreignKeys
99
+ );
100
+ Object.keys(scenarioData).forEach((key) => {
101
+ const value = scenarioData[key];
102
+ if (value && typeof value === "string" && value.match(/^\d+n$/)) {
103
+ scenarioData[key] = `${value.slice(0, value.length - 1)}n`;
104
+ }
105
+ });
106
+ standardScenario[scenarioModelName][name].data = scenarioData;
107
+ }
108
+ return standardScenario;
109
+ };
110
+ const buildStringifiedScenario = async (model) => {
111
+ const scenario = await buildScenario(model);
112
+ const jsonString = JSON.stringify(scenario, (_key, value) => {
113
+ if (typeof value === "bigint") {
114
+ return value.toString();
115
+ }
116
+ if (typeof value === "string" && value.match(/^\d+n$/)) {
117
+ return Number(value.slice(0, value.length - 1));
118
+ }
119
+ return value;
120
+ });
121
+ return jsonString.replace(/"Buffer\.from\(([^)]+)\)"/g, "Buffer.from($1)");
122
+ };
123
+ const fieldTypes = async (model) => {
124
+ const { scalarFields } = await parseSchema(model);
125
+ return scalarFields.reduce((acc, value) => {
126
+ acc[value.name] = value.type;
127
+ return acc;
128
+ }, {});
129
+ };
130
+ const fieldsToInput = async (model) => {
131
+ const { scalarFields, foreignKeys } = await parseSchema(model);
132
+ const modelName = camelcase(singularize(model));
133
+ let inputObj = {};
134
+ scalarFields.forEach((field) => {
135
+ if (foreignKeys.includes(field.name)) {
136
+ inputObj[field.name] = `scenario.${modelName}.two.${field.name}`;
137
+ } else {
138
+ inputObj[field.name] = scenarioFieldValue(field);
139
+ }
140
+ });
141
+ if (Object.keys(inputObj).length > 0) {
142
+ return inputObj;
143
+ } else {
144
+ return false;
145
+ }
146
+ };
147
+ const fieldsToUpdate = async (model) => {
148
+ const { scalarFields, relations, foreignKeys } = await parseSchema(model);
149
+ const modelName = camelcase(singularize(model));
150
+ let field, newValue, fieldName;
151
+ field = scalarFields.find((scalar) => !foreignKeys.includes(scalar.name));
152
+ if (!field) {
153
+ field = scalarFields[0];
154
+ }
155
+ if (!field) {
156
+ return false;
157
+ }
158
+ if (foreignKeys.includes(field.name)) {
159
+ fieldName = Object.values(relations)[0].foreignKey;
160
+ newValue = `scenario.${modelName}.two.${field.name}`;
161
+ } else {
162
+ fieldName = field.name;
163
+ const value = scenarioFieldValue(field);
164
+ newValue = value;
165
+ switch (field.type) {
166
+ case "BigInt":
167
+ newValue = `${newValue + 1n}`;
168
+ break;
169
+ case "Boolean": {
170
+ newValue = !value;
171
+ break;
172
+ }
173
+ case "DateTime": {
174
+ let date = /* @__PURE__ */ new Date();
175
+ date.setDate(date.getDate() + 1);
176
+ newValue = date;
177
+ break;
178
+ }
179
+ case "Decimal":
180
+ case "Float": {
181
+ newValue = newValue + 1.1;
182
+ break;
183
+ }
184
+ case "Int": {
185
+ newValue = newValue + 1;
186
+ break;
187
+ }
188
+ case "Json": {
189
+ newValue = { foo: "baz" };
190
+ break;
191
+ }
192
+ case "String": {
193
+ newValue = newValue + "2";
194
+ break;
195
+ }
196
+ default: {
197
+ if (field.kind === "enum" && field.enumValues[field.enumValues.length - 1]) {
198
+ const enumVal = field.enumValues[field.enumValues.length - 1];
199
+ newValue = enumVal.dbName || enumVal.name;
200
+ }
201
+ break;
202
+ }
203
+ }
204
+ }
205
+ return { [fieldName]: newValue };
206
+ };
207
+ const getIdName = async (model) => {
208
+ const schema = await getSchema(model);
209
+ return schema.fields.find((field) => field.isId)?.name;
210
+ };
211
+ const files = async ({
212
+ name,
213
+ tests,
214
+ relations,
215
+ typescript,
216
+ ...rest
217
+ }) => {
218
+ const componentName = camelcase(pluralize(name));
219
+ const model = name;
220
+ const idName = await getIdName(model);
221
+ const extension = "ts";
222
+ const modelRelations = relations || relationsForModel(await getSchema(model));
223
+ const serviceFile = await templateForComponentFile({
224
+ name,
225
+ componentName,
226
+ extension: `.${extension}`,
227
+ apiPathSection: "services",
228
+ generator: "service",
229
+ templatePath: `service.${extension}.template`,
230
+ templateVars: { relations: modelRelations, idName, ...rest }
231
+ });
232
+ const testFile = await templateForComponentFile({
233
+ name,
234
+ componentName,
235
+ extension: `.test.${extension}`,
236
+ apiPathSection: "services",
237
+ generator: "service",
238
+ templatePath: `test.${extension}.template`,
239
+ templateVars: {
240
+ relations: relations || [],
241
+ create: await fieldsToInput(model),
242
+ update: await fieldsToUpdate(model),
243
+ types: await fieldTypes(model),
244
+ prismaImport: (await parseSchema(model)).scalarFields.some(
245
+ (field) => field.type === "Decimal"
246
+ ),
247
+ prismaModel: model,
248
+ idName,
249
+ ...rest
250
+ }
251
+ });
252
+ const scenariosFile = await templateForComponentFile({
253
+ name,
254
+ componentName,
255
+ extension: `.scenarios.${extension}`,
256
+ apiPathSection: "services",
257
+ generator: "service",
258
+ templatePath: `scenarios.${extension}.template`,
259
+ templateVars: {
260
+ scenario: await buildScenario(model),
261
+ stringifiedScenario: await buildStringifiedScenario(model),
262
+ prismaModel: model,
263
+ idName,
264
+ relations: modelRelations,
265
+ ...rest
266
+ }
267
+ });
268
+ const files2 = [serviceFile];
269
+ if (tests) {
270
+ files2.push(testFile);
271
+ files2.push(scenariosFile);
272
+ }
273
+ return files2.reduce(async (accP, [outputPath, content]) => {
274
+ const acc = await accP;
275
+ if (!typescript) {
276
+ content = await transformTSToJS(outputPath, content);
277
+ outputPath = outputPath.replace(".ts", ".js");
278
+ }
279
+ return {
280
+ [outputPath]: content,
281
+ ...acc
282
+ };
283
+ }, Promise.resolve({}));
284
+ };
285
+ const handler = createHandler({
286
+ componentName: "service",
287
+ preTasksFn: verifyModelName,
288
+ filesFn: files
289
+ });
290
+ export {
291
+ buildScenario,
292
+ buildStringifiedScenario,
293
+ fieldTypes,
294
+ fieldsToInput,
295
+ fieldsToScenario,
296
+ fieldsToUpdate,
297
+ files,
298
+ handler,
299
+ parseSchema,
300
+ scenarioFieldValue
301
+ };
@@ -0,0 +1,7 @@
1
+ import type { Prisma, ${prismaModel} } from '@prisma/client'
2
+
3
+ import type { ScenarioData } from '@cedarjs/testing/api'
4
+
5
+ export const standard = defineScenario<Prisma.${prismaModel}CreateArgs>(${stringifiedScenario})
6
+
7
+ export type StandardScenario = ScenarioData<${prismaModel}, '${camelName}'>
@@ -0,0 +1,38 @@
1
+ import type { QueryResolvers<% if (crud) { %>, MutationResolvers<% } %><% if (relations.length) { %>, ${singularPascalName}RelationResolvers<% } %> } from 'types/graphql'
2
+
3
+ import { db } from 'src/lib/db'
4
+
5
+ export const ${pluralCamelName}: QueryResolvers['${pluralCamelName}'] = () => {
6
+ return db.${singularCamelName}.findMany()
7
+ }<% if (crud || relations.length) { %>
8
+
9
+ export const ${singularCamelName}: QueryResolvers['${singularCamelName}'] = ({ ${idName} }) => {
10
+ return db.${singularCamelName}.findUnique({
11
+ where: { ${idName} },
12
+ })
13
+ }<% } %><% if (crud) { %>
14
+
15
+ export const create${singularPascalName}: MutationResolvers['create${singularPascalName}'] = ({ input }) => {
16
+ return db.${singularCamelName}.create({
17
+ data: input,
18
+ })
19
+ }
20
+
21
+ export const update${singularPascalName}: MutationResolvers['update${singularPascalName}'] = ({ ${idName}, input }) => {
22
+ return db.${singularCamelName}.update({
23
+ data: input,
24
+ where: { ${idName} },
25
+ })
26
+ }
27
+
28
+ export const delete${singularPascalName}: MutationResolvers['delete${singularPascalName}'] = ({ ${idName} }) => {
29
+ return db.${singularCamelName}.delete({
30
+ where: { ${idName} },
31
+ })
32
+ }<% } %><% if (relations.length) { %>
33
+
34
+ export const ${singularPascalName}: ${singularPascalName}RelationResolvers = {<% relations.forEach(relation => { %>
35
+ ${relation}: (_obj, { root }) => {
36
+ return db.${singularCamelName}.findUnique({ where: { ${idName}: root?.${idName} } }).${relation}()
37
+ },<% }) %>
38
+ }<% } %>
@@ -0,0 +1,84 @@
1
+ <% // Transforms an object or single value into something that's more suitable
2
+ // for generating test cases
3
+ // If a `type` is passed in, the string for creating an object of that type
4
+ // will be generated
5
+ // If no type, or a type we don't support, is passed in we'll default to
6
+ // generating regular strings
7
+ // Looks for quoted strings, either by single (') or double (") quotes.
8
+ // When found
9
+ // - Removes the quotes around `scenario` variables.
10
+ // - Removes the quotes around `BigInt` fields.
11
+ const transformValue = (obj, type) => {
12
+ if (type === 'DateTime') {
13
+ return `new Date('${obj.toISOString()}')`
14
+ } else if (type === 'Decimal') {
15
+ return `new Prisma.Decimal(${obj})`
16
+ }
17
+
18
+ const jsonString = JSON.stringify(obj).replace(/['"].*?['"]/g, (string) => {
19
+ if (string.match(/scenario\./)) {
20
+ return string.replace(/['"]/g, '')
21
+ }
22
+
23
+ // BigInt
24
+ if (string.match(/^\"\d+n\"$/)) {
25
+ return string.slice(1, string.length - 1)
26
+ }
27
+
28
+ return string
29
+ })
30
+
31
+ // Not all values can be represented as JSON, like function invocations
32
+ return jsonString.replace(/"Buffer\.from\(([^)]+)\)"/g, 'Buffer.from($1)')
33
+ } %>
34
+ <% if (prismaImport) { %>import { Prisma, ${prismaModel} } from '@prisma/client'<% } else { %>import type { ${prismaModel} } from '@prisma/client'<% } %>
35
+
36
+ import { ${pluralCamelName}<% if (crud) { %>,${singularCamelName}, create${singularPascalName}, update${singularPascalName}, delete${singularPascalName}<% } %> } from './${pluralCamelName}'
37
+ import type { StandardScenario } from './${pluralCamelName}.scenarios'
38
+
39
+ // Generated boilerplate tests do not account for all circumstances
40
+ // and can fail without adjustments, e.g. Float.
41
+ // Please refer to the RedwoodJS Testing Docs:
42
+ // https://redwoodjs.com/docs/testing#testing-services
43
+ // https://redwoodjs.com/docs/testing#jest-expect-type-considerations
44
+
45
+ describe('${pluralCamelName}', () => {
46
+ scenario('returns all ${pluralCamelName}', async (scenario: StandardScenario) => {
47
+ const result = await ${pluralCamelName}()
48
+
49
+ expect(result.length).toEqual(Object.keys(scenario.${singularCamelName}).length)
50
+ })<% if (crud) { %>
51
+
52
+ scenario('returns a single ${singularCamelName}', async (scenario: StandardScenario) => {
53
+ const result = await ${singularCamelName}({ ${idName}: scenario.${singularCamelName}.one.${idName} })
54
+
55
+ expect(result).toEqual(scenario.${singularCamelName}.one)
56
+ })
57
+
58
+ <% if (create) { %>scenario('creates a ${singularCamelName}', async (${transformValue(create).includes('scenario.') ? 'scenario: StandardScenario' : ''}) => {
59
+ const result = await create${singularPascalName}({
60
+ input: ${transformValue(create)},
61
+ })
62
+
63
+ <% for (const [name, value] of Object.entries(create)) { %>
64
+ expect(result.${name}).toEqual(${transformValue(value, types[name])})<% } %>
65
+ })<% } %>
66
+
67
+ <% if (update) { %>scenario('updates a ${singularCamelName}', async (scenario: StandardScenario) => {<% rand = parseInt(Math.random() * 10000000) %>
68
+ const original = await (${singularCamelName}({ ${idName}: scenario.${singularCamelName}.one.${idName} })) as ${prismaModel}
69
+ const result = await update${singularPascalName}({
70
+ ${idName}: original.${idName},
71
+ input: ${transformValue(update)},
72
+ })
73
+
74
+ <% for (const [name, value] of Object.entries(update)) { %>
75
+ expect(result.${name}).toEqual(${transformValue(value, types[name])})<% } %>
76
+ })<% } %>
77
+
78
+ scenario('deletes a ${singularCamelName}', async (scenario: StandardScenario) => {
79
+ const original = (await delete${singularPascalName}({ ${idName}: scenario.${singularCamelName}.one.${idName} })) as ${prismaModel}
80
+ const result = await ${singularCamelName}({ ${idName}: original.${idName} })
81
+
82
+ expect(result).toEqual(null)
83
+ })<% } %>
84
+ })
@@ -0,0 +1,77 @@
1
+ import terminalLink from "terminal-link";
2
+ import { isTypeScriptProject } from "@cedarjs/cli-helpers";
3
+ const getYargsDefaults = () => ({
4
+ force: {
5
+ alias: "f",
6
+ default: false,
7
+ description: "Overwrite existing files",
8
+ type: "boolean"
9
+ },
10
+ typescript: {
11
+ alias: "ts",
12
+ default: isTypeScriptProject(),
13
+ description: "Generate TypeScript files",
14
+ type: "boolean"
15
+ }
16
+ });
17
+ const appendPositionalsToCmd = (commandString, positionalsObj) => {
18
+ if (Object.keys(positionalsObj).length > 0) {
19
+ const positionalNames = Object.keys(positionalsObj).map((positionalName) => `[${positionalName}]`).join(" ");
20
+ return `${commandString} ${positionalNames}`;
21
+ } else {
22
+ return commandString;
23
+ }
24
+ };
25
+ function createCommand(componentName, positionalsObj = {}) {
26
+ return appendPositionalsToCmd(`${componentName} <name>`, positionalsObj);
27
+ }
28
+ function createDescription(componentName) {
29
+ return `Generate a ${componentName} component`;
30
+ }
31
+ function createBuilder({ componentName, optionsObj, positionalsObj }) {
32
+ return (yargs) => {
33
+ yargs.positional("name", {
34
+ description: `Name of the ${componentName}`,
35
+ type: "string"
36
+ }).epilogue(
37
+ `Also see the ${terminalLink(
38
+ "Redwood CLI Reference",
39
+ `https://redwoodjs.com/docs/cli-commands#generate-${componentName}`
40
+ )}`
41
+ ).option("tests", {
42
+ description: "Generate test files",
43
+ type: "boolean"
44
+ }).option("stories", {
45
+ description: "Generate storybook files",
46
+ type: "boolean"
47
+ }).option("verbose", {
48
+ description: "Print all logs",
49
+ type: "boolean",
50
+ default: false
51
+ }).option("rollback", {
52
+ description: "Revert all generator actions if an error occurs",
53
+ type: "boolean",
54
+ default: true
55
+ });
56
+ Object.entries(positionalsObj || {}).forEach(([option, config]) => {
57
+ yargs.positional(option, config);
58
+ });
59
+ const opts = typeof optionsObj === "object" ? optionsObj : typeof optionsObj === "function" ? optionsObj() : getYargsDefaults();
60
+ Object.entries(opts).forEach(([option, config]) => {
61
+ yargs.option(option, config);
62
+ });
63
+ };
64
+ }
65
+ function createHandler(componentName) {
66
+ return async function handler(argv) {
67
+ const { handler: importedHandler } = await import(`./${componentName}/${componentName}Handler.js`);
68
+ return importedHandler(argv);
69
+ };
70
+ }
71
+ export {
72
+ createBuilder,
73
+ createCommand,
74
+ createDescription,
75
+ createHandler,
76
+ getYargsDefaults
77
+ };