@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
@@ -0,0 +1,264 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import execa from "execa";
4
+ import { Listr } from "listr2";
5
+ import prompts from "prompts";
6
+ import { colors } from "@cedarjs/cli-helpers/colors";
7
+ import { installPackages } from "@cedarjs/cli-helpers/installHelpers";
8
+ import { prettyPrintCedarCommand } from "@cedarjs/cli-helpers/packageManager";
9
+ import { getPaths } from "@cedarjs/cli-helpers/paths";
10
+ import { requireTTYOrExit } from "@cedarjs/cli-helpers/tty";
11
+ import { errorTelemetry } from "@cedarjs/telemetry";
12
+ import {
13
+ checkProjectShape,
14
+ getSqliteToPostgresTasks
15
+ } from "../database/postgresHandler.js";
16
+ function isPostgresConnectionString(rawValue) {
17
+ let value = rawValue.trim();
18
+ const quoted = value.match(/^(['"])(.*)\1$/);
19
+ if (quoted) {
20
+ value = quoted[2];
21
+ }
22
+ if (!value) {
23
+ return false;
24
+ }
25
+ try {
26
+ const url = new URL(value);
27
+ return (url.protocol === "postgres:" || url.protocol === "postgresql:") && !!url.hostname;
28
+ } catch {
29
+ return false;
30
+ }
31
+ }
32
+ async function handler({ force, migrations, verbose }) {
33
+ const cedarPaths = getPaths();
34
+ const shape = checkProjectShape(cedarPaths);
35
+ if (!shape.ok) {
36
+ if (shape.alreadyConverted) {
37
+ console.log(colors.note(shape.message));
38
+ return;
39
+ }
40
+ console.error(colors.error(shape.message));
41
+ process.exit(1);
42
+ }
43
+ const envPath = path.join(cedarPaths.base, ".env");
44
+ let hasExistingDatabaseUrl = false;
45
+ if (fs.existsSync(envPath)) {
46
+ const match = fs.readFileSync(envPath, "utf-8").match(/^DATABASE_URL=(.*)$/m);
47
+ hasExistingDatabaseUrl = !!match?.[1] && isPostgresConnectionString(match[1]);
48
+ }
49
+ const skipProvisioning = hasExistingDatabaseUrl && !force;
50
+ const notes = [];
51
+ if (skipProvisioning) {
52
+ notes.push(
53
+ colors.note(
54
+ "DATABASE_URL is already set in .env. Use --force to overwrite."
55
+ )
56
+ );
57
+ }
58
+ let runMigrations = migrations;
59
+ if (!skipProvisioning && runMigrations === void 0) {
60
+ requireTTYOrExit("--migrations or --no-migrations");
61
+ const response = await prompts({
62
+ type: "toggle",
63
+ name: "runMigrations",
64
+ message: "Run Prisma migrations now?",
65
+ initial: true,
66
+ active: "Yes",
67
+ inactive: "No"
68
+ });
69
+ if (response.runMigrations === void 0) {
70
+ process.exit(0);
71
+ }
72
+ runMigrations = response.runMigrations;
73
+ }
74
+ const tasks = new Listr(
75
+ [
76
+ ...getSqliteToPostgresTasks({ dbPath: shape.dbPath }),
77
+ {
78
+ title: "Setting DIRECT_DATABASE_URL in Prisma config",
79
+ skip: () => skipProvisioning,
80
+ task: (ctx, task) => {
81
+ const prismaConfigPathCjs = path.join(
82
+ cedarPaths.api.base,
83
+ "prisma.config.cjs"
84
+ );
85
+ const prismaConfigPathMts = path.join(
86
+ cedarPaths.api.base,
87
+ "prisma.config.mts"
88
+ );
89
+ const configPath = fs.existsSync(prismaConfigPathCjs) ? prismaConfigPathCjs : prismaConfigPathMts;
90
+ const configContent = fs.readFileSync(configPath, "utf-8");
91
+ const datasourceUrlRegex = /(\burl\s*:\s*)env\(["'][^"']*?["']\)/;
92
+ if (!datasourceUrlRegex.test(configContent)) {
93
+ ctx.directDatabaseUrlNotSet = true;
94
+ task.skip(
95
+ "Could not set DIRECT_DATABASE_URL. Please manually set datasource.url in " + configPath
96
+ );
97
+ return;
98
+ }
99
+ fs.writeFileSync(
100
+ configPath,
101
+ configContent.replace(
102
+ datasourceUrlRegex,
103
+ "$1env('DIRECT_DATABASE_URL')"
104
+ )
105
+ );
106
+ }
107
+ },
108
+ {
109
+ title: "Provisioning Neon database",
110
+ skip: () => skipProvisioning,
111
+ task: async (ctx) => {
112
+ const res = await fetch("https://neon.new/api/v1/database", {
113
+ method: "POST",
114
+ headers: { "Content-Type": "application/json" },
115
+ body: JSON.stringify({ ref: "cedarjs" })
116
+ });
117
+ if (!res.ok) {
118
+ throw new Error(`Neon API returned ${res.status} ${res.statusText}`);
119
+ }
120
+ const data = await res.json();
121
+ if (!data.connection_string || !data.expires_at || !data.claim_url) {
122
+ throw new Error(
123
+ "Neon API returned an invalid response\n\n" + JSON.stringify(data, null, 2)
124
+ );
125
+ }
126
+ ctx.databaseUrl = data.connection_string;
127
+ ctx.databaseUrlDirect = data.connection_string.replace(
128
+ "-pooler.",
129
+ "."
130
+ );
131
+ if (ctx.databaseUrlDirect === ctx.databaseUrl) {
132
+ throw new Error(
133
+ 'Could not derive a direct (non-pooler) connection string from the Neon response. Expected the connection string to contain "-pooler." in the hostname.'
134
+ );
135
+ }
136
+ ctx.neonClaimUrl = data.claim_url;
137
+ ctx.neonClaimExpiry = new Date(data.expires_at).toUTCString();
138
+ }
139
+ },
140
+ installPackages,
141
+ {
142
+ title: "Running Prisma migrations",
143
+ skip: (ctx) => {
144
+ if (skipProvisioning) {
145
+ return true;
146
+ }
147
+ if (!runMigrations) {
148
+ return migrations === false ? "Skipped (--no-migrations)" : "Skipped";
149
+ }
150
+ if (ctx.directDatabaseUrlNotSet) {
151
+ return `Skipping migrations \u2014 could not confirm prisma.config is reading DIRECT_DATABASE_URL, so migrations could target the wrong database. Fix datasource.url, then run \`${prettyPrintCedarCommand(["prisma", "migrate", "dev"])}\` manually.`;
152
+ }
153
+ return false;
154
+ },
155
+ task: (ctx) => {
156
+ const result = execa.commandSync(
157
+ "yarn cedar prisma migrate dev --name init-neon",
158
+ {
159
+ cwd: cedarPaths.base,
160
+ stdio: verbose ? "inherit" : ["inherit", "inherit", "pipe"],
161
+ reject: false,
162
+ env: {
163
+ ...process.env,
164
+ DIRECT_DATABASE_URL: ctx.databaseUrlDirect
165
+ }
166
+ }
167
+ );
168
+ if (result.exitCode !== 0) {
169
+ throw new Error(
170
+ verbose ? `Prisma migration failed. You can try running it manually:
171
+ ${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}` : "Prisma migration failed:\n\n" + result.stderr + `
172
+
173
+ You can try running it manually:
174
+ ${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}`
175
+ );
176
+ }
177
+ }
178
+ },
179
+ {
180
+ title: "Writing database connection to .env",
181
+ // Deliberately runs after migrations, not before — with
182
+ // `exitOnError: true`, a migration failure stops the list here and
183
+ // this task never runs. That means a project whose migrations
184
+ // failed never has DATABASE_URL/DIRECT_DATABASE_URL written to
185
+ // .env, so it's never left pointing at a Neon database it doesn't
186
+ // know it needs to claim. Provisioning that database anyway (and
187
+ // letting it expire unclaimed) is fine — it's exactly as if the
188
+ // command were re-run from scratch, which is safe.
189
+ skip: () => skipProvisioning,
190
+ task: (ctx) => {
191
+ let envContent = "";
192
+ if (fs.existsSync(envPath)) {
193
+ envContent = fs.readFileSync(envPath, "utf-8");
194
+ const lines = envContent.split("\n");
195
+ const filtered = lines.filter(
196
+ (line) => !line.startsWith("DATABASE_URL=") && !line.startsWith("DIRECT_DATABASE_URL=")
197
+ );
198
+ envContent = filtered.join("\n").trimEnd();
199
+ if (envContent && !envContent.endsWith("\n")) {
200
+ envContent += "\n";
201
+ }
202
+ }
203
+ envContent += `DATABASE_URL=${ctx.databaseUrl}
204
+ `;
205
+ envContent += `DIRECT_DATABASE_URL=${ctx.databaseUrlDirect}
206
+ `;
207
+ fs.writeFileSync(envPath, envContent);
208
+ }
209
+ },
210
+ {
211
+ title: "One more thing...",
212
+ task: (ctx, task) => {
213
+ if (skipProvisioning) {
214
+ task.output = "Skipped \u2014 DATABASE_URL already configured";
215
+ return;
216
+ }
217
+ const claimMsg = [
218
+ colors.important(
219
+ "Your Neon database has been created and is ready to use!"
220
+ ),
221
+ "",
222
+ `Claim URL: ${colors.underline(ctx.neonClaimUrl || "N/A")}`,
223
+ `Expires: ${ctx.neonClaimExpiry || "N/A"}`,
224
+ "",
225
+ "Claim your database to keep it beyond the expiration date."
226
+ ];
227
+ notes.push(...claimMsg);
228
+ }
229
+ }
230
+ ],
231
+ {
232
+ // Migrations run before .env is written (see above) specifically so
233
+ // that a failure here — the one step that shouldn't be allowed to
234
+ // continue — stops the whole list via the default exitOnError
235
+ // behavior, rather than needing every later task to know to skip.
236
+ exitOnError: true
237
+ }
238
+ );
239
+ try {
240
+ await tasks.run();
241
+ if (notes.length > 0) {
242
+ console.log();
243
+ console.log(notes.join("\n"));
244
+ }
245
+ } catch (e) {
246
+ if (isErrorWithMessage(e)) {
247
+ errorTelemetry(process.argv, e.message);
248
+ console.error(colors.error(e.message));
249
+ }
250
+ if (isErrorWithExitCode(e)) {
251
+ process.exit(e.exitCode);
252
+ }
253
+ process.exit(1);
254
+ }
255
+ }
256
+ function isErrorWithMessage(e) {
257
+ return !!e && typeof e === "object" && "message" in e;
258
+ }
259
+ function isErrorWithExitCode(e) {
260
+ return !!e && typeof e === "object" && "exitCode" in e && typeof e.exitCode === "number";
261
+ }
262
+ export {
263
+ handler
264
+ };
@@ -1,5 +1,5 @@
1
1
  import { terminalLink } from "termi-link";
2
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
2
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
3
3
  const command = "package <npm-package>";
4
4
  const description = "Run a bin from an NPM package with version compatibility checks";
5
5
  const builder = (yargs) => {
@@ -1,9 +1,13 @@
1
1
  import enq from "enquirer";
2
- import execa from "execa";
3
- import semver from "semver";
4
- import { getCompatibilityData } from "@cedarjs/cli-helpers";
2
+ import { isGreaterOrEqual, isLess, tryParse } from "verkit";
3
+ import { dlx } from "@cedarjs/cli-helpers/packageManager/exec";
4
+ import { getCompatibilityData } from "@cedarjs/cli-helpers/version";
5
5
  import { getPaths } from "@cedarjs/project-config";
6
- async function handler({ npmPackage, force, _: _args }) {
6
+ async function handler({
7
+ npmPackage,
8
+ force,
9
+ _: _args
10
+ }) {
7
11
  const isScoped = npmPackage.startsWith("@");
8
12
  const packageName = (isScoped ? "@" : "") + npmPackage.split("@")[isScoped ? 1 : 0];
9
13
  const packageVersion = npmPackage.split("@")[isScoped ? 2 : 1] ?? "latest";
@@ -12,7 +16,7 @@ async function handler({ npmPackage, force, _: _args }) {
12
16
  console.log(
13
17
  "No compatibility check will be performed because you used the --force flag."
14
18
  );
15
- if (semver.parse(packageVersion) !== null && semver.lt(packageVersion, "1.0.0")) {
19
+ if (tryParse(packageVersion) !== null && isLess(packageVersion, "1.0.0")) {
16
20
  console.log(
17
21
  "Be aware that this package is under version 1.0.0 and so should be considered experimental."
18
22
  );
@@ -24,9 +28,9 @@ async function handler({ npmPackage, force, _: _args }) {
24
28
  let compatibilityData;
25
29
  try {
26
30
  compatibilityData = await getCompatibilityData(packageName, packageVersion);
27
- } catch (error) {
31
+ } catch (e) {
28
32
  console.log("The following error occurred while checking compatibility:");
29
- const errorMessage = error.message ?? error;
33
+ const errorMessage = e instanceof Error ? e.message : String(e);
30
34
  console.log(errorMessage);
31
35
  if (errorMessage.includes("does not have a tag") || errorMessage.includes("does not have a version")) {
32
36
  process.exit(1);
@@ -82,7 +86,7 @@ The latest version compatible with your project is ${latestCompatibleVersionText
82
86
  await runPackage(packageName, versionToUse, additionalOptionsToForward);
83
87
  }
84
88
  async function showExperimentalWarning(version) {
85
- if (version === void 0 || semver.parse(version) === null || semver.gte(version, "1.0.0")) {
89
+ if (version === void 0 || tryParse(version) === null || isGreaterOrEqual(version, "1.0.0")) {
86
90
  return;
87
91
  }
88
92
  const decision = await promptWithChoices(
@@ -106,12 +110,12 @@ async function runPackage(packageName, version, options = []) {
106
110
  const versionString = version === void 0 ? "" : `@${version}`;
107
111
  console.log(`Running ${packageName}${versionString}...`);
108
112
  try {
109
- await execa("yarn", ["dlx", `${packageName}${versionString}`, ...options], {
113
+ await dlx(`${packageName}${versionString}`, options, {
110
114
  stdio: "inherit",
111
115
  cwd: getPaths().base
112
116
  });
113
- } catch (error) {
114
- process.exitCode = error.exitCode ?? 1;
117
+ } catch (e) {
118
+ process.exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
115
119
  }
116
120
  }
117
121
  async function promptWithChoices(message, choices) {
@@ -122,9 +126,9 @@ async function promptWithChoices(message, choices) {
122
126
  choices
123
127
  });
124
128
  return await prompt.run();
125
- } catch (error) {
126
- if (error) {
127
- throw error;
129
+ } catch (e) {
130
+ if (e) {
131
+ throw e;
128
132
  }
129
133
  }
130
134
  return null;
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { isTypeScriptProject } from "@cedarjs/cli-helpers";
3
+ import { isTypeScriptProject } from "@cedarjs/cli-helpers/project";
4
4
  import { getPaths } from "@cedarjs/project-config";
5
5
  function addRealtimeToGraphqlHandler(ctx, task, force) {
6
6
  const graphqlHandlerPath = path.join(
@@ -1,4 +1,4 @@
1
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
1
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
2
2
  const command = "realtime";
3
3
  const description = "Setup RedwoodJS Realtime";
4
4
  function builder(yargs) {
@@ -1,13 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
- import execa from "execa";
4
3
  import { Listr } from "listr2";
5
4
  import prompts from "prompts";
6
- import { addApiPackages } from "@cedarjs/cli-helpers";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
+ import { addApiPackages } from "@cedarjs/cli-helpers/installHelpers";
7
+ import { runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
7
8
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
8
- import { projectIsEsm } from "@cedarjs/project-config";
9
9
  import { errorTelemetry } from "@cedarjs/telemetry";
10
- import c from "../../../lib/colors.js";
11
10
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
12
11
  import { isTypeScriptProject, serverFileExists } from "../../../lib/project.js";
13
12
  import { setupServerFileTasks } from "../server-file/serverFileHandler.js";
@@ -31,13 +30,13 @@ async function handleExamplesPreference(includeExamples) {
31
30
  });
32
31
  incl = response.includeExamples;
33
32
  }
34
- return incl;
33
+ return incl ?? false;
35
34
  }
36
35
  async function handler(args) {
37
- const redwoodPaths = getPaths();
36
+ const cedarPaths = getPaths();
38
37
  const ts = isTypeScriptProject();
39
38
  const realtimeLibFilePath = path.join(
40
- redwoodPaths.api.lib,
39
+ cedarPaths.api.lib,
41
40
  `realtime.${isTypeScriptProject() ? "ts" : "js"}`
42
41
  );
43
42
  const force = args.force || false;
@@ -78,7 +77,7 @@ async function handler(args) {
78
77
  title: "Adding Countdown example subscription...",
79
78
  enabled: () => includeExamples,
80
79
  task: async () => {
81
- let exampleSubscriptionTemplateContent = fs.readFileSync(
80
+ const exampleSubscriptionTemplateContent = fs.readFileSync(
82
81
  path.resolve(
83
82
  import.meta.dirname,
84
83
  "templates",
@@ -88,14 +87,8 @@ async function handler(args) {
88
87
  ),
89
88
  "utf-8"
90
89
  );
91
- if (projectIsEsm()) {
92
- exampleSubscriptionTemplateContent = exampleSubscriptionTemplateContent.replace(
93
- "import gql from 'graphql-tag'",
94
- "import { gql } from 'graphql-tag'"
95
- );
96
- }
97
90
  const exampleFile = path.join(
98
- redwoodPaths.api.subscriptions,
91
+ cedarPaths.api.subscriptions,
99
92
  "countdown",
100
93
  `countdown.${isTypeScriptProject() ? "ts" : "js"}`
101
94
  );
@@ -125,7 +118,7 @@ async function handler(args) {
125
118
  "utf-8"
126
119
  );
127
120
  const sdlFile = path.join(
128
- redwoodPaths.api.graphql,
121
+ cedarPaths.api.graphql,
129
122
  `rooms.sdl.${isTypeScriptProject() ? "ts" : "js"}`
130
123
  );
131
124
  const sdlContent = ts ? exampleSdlTemplateContent : await transformTSToJS(sdlFile, exampleSdlTemplateContent);
@@ -140,12 +133,12 @@ async function handler(args) {
140
133
  "utf-8"
141
134
  );
142
135
  const serviceFile = path.join(
143
- redwoodPaths.api.services,
136
+ cedarPaths.api.services,
144
137
  "rooms",
145
138
  `rooms.${isTypeScriptProject() ? "ts" : "js"}`
146
139
  );
147
140
  const serviceContent = ts ? exampleServiceTemplateContent : await transformTSToJS(serviceFile, exampleServiceTemplateContent);
148
- let exampleSubscriptionTemplateContent = fs.readFileSync(
141
+ const exampleSubscriptionTemplateContent = fs.readFileSync(
149
142
  path.resolve(
150
143
  import.meta.dirname,
151
144
  "templates",
@@ -155,14 +148,8 @@ async function handler(args) {
155
148
  ),
156
149
  "utf-8"
157
150
  );
158
- if (projectIsEsm()) {
159
- exampleSubscriptionTemplateContent = exampleSubscriptionTemplateContent.replace(
160
- "import gql from 'graphql-tag'",
161
- "import { gql } from 'graphql-tag'"
162
- );
163
- }
164
151
  const exampleFile = path.join(
165
- redwoodPaths.api.subscriptions,
152
+ cedarPaths.api.subscriptions,
166
153
  "newMessage",
167
154
  `newMessage.${isTypeScriptProject() ? "ts" : "js"}`
168
155
  );
@@ -198,7 +185,7 @@ async function handler(args) {
198
185
  "utf-8"
199
186
  );
200
187
  const sdlFile = path.join(
201
- redwoodPaths.api.graphql,
188
+ cedarPaths.api.graphql,
202
189
  `auctions.sdl.${isTypeScriptProject() ? "ts" : "js"}`
203
190
  );
204
191
  const sdlContent = ts ? exampleSdlTemplateContent : await transformTSToJS(sdlFile, exampleSdlTemplateContent);
@@ -213,7 +200,7 @@ async function handler(args) {
213
200
  "utf-8"
214
201
  );
215
202
  const serviceFile = path.join(
216
- redwoodPaths.api.services,
203
+ cedarPaths.api.services,
217
204
  "auctions",
218
205
  `auctions.${isTypeScriptProject() ? "ts" : "js"}`
219
206
  );
@@ -243,7 +230,7 @@ async function handler(args) {
243
230
  "utf-8"
244
231
  );
245
232
  const sdlFile = path.join(
246
- redwoodPaths.api.graphql,
233
+ cedarPaths.api.graphql,
247
234
  `fastAndSlowFields.sdl.${isTypeScriptProject() ? "ts" : "js"}`
248
235
  );
249
236
  const sdlContent = ts ? exampleSdlTemplateContent : await transformTSToJS(sdlFile, exampleSdlTemplateContent);
@@ -258,7 +245,7 @@ async function handler(args) {
258
245
  "utf-8"
259
246
  );
260
247
  const serviceFile = path.join(
261
- redwoodPaths.api.services,
248
+ cedarPaths.api.services,
262
249
  "fastAndSlowFields",
263
250
  `fastAndSlowFields.${isTypeScriptProject() ? "ts" : "js"}`
264
251
  );
@@ -288,7 +275,7 @@ async function handler(args) {
288
275
  "utf-8"
289
276
  );
290
277
  const sdlFile = path.join(
291
- redwoodPaths.api.graphql,
278
+ cedarPaths.api.graphql,
292
279
  `alphabet.sdl.${isTypeScriptProject() ? "ts" : "js"}`
293
280
  );
294
281
  const sdlContent = ts ? exampleSdlTemplateContent : await transformTSToJS(sdlFile, exampleSdlTemplateContent);
@@ -303,7 +290,7 @@ async function handler(args) {
303
290
  "utf-8"
304
291
  );
305
292
  const serviceFile = path.join(
306
- redwoodPaths.api.services,
293
+ cedarPaths.api.services,
307
294
  "alphabet",
308
295
  `alphabet.${isTypeScriptProject() ? "ts" : "js"}`
309
296
  );
@@ -334,9 +321,9 @@ async function handler(args) {
334
321
  getPaths().api.functions,
335
322
  `graphql.${isTypeScriptProject() ? "ts" : "js"}`
336
323
  );
337
- execa.sync(
338
- "yarn",
339
- ["cedar", "lint", "--fix", graphqlHandlerPath, realtimeLibFilePath],
324
+ runBinSync(
325
+ "cedar",
326
+ ["lint", "--fix", graphqlHandlerPath, realtimeLibFilePath],
340
327
  {
341
328
  cwd: getPaths().base,
342
329
  // Silently ignore errors
@@ -373,9 +360,11 @@ async function handler(args) {
373
360
  );
374
361
  }
375
362
  } catch (e) {
376
- errorTelemetry(process.argv, e.message);
377
- console.error(c.error(e.message));
378
- process.exit(e?.exitCode || 1);
363
+ const message = e instanceof Error ? e.message : String(e);
364
+ const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
365
+ errorTelemetry(process.argv, message);
366
+ console.error(c.error(message));
367
+ process.exit(exitCode);
379
368
  }
380
369
  }
381
370
  export {
@@ -1,4 +1,4 @@
1
- import { CedarRealtimeOptions } from '@cedarjs/realtime'
1
+ import type { CedarRealtimeOptions } from '@cedarjs/realtime'
2
2
 
3
3
  import subscriptions from 'src/subscriptions/**/*.{js,ts}'
4
4
 
@@ -1,4 +1,4 @@
1
- import gql from 'graphql-tag'
1
+ import { gql } from 'graphql-tag'
2
2
 
3
3
  import { Repeater } from '@cedarjs/realtime'
4
4
 
@@ -1,4 +1,4 @@
1
- import gql from 'graphql-tag'
1
+ import { gql } from 'graphql-tag'
2
2
 
3
3
  import type { PubSub } from '@cedarjs/realtime'
4
4
 
@@ -1,4 +1,4 @@
1
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
1
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
2
2
  const command = "server-file";
3
3
  const description = "Setup the server file";
4
4
  function builder(yargs) {
@@ -1,18 +1,21 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
3
  import { Listr } from "listr2";
4
- import { addApiPackages } from "@cedarjs/cli-helpers";
4
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
5
+ import { addApiPackages } from "@cedarjs/cli-helpers/installHelpers";
5
6
  import { errorTelemetry } from "@cedarjs/telemetry";
6
- import c from "../../../lib/colors.js";
7
7
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
8
8
  import { isTypeScriptProject } from "../../../lib/project.js";
9
- const { version } = JSON.parse(
9
+ const packageJson = JSON.parse(
10
10
  fs.readFileSync(
11
11
  path.resolve(import.meta.dirname, "../../../../package.json"),
12
12
  "utf-8"
13
13
  )
14
14
  );
15
- function setupServerFileTasks({ force = false } = {}) {
15
+ const { version } = packageJson;
16
+ function setupServerFileTasks({
17
+ force = false
18
+ } = {}) {
16
19
  return [
17
20
  {
18
21
  title: "Adding the server file...",
@@ -37,17 +40,22 @@ function setupServerFileTasks({ force = false } = {}) {
37
40
  addApiPackages([`@cedarjs/api-server@${version}`])
38
41
  ];
39
42
  }
40
- async function handler({ force, verbose }) {
41
- const tasks = new Listr(setupServerFileTasks({ force }), {
43
+ async function handler({
44
+ force,
45
+ verbose
46
+ }) {
47
+ const listr = new Listr(setupServerFileTasks({ force }), {
42
48
  rendererOptions: { collapseSubtasks: false, persistentOutput: true },
43
49
  renderer: verbose ? "verbose" : "default"
44
50
  });
45
51
  try {
46
- await tasks.run();
52
+ await listr.run();
47
53
  } catch (e) {
48
- errorTelemetry(process.argv, e.message);
49
- console.error(c.error(e.message));
50
- process.exit(e?.exitCode || 1);
54
+ const message = e instanceof Error ? e.message : String(e);
55
+ errorTelemetry(process.argv, message);
56
+ console.error(c.error(message));
57
+ const exitCode = typeof e === "object" && e !== null && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
58
+ process.exit(exitCode);
51
59
  }
52
60
  }
53
61
  export {