@cedarjs/cli 9.0.0-canary.1784 → 9.0.0-canary.3124

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 (277) hide show
  1. package/README.md +7 -10
  2. package/dist/cfw.js +10 -6
  3. package/dist/commands/build/buildHandler.js +220 -45
  4. package/dist/commands/build/buildPackagesTask.js +21 -20
  5. package/dist/commands/build.js +13 -2
  6. package/dist/commands/check.js +4 -6
  7. package/dist/commands/console.js +6 -4
  8. package/dist/commands/deploy/baremetal/SshExecutor.js +13 -4
  9. package/dist/commands/deploy/baremetal/baremetalHandler.js +116 -50
  10. package/dist/commands/deploy/baremetal.js +11 -4
  11. package/dist/commands/deploy/flightcontrolHandler.js +28 -15
  12. package/dist/commands/deploy/helpers/deployHandler.js +11 -6
  13. package/dist/commands/deploy/netlify.js +1 -1
  14. package/dist/commands/deploy/packing/nft.js +1 -2
  15. package/dist/commands/deploy/render.js +1 -1
  16. package/dist/commands/deploy/renderHandler.js +24 -13
  17. package/dist/commands/deploy/serverlessHandler.js +69 -27
  18. package/dist/commands/deploy/vercel.js +1 -1
  19. package/dist/commands/destroy/component/component.js +2 -3
  20. package/dist/commands/destroy/directive/directive.js +1 -3
  21. package/dist/commands/destroy/directive/directiveHandler.js +2 -4
  22. package/dist/commands/destroy/function/function.js +1 -3
  23. package/dist/commands/destroy/handlerHelpers.js +17 -17
  24. package/dist/commands/destroy/helpers.js +8 -2
  25. package/dist/commands/destroy/layout/layout.js +1 -2
  26. package/dist/commands/destroy/page/pageHandler.js +3 -3
  27. package/dist/commands/destroy/scaffold/scaffoldHandler.js +31 -12
  28. package/dist/commands/destroy/sdl/sdlHandler.js +3 -3
  29. package/dist/commands/dev/apiDebugFlag.js +5 -4
  30. package/dist/commands/dev/devHandler.js +219 -68
  31. package/dist/commands/dev/packageWatchCommands.js +8 -3
  32. package/dist/commands/dev.js +16 -6
  33. package/dist/commands/execHandler.js +49 -29
  34. package/dist/commands/experimental/live-queries/liveQueries.js +32 -0
  35. package/dist/commands/experimental/live-queries/liveQueriesHandler.js +448 -0
  36. package/dist/commands/experimental/live-queries/templates/liveQueriesListener.ts.template +153 -0
  37. package/dist/commands/experimental/live-queries/templates/migration.sql.template +100 -0
  38. package/dist/commands/experimental/setupInngest.js +2 -2
  39. package/dist/commands/experimental/setupInngestHandler.js +13 -12
  40. package/dist/commands/experimental/setupOpentelemetry.js +2 -2
  41. package/dist/commands/experimental/setupOpentelemetryHandler.js +14 -10
  42. package/dist/commands/experimental/setupReactCompiler.js +2 -2
  43. package/dist/commands/experimental/setupReactCompilerHandler.js +48 -33
  44. package/dist/commands/experimental/setupRsc.js +1 -1
  45. package/dist/commands/experimental/setupRscHandler.js +20 -16
  46. package/dist/commands/experimental/setupStreamingSsr.js +2 -2
  47. package/dist/commands/experimental/setupStreamingSsrHandler.js +49 -34
  48. package/dist/commands/experimental/templates/opentelemetry.ts.template +2 -1
  49. package/dist/commands/experimental/templates/rsc/Document.tsx.template +1 -1
  50. package/dist/commands/experimental/templates/rsc/entry.client.tsx.template +8 -8
  51. package/dist/commands/experimental/templates/streamingSsr/Document.tsx.template +1 -1
  52. package/dist/commands/experimental/templates/streamingSsr/entry.client.tsx.template +6 -6
  53. package/dist/commands/experimental/templates/streamingSsr/tsconfig.json.template +6 -6
  54. package/dist/commands/experimental/util.js +27 -25
  55. package/dist/commands/experimental.js +3 -2
  56. package/dist/commands/generate/cell/cell.js +20 -0
  57. package/dist/commands/generate/cell/cellHandler.js +89 -40
  58. package/dist/commands/generate/cell/templates/cell.tsx.template +21 -2
  59. package/dist/commands/generate/cell/templates/cellFragment.tsx.template +43 -0
  60. package/dist/commands/generate/cell/templates/cellList.tsx.template +21 -2
  61. package/dist/commands/generate/cell/templates/storiesFragment.tsx.template +23 -0
  62. package/dist/commands/generate/cell/templates/test.js.template +1 -1
  63. package/dist/commands/generate/cell/templates/testFragment.js.template +30 -0
  64. package/dist/commands/generate/component/componentHandler.js +14 -16
  65. package/dist/commands/generate/dataMigration/dataMigration.js +36 -18
  66. package/dist/commands/generate/dataMigration/templates/dataMigration.js.template +1 -1
  67. package/dist/commands/generate/dataMigration/templates/dataMigration.ts.template +1 -1
  68. package/dist/commands/generate/dbAuth/dbAuth.js +1 -0
  69. package/dist/commands/generate/dbAuth/dbAuthHandler.js +63 -34
  70. package/dist/commands/generate/dbAuth/templates/login.oauth.tsx.template +164 -0
  71. package/dist/commands/generate/dbAuth/templates/signup.oauth.tsx.template +147 -0
  72. package/dist/commands/generate/directive/directiveHandler.js +14 -16
  73. package/dist/commands/generate/function/function.js +1 -0
  74. package/dist/commands/generate/function/functionHandler.js +14 -19
  75. package/dist/commands/generate/helpers.js +34 -18
  76. package/dist/commands/generate/job/job.js +1 -0
  77. package/dist/commands/generate/job/jobHandler.js +20 -24
  78. package/dist/commands/generate/layout/layoutHandler.js +13 -16
  79. package/dist/commands/generate/model/model.js +1 -0
  80. package/dist/commands/generate/model/modelHandler.js +11 -5
  81. package/dist/commands/generate/ogImage/ogImage.js +1 -0
  82. package/dist/commands/generate/ogImage/ogImageHandler.js +18 -11
  83. package/dist/commands/generate/package/filesTask.js +9 -0
  84. package/dist/commands/generate/package/packageHandler.js +50 -61
  85. package/dist/commands/generate/package/templates/test.ts.template +2 -2
  86. package/dist/commands/generate/package/templates/vitest.config.ts.template +9 -0
  87. package/dist/commands/generate/page/pageHandler.js +27 -24
  88. package/dist/commands/generate/realtime/realtime.js +2 -2
  89. package/dist/commands/generate/realtime/realtimeHandler.js +51 -32
  90. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +1 -1
  91. package/dist/commands/generate/scaffold/scaffold.js +1 -0
  92. package/dist/commands/generate/scaffold/scaffoldHandler.js +176 -49
  93. package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +1 -1
  94. package/dist/commands/generate/script/script.js +1 -0
  95. package/dist/commands/generate/script/scriptHandler.js +10 -6
  96. package/dist/commands/generate/script/templates/script.ts.template +9 -4
  97. package/dist/commands/generate/script/templates/tsconfig.json.template +16 -2
  98. package/dist/commands/generate/sdl/sdl.js +4 -3
  99. package/dist/commands/generate/sdl/sdlHandler.js +135 -46
  100. package/dist/commands/generate/sdl/stubFiles.js +132 -0
  101. package/dist/commands/generate/sdl/templates/sdl.js.template +2 -1
  102. package/dist/commands/generate/sdl/templates/sdl.ts.template +2 -1
  103. package/dist/commands/generate/secret/secret.js +20 -20
  104. package/dist/commands/generate/service/service.js +5 -5
  105. package/dist/commands/generate/service/serviceHandler.js +126 -61
  106. package/dist/commands/generate/service/templates/scenarios.ts.template +4 -2
  107. package/dist/commands/generate/service/templates/service.ts.template +22 -8
  108. package/dist/commands/generate/service/templates/test.ts.template +2 -2
  109. package/dist/commands/generate/yargsCommandHelpers.js +7 -2
  110. package/dist/commands/generate/yargsHandlerHelpers.js +20 -18
  111. package/dist/commands/generate.js +4 -4
  112. package/dist/commands/info.js +2 -2
  113. package/dist/commands/jobsHandler.js +7 -4
  114. package/dist/commands/lint.js +26 -69
  115. package/dist/commands/prerenderHandler.js +95 -58
  116. package/dist/commands/prismaHandler.js +51 -26
  117. package/dist/commands/record/init.js +2 -2
  118. package/dist/commands/record.js +4 -3
  119. package/dist/commands/serve.js +245 -31
  120. package/dist/commands/serveApiHandler.js +7 -6
  121. package/dist/commands/serveBothHandler.js +22 -13
  122. package/dist/commands/serveWebHandler.js +3 -2
  123. package/dist/commands/setup/auth/auth.js +15 -11
  124. package/dist/commands/setup/cache/cache.js +1 -1
  125. package/dist/commands/setup/cache/cacheHandler.js +15 -9
  126. package/dist/commands/setup/database/database.js +15 -0
  127. package/dist/commands/setup/database/postgres.js +19 -0
  128. package/dist/commands/setup/database/postgresHandler.js +196 -0
  129. package/dist/commands/setup/database/templates/db.ts.template +32 -0
  130. package/dist/commands/setup/deploy/deploy.js +4 -3
  131. package/dist/commands/setup/deploy/helpers/helpers.js +5 -1
  132. package/dist/commands/setup/deploy/helpers/index.js +132 -6
  133. package/dist/commands/setup/deploy/providers/baremetalHandler.js +28 -6
  134. package/dist/commands/setup/deploy/providers/coherence.js +1 -1
  135. package/dist/commands/setup/deploy/providers/coherenceHandler.js +60 -31
  136. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +69 -51
  137. package/dist/commands/setup/deploy/providers/netlify.js +6 -0
  138. package/dist/commands/setup/deploy/providers/netlifyHandler.js +114 -13
  139. package/dist/commands/setup/deploy/providers/renderHandler.js +44 -41
  140. package/dist/commands/setup/deploy/providers/serverlessHandler.js +7 -5
  141. package/dist/commands/setup/deploy/providers/universal-deploy.js +11 -0
  142. package/dist/commands/setup/deploy/providers/universalDeployHandler.js +186 -0
  143. package/dist/commands/setup/deploy/providers/vercel.js +6 -0
  144. package/dist/commands/setup/deploy/providers/vercelHandler.js +115 -14
  145. package/dist/commands/setup/deploy/templates/baremetal.js +3 -2
  146. package/dist/commands/setup/deploy/templates/flightcontrol.js +60 -49
  147. package/dist/commands/setup/deploy/templates/netlify.js +2 -1
  148. package/dist/commands/setup/deploy/templates/netlifyUD.js +31 -0
  149. package/dist/commands/setup/deploy/templates/render.js +32 -17
  150. package/dist/commands/setup/docker/docker.js +2 -2
  151. package/dist/commands/setup/docker/dockerHandler.js +74 -39
  152. package/dist/commands/setup/docker/templates/Dockerfile.npm +119 -0
  153. package/dist/commands/setup/docker/templates/Dockerfile.pnpm +112 -0
  154. package/dist/commands/setup/docker/templates/{Dockerfile → Dockerfile.yarn} +4 -7
  155. package/dist/commands/setup/docker/templates/docker-compose.dev.yml +3 -3
  156. package/dist/commands/setup/docker/templates/docker-compose.prod.yml +2 -5
  157. package/dist/commands/setup/docker/templates/dockerignore +1 -0
  158. package/dist/commands/setup/generator/generator.js +1 -1
  159. package/dist/commands/setup/generator/generatorHandler.js +5 -4
  160. package/dist/commands/setup/graphql/features/fragments/appGqlConfigTransform.js +6 -3
  161. package/dist/commands/setup/graphql/features/fragments/fragments.js +1 -1
  162. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +5 -7
  163. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +1 -1
  164. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +4 -3
  165. package/dist/commands/setup/i18n/i18n.js +1 -1
  166. package/dist/commands/setup/i18n/i18nHandler.js +21 -17
  167. package/dist/commands/setup/jobs/jobs.js +1 -1
  168. package/dist/commands/setup/jobs/jobsHandler.js +17 -12
  169. package/dist/commands/setup/mailer/mailer.js +1 -1
  170. package/dist/commands/setup/mailer/mailerHandler.js +13 -11
  171. package/dist/commands/setup/middleware/ogImage/ogImage.js +1 -1
  172. package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +2 -1
  173. package/dist/commands/setup/monitoring/sentry/sentry.js +1 -1
  174. package/dist/commands/setup/monitoring/sentry/sentryHandler.js +18 -12
  175. package/dist/commands/setup/neon/neon.js +35 -0
  176. package/dist/commands/setup/neon/neonHandler.js +264 -0
  177. package/dist/commands/setup/package/package.js +1 -1
  178. package/dist/commands/setup/package/packageHandler.js +18 -14
  179. package/dist/commands/setup/realtime/addRealtimeToGraphql.js +1 -1
  180. package/dist/commands/setup/realtime/realtime.js +1 -1
  181. package/dist/commands/setup/realtime/realtimeHandler.js +26 -37
  182. package/dist/commands/setup/realtime/templates/realtime.ts.template +1 -1
  183. package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +1 -1
  184. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +1 -1
  185. package/dist/commands/setup/server-file/serverFile.js +1 -1
  186. package/dist/commands/setup/server-file/serverFileHandler.js +18 -10
  187. package/dist/commands/setup/tenancy/authCodemod.js +66 -0
  188. package/dist/commands/setup/tenancy/dbCodemod.js +64 -0
  189. package/dist/commands/setup/tenancy/graphqlCodemod.js +88 -0
  190. package/dist/commands/setup/tenancy/preflight.js +49 -0
  191. package/dist/commands/setup/tenancy/schemaPrisma.js +81 -0
  192. package/dist/commands/setup/tenancy/signupCodemod.js +153 -0
  193. package/dist/commands/setup/tenancy/templates/InvitePage.tsx.template +63 -0
  194. package/dist/commands/setup/tenancy/templates/OrgScope.tsx.template +40 -0
  195. package/dist/commands/setup/tenancy/templates/ensureDefaultOrganizations.dataMigration.ts.template +39 -0
  196. package/dist/commands/setup/tenancy/templates/organizations.scenarios.ts.template +59 -0
  197. package/dist/commands/setup/tenancy/templates/organizations.sdl.ts.template +89 -0
  198. package/dist/commands/setup/tenancy/templates/organizations.test.ts.template +389 -0
  199. package/dist/commands/setup/tenancy/templates/organizations.ts.template +394 -0
  200. package/dist/commands/setup/tenancy/templates/requireMembership.test.ts.template +35 -0
  201. package/dist/commands/setup/tenancy/templates/requireMembership.ts.template +25 -0
  202. package/dist/commands/setup/tenancy/tenancy.js +30 -0
  203. package/dist/commands/setup/tenancy/tenancyHandler.js +425 -0
  204. package/dist/commands/setup/ui/helpers/helpers.js +5 -1
  205. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +16 -8
  206. package/dist/commands/setup/ui/libraries/mantineHandler.js +26 -16
  207. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +40 -29
  208. package/dist/commands/setup/uploads/schemaPrisma.js +41 -0
  209. package/dist/commands/setup/uploads/serverFile.js +151 -0
  210. package/dist/commands/setup/uploads/templates/requireUploadToken.ts.template +15 -0
  211. package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +23 -24
  212. package/dist/commands/setup/uploads/templates/uploads.sdl.ts.template +79 -0
  213. package/dist/commands/setup/uploads/templates/uploads.ts.template +89 -0
  214. package/dist/commands/setup/uploads/templates/withDataUri.ts.template +14 -0
  215. package/dist/commands/setup/uploads/templates/withSignedUrl.ts.template +16 -0
  216. package/dist/commands/setup/uploads/uploads.js +49 -7
  217. package/dist/commands/setup/uploads/uploadsHandler.js +266 -72
  218. package/dist/commands/setup.js +5 -4
  219. package/dist/commands/studio.js +1 -1
  220. package/dist/commands/studioHandler.js +2 -2
  221. package/dist/commands/test/datasourceWarning.js +42 -0
  222. package/dist/commands/test/testHandler.js +104 -0
  223. package/dist/commands/test/viteVersionCheck.js +75 -0
  224. package/dist/commands/test.js +16 -19
  225. package/dist/commands/type-check.js +2 -1
  226. package/dist/commands/type-checkHandler.js +25 -18
  227. package/dist/commands/upgrade/preUpgradeScripts.js +11 -11
  228. package/dist/commands/upgrade/upgrade.js +4 -2
  229. package/dist/commands/upgrade/upgradeHandler.js +97 -73
  230. package/dist/index.js +15 -11
  231. package/dist/lib/background.js +22 -1
  232. package/dist/lib/configureStorybook.js +2 -2
  233. package/dist/lib/exec.js +68 -63
  234. package/dist/lib/exit.js +20 -5
  235. package/dist/lib/extendFile.js +23 -13
  236. package/dist/lib/generatePrismaClient.js +48 -12
  237. package/dist/lib/index.js +137 -106
  238. package/dist/lib/loadEnvFiles.js +1 -1
  239. package/dist/lib/locking.js +8 -4
  240. package/dist/lib/merge/algorithms.js +4 -1
  241. package/dist/lib/merge/index.js +78 -41
  242. package/dist/lib/merge/semanticIdentity.js +18 -6
  243. package/dist/lib/merge/strategy.js +86 -36
  244. package/dist/lib/packages.js +23 -13
  245. package/dist/lib/plugin.js +13 -7
  246. package/dist/lib/pluralHelpers.js +6 -2
  247. package/dist/lib/project.js +3 -1
  248. package/dist/lib/rollback.js +7 -7
  249. package/dist/lib/schemaHelpers.js +16 -19
  250. package/dist/lib/test.js +20 -5
  251. package/dist/lib/updateCheck.js +47 -18
  252. package/dist/middleware/checkNodeVersion.js +9 -4
  253. package/dist/middleware/{detectProjectRxVersion.js → detectProjectCedarVersion.js} +2 -2
  254. package/dist/plugin.js +18 -12
  255. package/dist/telemetry/exporter.js +12 -5
  256. package/dist/telemetry/index.js +4 -3
  257. package/dist/telemetry/resource.js +9 -12
  258. package/dist/telemetry/send.js +14 -10
  259. package/dist/testLib/cells.js +5 -3
  260. package/package.json +44 -41
  261. package/LICENSE +0 -21
  262. package/dist/commands/consoleHandler.js +0 -68
  263. package/dist/commands/setup/tsconfig/tsconfig.js +0 -25
  264. package/dist/commands/setup/tsconfig/tsconfigHandler.js +0 -59
  265. package/dist/commands/setup/uploads/dbCodemod.js +0 -28
  266. package/dist/commands/setup/uploads/templates/signedUrl.ts.template +0 -21
  267. package/dist/commands/setup/vite/templates/vite.config.ts.template +0 -19
  268. package/dist/commands/setup/vite/vite.js +0 -38
  269. package/dist/commands/setup/vite/viteHandler.js +0 -83
  270. package/dist/commands/testEsm.js +0 -36
  271. package/dist/commands/testHandler.js +0 -137
  272. package/dist/commands/testHandlerEsm.js +0 -85
  273. package/dist/commands/ts-to-js.js +0 -20
  274. package/dist/lib/cedarPluralize.js +0 -56
  275. package/dist/lib/colors.js +0 -18
  276. package/dist/testLib/getFilesWithPattern.js +0 -21
  277. /package/dist/{index.d.js → global.d.js} +0 -0
@@ -1,23 +1,15 @@
1
- import fs from "node:fs";
2
1
  import path from "path";
3
2
  import prismaInternals from "@prisma/internals";
4
3
  import { Listr } from "listr2";
5
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
4
+ import prompts from "prompts";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
7
+ import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
6
8
  import { errorTelemetry } from "@cedarjs/telemetry";
7
- import c from "../../../../lib/colors.js";
8
- import {
9
- getPaths,
10
- writeFilesTask,
11
- printSetupNotes
12
- } from "../../../../lib/index.js";
13
- import { addFilesTask, updateApiURLTask } from "../helpers/index.js";
14
- import {
15
- POSTGRES_YAML,
16
- RENDER_HEALTH_CHECK,
17
- RENDER_YAML,
18
- SQLITE_YAML
19
- } from "../templates/render.js";
20
- const { getSchemaWithPath, getConfig } = prismaInternals;
9
+ import { writeFilesTask, printSetupNotes } from "../../../../lib/index.js";
10
+ import { POSTGRES_YAML, RENDER_YAML, SQLITE_YAML } from "../templates/render.js";
11
+ const { getConfig } = prismaInternals;
12
+ const SQLITE_API_PLAN = "starter";
21
13
  const getRenderYamlContent = async (database) => {
22
14
  if (database === "none") {
23
15
  return {
@@ -25,11 +17,8 @@ const getRenderYamlContent = async (database) => {
25
17
  content: RENDER_YAML("")
26
18
  };
27
19
  }
28
- if (!fs.existsSync("api/db/schema.prisma")) {
29
- throw new Error("Could not find prisma schema at 'api/db/schema.prisma'");
30
- }
31
- const { schemas } = await getSchemaWithPath("api/db/schema.prisma");
32
- const config = await getConfig({ datamodel: schemas });
20
+ const result = await getPrismaSchemas();
21
+ const config = await getConfig({ datamodel: result.schemas });
33
22
  const detectedDatabase = config.datasources[0].activeProvider;
34
23
  if (detectedDatabase === database) {
35
24
  switch (database) {
@@ -41,7 +30,7 @@ const getRenderYamlContent = async (database) => {
41
30
  case "sqlite":
42
31
  return {
43
32
  path: path.join(getPaths().base, "render.yaml"),
44
- content: RENDER_YAML(SQLITE_YAML)
33
+ content: RENDER_YAML(SQLITE_YAML, SQLITE_API_PLAN)
45
34
  };
46
35
  default:
47
36
  throw new Error(`
@@ -62,38 +51,50 @@ const getRenderYamlContent = async (database) => {
62
51
  const notes = [
63
52
  "You are ready to deploy to Render!\n",
64
53
  "Go to https://dashboard.render.com/iacs to create your account and deploy to Render",
65
- "Check out the deployment docs at https://render.com/docs/deploy-redwood for detailed instructions",
66
- "Note: After first deployment to Render update the rewrite rule destination in `./render.yaml`"
67
- ];
68
- const additionalFiles = [
69
- {
70
- path: path.join(getPaths().base, "api/src/functions/healthz.js"),
71
- content: RENDER_HEALTH_CHECK
72
- }
54
+ "Check out the deployment docs at https://cedarjs.com/docs/deploy/render for detailed instructions",
55
+ "Note: After first deployment to Render update the rewrite rule destination in `./render.yaml`",
56
+ "Note: The api service now health checks `/graphql/health`. If a previous setup left an unused `api/src/functions/healthz.js` behind, you can delete it"
73
57
  ];
74
- const handler = async ({ force, database }) => {
58
+ const handler = async ({
59
+ force,
60
+ database
61
+ }) => {
75
62
  recordTelemetryAttributes({
76
63
  command: "setup deploy render",
77
64
  force,
78
65
  database
79
66
  });
67
+ if (database === "sqlite") {
68
+ console.warn(
69
+ c.warning(
70
+ `Render's free plan doesn't support persistent disks, which the \`sqlite\` deploy option requires for its database file. The generated render.yaml will set the api service's plan to "${SQLITE_API_PLAN}" (a paid plan) instead of "free" so the disk can actually attach.
71
+
72
+ If you want to stay on the free plan, rerun this command with \`--database postgresql\` (a managed database, not a disk) or \`--database none\`.`
73
+ )
74
+ );
75
+ console.log();
76
+ const { confirmed } = await prompts({
77
+ type: "confirm",
78
+ name: "confirmed",
79
+ message: `Generate render.yaml with the api service on the "${SQLITE_API_PLAN}" plan?`
80
+ });
81
+ if (!confirmed) {
82
+ console.log("Aborting render setup.");
83
+ return;
84
+ }
85
+ console.log();
86
+ }
80
87
  const tasks = new Listr(
81
88
  [
82
89
  {
83
90
  title: "Adding render.yaml",
84
91
  task: async () => {
85
92
  const fileData = await getRenderYamlContent(database);
86
- let files = {};
93
+ const files = {};
87
94
  files[fileData.path] = fileData.content;
88
95
  return writeFilesTask(files, { overwriteExisting: force });
89
96
  }
90
97
  },
91
- updateApiURLTask("/.redwood/functions"),
92
- // Add health check api function
93
- addFilesTask({
94
- files: additionalFiles,
95
- force
96
- }),
97
98
  printSetupNotes(notes)
98
99
  ],
99
100
  { rendererOptions: { collapseSubtasks: false } }
@@ -101,9 +102,11 @@ const handler = async ({ force, database }) => {
101
102
  try {
102
103
  await tasks.run();
103
104
  } catch (e) {
104
- errorTelemetry(process.argv, e.message);
105
- console.error(c.error(e.message));
106
- process.exit(e?.exitCode || 1);
105
+ const message = e instanceof Error ? e.message : String(e);
106
+ errorTelemetry(process.argv, message);
107
+ console.error(c.error(message));
108
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
109
+ process.exit(exitCode);
107
110
  }
108
111
  };
109
112
  export {
@@ -1,10 +1,10 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { Listr } from "listr2";
4
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
4
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
5
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
5
6
  import { getSchemaPath, getConfigPath } from "@cedarjs/project-config";
6
7
  import { errorTelemetry } from "@cedarjs/telemetry";
7
- import c from "../../../../lib/colors.js";
8
8
  import {
9
9
  addPackagesTask,
10
10
  getPaths,
@@ -133,9 +133,11 @@ const handler = async ({ force }) => {
133
133
  try {
134
134
  await tasks.run();
135
135
  } catch (e) {
136
- errorTelemetry(process.argv, e.message);
137
- console.error(c.error(e.message));
138
- process.exit(e?.exitCode || 1);
136
+ const message = e instanceof Error ? e.message : String(e);
137
+ errorTelemetry(process.argv, message);
138
+ console.error(c.error(message));
139
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
140
+ process.exit(exitCode);
139
141
  }
140
142
  };
141
143
  export {
@@ -0,0 +1,11 @@
1
+ const command = "universal-deploy";
2
+ const description = "Setup Universal Deploy";
3
+ async function handler() {
4
+ const { handler: handler2 } = await import("./universalDeployHandler.js");
5
+ return handler2();
6
+ }
7
+ export {
8
+ command,
9
+ description,
10
+ handler
11
+ };
@@ -0,0 +1,186 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { Listr } from "listr2";
4
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
5
+ import { getPaths } from "@cedarjs/cli-helpers/paths";
6
+ import { isTypeScriptProject } from "@cedarjs/cli-helpers/project";
7
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
8
+ import { errorTelemetry } from "@cedarjs/telemetry";
9
+ import { printSetupNotes } from "../../../../lib/index.js";
10
+ const notes = [
11
+ "Universal Deploy is set up!",
12
+ "",
13
+ "Next steps:",
14
+ ` ${c.highlight("yarn cedar build --ud")} \u2014 build the Universal Deploy server entry`,
15
+ ` ${c.highlight("yarn cedar serve --ud")} \u2014 serve it locally`,
16
+ "",
17
+ "To deploy, pick a deployment target, for example:",
18
+ ` ${c.highlight("yarn cedar setup deploy netlify --ud")}`,
19
+ ` ${c.highlight("yarn cedar setup deploy vercel --ud")}`,
20
+ "",
21
+ "See: https://cedarjs.com/docs/deploy/universal-deploy"
22
+ ];
23
+ async function handler() {
24
+ recordTelemetryAttributes({
25
+ command: "setup deploy universal-deploy"
26
+ });
27
+ const tasks = new Listr(
28
+ [addUniversalDeployPluginToViteConfig(), printSetupNotes(notes)],
29
+ { rendererOptions: { collapseSubtasks: false } }
30
+ );
31
+ try {
32
+ await tasks.run();
33
+ } catch (e) {
34
+ errorTelemetry(process.argv, e.message);
35
+ console.error(c.error(e.message));
36
+ process.exit(e.exitCode || 1);
37
+ }
38
+ }
39
+ function addUniversalDeployPluginToViteConfig() {
40
+ return {
41
+ title: "Adding cedarUniversalDeployPlugin to vite config...",
42
+ task: async (_ctx, task) => {
43
+ const projectIsTS = isTypeScriptProject();
44
+ const viteConfigPath = path.join(
45
+ getPaths().web.base,
46
+ `vite.config.${projectIsTS ? "ts" : "js"}`
47
+ );
48
+ if (!fs.existsSync(viteConfigPath)) {
49
+ task.skip(`${viteConfigPath} not found`);
50
+ return;
51
+ }
52
+ let content = fs.readFileSync(viteConfigPath, "utf-8");
53
+ if (content.includes("cedarUniversalDeployPlugin")) {
54
+ task.skip("cedarUniversalDeployPlugin is already configured.");
55
+ return;
56
+ }
57
+ content = mergeImport(content);
58
+ content = addPluginToConfig(content);
59
+ fs.writeFileSync(viteConfigPath, content);
60
+ }
61
+ };
62
+ }
63
+ function findCedarViteImportLine(lines) {
64
+ for (let i = 0; i < lines.length; i++) {
65
+ if (/^import\b/.test(lines[i]) && /from\s+['"]@cedarjs\/vite['"]/.test(lines[i])) {
66
+ return i;
67
+ }
68
+ }
69
+ for (let i = 0; i < lines.length; i++) {
70
+ if (/from\s+['"]@cedarjs\/vite['"]/.test(lines[i])) {
71
+ for (let j = i; j >= 0; j--) {
72
+ if (/^import\b/.test(lines[j])) {
73
+ return j;
74
+ }
75
+ }
76
+ return i;
77
+ }
78
+ }
79
+ return -1;
80
+ }
81
+ function mergeImport(content) {
82
+ const lines = content.split("\n");
83
+ const importIndex = findCedarViteImportLine(lines);
84
+ if (importIndex === -1) {
85
+ throw new Error("No import from @cedarjs/vite found");
86
+ }
87
+ const importLine = lines[importIndex];
88
+ const singleLineNamed = importLine.match(
89
+ /^(import\s*\{\s*)([^}]*?)(\s*\}\s*from\s+['"]@cedarjs\/vite['"];?)$/
90
+ );
91
+ if (singleLineNamed) {
92
+ const specifiers = singleLineNamed[2].trim();
93
+ if (specifiers.includes("cedarUniversalDeployPlugin")) {
94
+ return content;
95
+ }
96
+ lines[importIndex] = specifiers ? `${singleLineNamed[1]}${specifiers}, cedarUniversalDeployPlugin${singleLineNamed[3]}` : `${singleLineNamed[1]}cedarUniversalDeployPlugin${singleLineNamed[3]}`;
97
+ return lines.join("\n");
98
+ }
99
+ let closeIndex = importIndex;
100
+ for (let i = importIndex + 1; i < lines.length; i++) {
101
+ if (/}\s*from\s+['"]@cedarjs\/vite['"]/.test(lines[i])) {
102
+ closeIndex = i;
103
+ break;
104
+ }
105
+ }
106
+ if (closeIndex > importIndex) {
107
+ const specifiersLines = lines.slice(importIndex + 1, closeIndex);
108
+ const allSpecifiers = specifiersLines.join(" ");
109
+ if (allSpecifiers.includes("cedarUniversalDeployPlugin")) {
110
+ return content;
111
+ }
112
+ const indentMatch = specifiersLines[0]?.match(/^(\s+)/);
113
+ const indent = indentMatch?.[1] || " ";
114
+ lines.splice(closeIndex, 0, `${indent}cedarUniversalDeployPlugin,`);
115
+ return lines.join("\n");
116
+ }
117
+ const defaultMatch = importLine.match(
118
+ /^import\s+(\w+)\s+from\s+['"]@cedarjs\/vite['"];?\s*$/
119
+ );
120
+ if (defaultMatch) {
121
+ lines[importIndex] = importLine.replace(
122
+ /(import\s+\w+)(\s+from\s+['"]@cedarjs\/vite['"];?)/,
123
+ "$1, { cedarUniversalDeployPlugin }$2"
124
+ );
125
+ return lines.join("\n");
126
+ }
127
+ return content;
128
+ }
129
+ function addPluginToConfig(content) {
130
+ const lines = content.split("\n");
131
+ const pluginsLineIndex = lines.findIndex(
132
+ (line) => /plugins\s*:\s*\[/.test(line)
133
+ );
134
+ if (pluginsLineIndex === -1) {
135
+ return content;
136
+ }
137
+ const pluginsLine = lines[pluginsLineIndex];
138
+ const inlineMatch = pluginsLine.trim().match(/^plugins\s*:\s*\[([\s\S]*?)\]\s*,?\s*$/);
139
+ if (inlineMatch) {
140
+ const inner = inlineMatch[1].trimEnd();
141
+ const indentation = pluginsLine.match(/^\s*/)?.[0] || " ";
142
+ lines[pluginsLineIndex] = inner ? `${indentation}plugins: [${inner}, cedarUniversalDeployPlugin()],` : `${indentation}plugins: [cedarUniversalDeployPlugin()],`;
143
+ return lines.join("\n");
144
+ }
145
+ let closeIndex = -1;
146
+ for (let i = pluginsLineIndex + 1; i < lines.length; i++) {
147
+ const trimmed = lines[i].trim();
148
+ if (trimmed === "]" || trimmed === "],") {
149
+ closeIndex = i;
150
+ break;
151
+ }
152
+ }
153
+ if (closeIndex === -1) {
154
+ return content;
155
+ }
156
+ const pluginsLineIndent = pluginsLine.match(/^\s*/)?.[0] || "";
157
+ const firstEntryIndent = (() => {
158
+ for (let i = pluginsLineIndex + 1; i < closeIndex; i++) {
159
+ const trimmed = lines[i].trim();
160
+ if (trimmed) {
161
+ return lines[i].match(/^\s*/)?.[0] || " ";
162
+ }
163
+ }
164
+ return pluginsLineIndent + " ";
165
+ })();
166
+ const prevLine = lines[closeIndex - 1]?.trimEnd();
167
+ if (prevLine && !prevLine.endsWith(",") && prevLine !== "[" && !prevLine.endsWith("[")) {
168
+ const commentIdx = prevLine.search(/\s+\/\/|(?<!\\)\/\*/);
169
+ if (commentIdx !== -1) {
170
+ lines[closeIndex - 1] = prevLine.slice(0, commentIdx) + "," + prevLine.slice(commentIdx);
171
+ } else {
172
+ lines[closeIndex - 1] = prevLine + ",";
173
+ }
174
+ }
175
+ lines.splice(
176
+ closeIndex,
177
+ 0,
178
+ `${firstEntryIndent}cedarUniversalDeployPlugin(),`
179
+ );
180
+ return lines.join("\n");
181
+ }
182
+ export {
183
+ addPluginToConfig,
184
+ handler,
185
+ mergeImport
186
+ };
@@ -1,8 +1,14 @@
1
1
  import { createHandler } from "../helpers/helpers.js";
2
2
  const command = "vercel";
3
3
  const description = "Setup Vercel deploy";
4
+ const builder = (yargs) => yargs.option("ud", {
5
+ description: "Setup for use with Universal Deploy",
6
+ type: "boolean",
7
+ default: false
8
+ });
4
9
  const handler = createHandler("vercel");
5
10
  export {
11
+ builder,
6
12
  command,
7
13
  description,
8
14
  handler
@@ -1,20 +1,36 @@
1
+ import fs from "node:fs";
1
2
  import path from "path";
2
3
  import { Listr } from "listr2";
3
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
4
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
5
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
6
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
4
7
  import { errorTelemetry } from "@cedarjs/telemetry";
5
- import c from "../../../../lib/colors.js";
6
- import { getPaths, printSetupNotes, writeFile } from "../../../../lib/index.js";
7
- import { updateApiURLTask } from "../helpers/index.js";
8
- async function handler(options) {
8
+ import {
9
+ addPackagesTask,
10
+ getPaths,
11
+ printSetupNotes,
12
+ writeFile
13
+ } from "../../../../lib/index.js";
14
+ import {
15
+ insertPluginsBeforeCedar,
16
+ updateApiURLTask,
17
+ verifyUDSetupTask
18
+ } from "../helpers/index.js";
19
+ async function handler({ force, ud }) {
9
20
  recordTelemetryAttributes({
10
- command: "setup deploy vercel"
21
+ command: "setup deploy vercel",
22
+ force,
23
+ ud
11
24
  });
12
25
  const tasks = new Listr(
13
26
  [
14
- updateApiURLTask("/api"),
15
- writeVercelConfigTask({ overwriteExisting: options.force }),
16
- printSetupNotes(notes)
17
- ],
27
+ ud && verifyUDSetupTask(),
28
+ ud && await installVercelPackagesTask(),
29
+ ud && addVercelPluginToViteConfigTask(),
30
+ !ud && updateApiURLTask("/api"),
31
+ ud ? writeVercelUDConfigTask({ overwriteExisting: force }) : writeVercelConfigTask({ overwriteExisting: force }),
32
+ printSetupNotes(ud ? udNotes : notes)
33
+ ].filter((task) => Boolean(task)),
18
34
  {
19
35
  rendererOptions: { collapseSubtasks: false }
20
36
  }
@@ -22,12 +38,64 @@ async function handler(options) {
22
38
  try {
23
39
  await tasks.run();
24
40
  } catch (e) {
25
- errorTelemetry(process.argv, e.message);
26
- console.error(c.error(e.message));
27
- process.exit(e?.exitCode || 1);
41
+ const message = e instanceof Error ? e.message : String(e);
42
+ errorTelemetry(process.argv, message);
43
+ console.error(c.error(message));
44
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
45
+ process.exit(exitCode);
28
46
  }
29
47
  }
30
- function writeVercelConfigTask({ overwriteExisting = false } = {}) {
48
+ function addVercelPluginToViteConfigTask() {
49
+ return {
50
+ title: "Adding Vercel plugin to vite config...",
51
+ task: async (_ctx, task) => {
52
+ const paths = getPaths();
53
+ const viteConfigTs = path.join(paths.web.base, "vite.config.ts");
54
+ const viteConfigJs = path.join(paths.web.base, "vite.config.js");
55
+ const viteConfigPath = fs.existsSync(viteConfigTs) ? viteConfigTs : viteConfigJs;
56
+ if (!fs.existsSync(viteConfigPath)) {
57
+ task.skip(`${viteConfigPath} not found`);
58
+ return;
59
+ }
60
+ let content = fs.readFileSync(viteConfigPath, "utf-8");
61
+ const hasVercelPlugin = content.includes("vite-plugin-vercel");
62
+ if (hasVercelPlugin && content.includes("vercel(")) {
63
+ task.skip("Vercel plugin is already configured.");
64
+ return;
65
+ }
66
+ if (!hasVercelPlugin) {
67
+ const newContent = content.replace(
68
+ /(import\s+\{[^}]*\}\s+from\s+['"]vite['"];?)/,
69
+ "import { vercel } from 'vite-plugin-vercel/vite'\n$1"
70
+ );
71
+ if (newContent === content) {
72
+ content = "import { vercel } from 'vite-plugin-vercel/vite'\n" + content;
73
+ } else {
74
+ content = newContent;
75
+ }
76
+ }
77
+ if (!content.includes("vercel(")) {
78
+ const result = insertPluginsBeforeCedar({
79
+ content,
80
+ pluginCodes: ["vercel({ outDir: '../.vercel/output' })"]
81
+ });
82
+ if (result) {
83
+ content = result;
84
+ }
85
+ }
86
+ fs.writeFileSync(viteConfigPath, content);
87
+ }
88
+ };
89
+ }
90
+ function installVercelPackagesTask() {
91
+ return addPackagesTask({
92
+ packages: ["vite-plugin-vercel"],
93
+ devDependency: true
94
+ });
95
+ }
96
+ function writeVercelConfigTask({
97
+ overwriteExisting = false
98
+ } = {}) {
31
99
  return {
32
100
  title: "Writing vercel.json...",
33
101
  task: (_ctx, task) => {
@@ -51,6 +119,39 @@ const notes = [
51
119
  "You are ready to deploy to Vercel!",
52
120
  "See: https://cedarjs.com/docs/deploy#vercel-deploy"
53
121
  ];
122
+ const udNotes = [
123
+ "You are ready to deploy to Vercel with Universal Deploy!",
124
+ `Build with: ${formatCedarCommand(["build", "--ud"])}`,
125
+ "See: https://cedarjs.com/docs/deploy#vercel-deploy"
126
+ ];
127
+ function writeVercelUDConfigTask({
128
+ overwriteExisting = false
129
+ } = {}) {
130
+ const config = {
131
+ build: {
132
+ command: formatCedarCommand([
133
+ "build",
134
+ "--ud",
135
+ "--verbose",
136
+ "--apiRootPath=/.api/functions"
137
+ ]),
138
+ env: {
139
+ ENABLE_EXPERIMENTAL_COREPACK: "1"
140
+ }
141
+ }
142
+ };
143
+ return {
144
+ title: "Writing vercel.json for Universal Deploy...",
145
+ task: (_ctx, task) => {
146
+ writeFile(
147
+ path.join(getPaths().base, "vercel.json"),
148
+ JSON.stringify(config, null, 2),
149
+ { overwriteExisting },
150
+ task
151
+ );
152
+ }
153
+ };
154
+ }
54
155
  export {
55
156
  handler
56
157
  };
@@ -1,9 +1,10 @@
1
+ import { getPackageManager } from "@cedarjs/project-config/packageManager";
1
2
  const ECOSYSTEM = `module.exports = {
2
3
  apps: [
3
4
  {
4
5
  name: 'serve',
5
6
  cwd: 'current',
6
- script: 'node_modules/.bin/rw',
7
+ script: 'node_modules/.bin/cedar',
7
8
  args: 'serve',
8
9
  instances: 'max',
9
10
  exec_mode: 'cluster',
@@ -32,7 +33,7 @@ host = "server.com"
32
33
  username = "user"
33
34
  agentForward = true
34
35
  sides = ["api","web"]
35
- packageManagerCommand = "yarn"
36
+ packageManagerCommand = "${getPackageManager()}"
36
37
  monitorCommand = "pm2"
37
38
  path = "/var/www/app"
38
39
  processNames = ["serve"]
@@ -1,55 +1,66 @@
1
- const flightcontrolConfig = {
2
- $schema: "https://app.flightcontrol.dev/schema.json",
3
- environments: [
4
- {
5
- id: "development",
6
- name: "Development",
7
- region: "us-east-1",
8
- source: {
9
- branch: "main"
10
- },
11
- services: [
12
- {
13
- id: "redwood-api",
14
- name: "Redwood API",
15
- type: "web",
16
- buildType: "nixpacks",
17
- cpu: 0.5,
18
- memory: 1,
19
- buildCommand: "yarn cedar deploy flightcontrol api",
20
- startCommand: "yarn cedar deploy flightcontrol api --serve",
21
- port: 8911,
22
- healthCheckPath: "/graphql/health",
23
- ci: {
24
- type: "ec2"
25
- },
26
- envVariables: {
27
- REDWOOD_WEB_URL: {
28
- fromService: { id: "redwood-web", value: "origin" }
29
- }
30
- }
1
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
2
+ function getFlightcontrolConfig() {
3
+ const apiBuildCommand = formatCedarCommand(["deploy", "flightcontrol", "api"]);
4
+ const apiStartCommand = formatCedarCommand([
5
+ "deploy",
6
+ "flightcontrol",
7
+ "api",
8
+ "--serve"
9
+ ]);
10
+ const webBuildCommand = formatCedarCommand(["deploy", "flightcontrol", "web"]);
11
+ return {
12
+ $schema: "https://app.flightcontrol.dev/schema.json",
13
+ environments: [
14
+ {
15
+ id: "development",
16
+ name: "Development",
17
+ region: "us-east-1",
18
+ source: {
19
+ branch: "main"
31
20
  },
32
- {
33
- id: "redwood-web",
34
- name: "Redwood Web",
35
- type: "static",
36
- buildType: "nixpacks",
37
- singlePageApp: true,
38
- buildCommand: "yarn cedar deploy flightcontrol web",
39
- outputDirectory: "web/dist",
40
- ci: {
41
- type: "ec2"
21
+ services: [
22
+ {
23
+ id: "cedar-api",
24
+ name: "Cedar API",
25
+ type: "web",
26
+ buildType: "nixpacks",
27
+ cpu: 0.5,
28
+ memory: 1,
29
+ buildCommand: apiBuildCommand,
30
+ startCommand: apiStartCommand,
31
+ port: 8911,
32
+ healthCheckPath: "/graphql/health",
33
+ ci: {
34
+ type: "ec2"
35
+ },
36
+ envVariables: {
37
+ CEDAR_WEB_URL: {
38
+ fromService: { id: "cedar-web", value: "origin" }
39
+ }
40
+ }
42
41
  },
43
- envVariables: {
44
- REDWOOD_API_URL: {
45
- fromService: { id: "redwood-api", value: "origin" }
42
+ {
43
+ id: "cedar-web",
44
+ name: "Cedar Web",
45
+ type: "static",
46
+ buildType: "nixpacks",
47
+ singlePageApp: true,
48
+ buildCommand: webBuildCommand,
49
+ outputDirectory: "web/dist",
50
+ ci: {
51
+ type: "ec2"
52
+ },
53
+ envVariables: {
54
+ CEDAR_API_URL: {
55
+ fromService: { id: "cedar-api", value: "origin" }
56
+ }
46
57
  }
47
58
  }
48
- }
49
- ]
50
- }
51
- ]
52
- };
59
+ ]
60
+ }
61
+ ]
62
+ };
63
+ }
53
64
  const postgresDatabaseService = {
54
65
  id: "db",
55
66
  name: "Database",
@@ -79,7 +90,7 @@ const databaseEnvVariables = {
79
90
  };
80
91
  export {
81
92
  databaseEnvVariables,
82
- flightcontrolConfig,
93
+ getFlightcontrolConfig,
83
94
  mysqlDatabaseService,
84
95
  postgresDatabaseService
85
96
  };