@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
@@ -2,22 +2,25 @@ import fs from "node:fs";
2
2
  import path from "path";
3
3
  import camelcase from "camelcase";
4
4
  import { paramCase } from "change-case";
5
- import execa from "execa";
6
5
  import humanize from "humanize-string";
7
6
  import { Listr } from "listr2";
8
7
  import pascalcase from "pascalcase";
9
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
8
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
9
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
10
+ import {
11
+ addWorkspacePackages,
12
+ removeWorkspacePackages
13
+ } from "@cedarjs/cli-helpers/packageManager/packages";
14
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
10
15
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
11
16
  import { getConfig } from "@cedarjs/project-config";
12
- import { pluralize, singularize } from "../../../lib/cedarPluralize.js";
13
- import c from "../../../lib/colors.js";
17
+ import { pluralize, singularize } from "@cedarjs/utils/cedarPluralize";
14
18
  import {
15
19
  generateTemplate,
16
20
  readFile,
17
21
  writeFile,
18
22
  getDefaultArgs,
19
23
  getPaths,
20
- writeFilesTask,
21
24
  addRoutesToRouterTask,
22
25
  addScaffoldImport,
23
26
  transformTSToJS,
@@ -29,17 +32,28 @@ import {
29
32
  } from "../../../lib/rollback.js";
30
33
  import { getSchema, verifyModelName } from "../../../lib/schemaHelpers.js";
31
34
  import {
35
+ redactedModelFields,
32
36
  relationsForModel,
33
37
  intForeignKeysForModel,
34
38
  mapPrismaScalarToPagePropTsType
35
39
  } from "../helpers.js";
36
40
  import { builder as sdlBuilder } from "../sdl/sdl.js";
37
- import { files as sdlFiles } from "../sdl/sdlHandler.js";
41
+ import {
42
+ files as sdlFiles,
43
+ stubFiles as sdlStubFiles,
44
+ printRedactedFieldsNote,
45
+ redactedSensitiveFields
46
+ } from "../sdl/sdlHandler.js";
47
+ import {
48
+ missingRelatedModels,
49
+ writeFilesWithStubsTask
50
+ } from "../sdl/stubFiles.js";
38
51
  import { builder as serviceBuilder } from "../service/service.js";
39
52
  import { files as serviceFiles } from "../service/serviceHandler.js";
40
53
  import { customOrDefaultTemplatePath } from "../yargsHandlerHelpers.js";
41
54
  const SKIPPABLE_ASSETS = ["scaffold.css"];
42
55
  const PACKAGE_SET = "Set";
56
+ const PACKAGE_PRIVATE_SET = "PrivateSet";
43
57
  const getIdType = (model) => {
44
58
  return model.fields.find((field) => field.isId)?.type;
45
59
  };
@@ -48,7 +62,7 @@ const getIdName = (model) => {
48
62
  };
49
63
  const isAutoGeneratedColumnForScaffold = (column) => {
50
64
  const autoGeneratedFunctions = ["now", "autoincrement"];
51
- const columnDefaultFunction = typeof column.default === "object" && "name" in column.default ? column.default?.name : "";
65
+ const columnDefaultFunction = typeof column.default === "object" && column.default !== null && "name" in column.default ? column.default.name : "";
52
66
  return column.isId || column.isUpdatedAt || column.name === "createdAt" || autoGeneratedFunctions.includes(columnDefaultFunction);
53
67
  };
54
68
  const getImportComponentNames = (name, scaffoldPath, nestScaffoldByModel = true) => {
@@ -147,7 +161,7 @@ const files = async ({
147
161
  };
148
162
  };
149
163
  const assetFiles = async (name, tailwind) => {
150
- let fileList = {};
164
+ const fileList = {};
151
165
  const assets = fs.readdirSync(
152
166
  customOrDefaultTemplatePath({
153
167
  side: "web",
@@ -269,17 +283,22 @@ const modelRelatedVariables = (model) => {
269
283
  listDisplayFunction: "truncate"
270
284
  }
271
285
  };
272
- const relations = relationsForModel(model).map((relation) => relation);
273
- const columns = model.fields.filter((field) => field.kind !== "object").map((column) => {
286
+ const relations = relationsForModel(model)?.map((relation) => relation);
287
+ const redactedFields = redactedModelFields(
288
+ model.fields.map((field) => field.name)
289
+ );
290
+ const columns = model.fields.filter((field) => field.kind !== "object").filter((field) => !redactedFields.includes(field.name)).map((column) => {
274
291
  let validation;
275
- if (componentMetadata[column.type]?.validation) {
276
- validation = componentMetadata[column.type]?.validation(
277
- column?.isRequired
278
- );
292
+ const meta = componentMetadata[column.type];
293
+ const validationDef = meta?.validation;
294
+ if (typeof validationDef === "function") {
295
+ validation = validationDef(column.isRequired);
296
+ } else if (validationDef !== void 0) {
297
+ validation = column.isRequired ? validationDef : null;
279
298
  } else {
280
- validation = column?.isRequired ? componentMetadata.default.validation : null;
299
+ validation = column.isRequired ? componentMetadata.default.validation : null;
281
300
  }
282
- const isRelationalField = column.name.endsWith("Id") && relations.some((relation) => column.name.includes(relation));
301
+ const isRelationalField = column.name.endsWith("Id") && relations?.some((relation) => column.name.includes(relation));
283
302
  const isRequired = column.isRequired;
284
303
  const isEnum = column.kind === "enum";
285
304
  const isList = column.isList;
@@ -306,7 +325,9 @@ const modelRelatedVariables = (model) => {
306
325
  );
307
326
  const fieldsToImport = Object.keys(
308
327
  editableColumns.reduce((accumulator, column) => {
309
- accumulator[column.component] = true;
328
+ if (column.component) {
329
+ accumulator[column.component] = true;
330
+ }
310
331
  return accumulator;
311
332
  }, {})
312
333
  );
@@ -324,7 +345,7 @@ const modelRelatedVariables = (model) => {
324
345
  };
325
346
  };
326
347
  const layoutFiles = async (name, force, generateTypescript, templateStrings) => {
327
- let fileList = {};
348
+ const fileList = {};
328
349
  const layouts = fs.readdirSync(
329
350
  customOrDefaultTemplatePath({
330
351
  side: "web",
@@ -367,7 +388,7 @@ const pageFiles = async (name, pascalScaffoldPath = "", generateTypescript, nest
367
388
  const idType = getIdType(model);
368
389
  const idTsType = mapPrismaScalarToPagePropTsType(idType);
369
390
  const idName = getIdName(model);
370
- let fileList = {};
391
+ const fileList = {};
371
392
  const pages = fs.readdirSync(
372
393
  customOrDefaultTemplatePath({
373
394
  side: "web",
@@ -409,9 +430,9 @@ const componentFiles = async (name, pascalScaffoldPath = "", generateTypescript,
409
430
  const model = await getSchema(singularName);
410
431
  const idType = getIdType(model);
411
432
  const idName = getIdName(model);
412
- const pascalIdName = pascalcase(idName);
433
+ const pascalIdName = pascalcase(idName ?? "");
413
434
  const intForeignKeys = intForeignKeysForModel(model);
414
- let fileList = {};
435
+ const fileList = {};
415
436
  const components = fs.readdirSync(
416
437
  customOrDefaultTemplatePath({
417
438
  side: "web",
@@ -501,45 +522,110 @@ const addHelperPackages = async (task) => {
501
522
  if (packageJson.default.dependencies["humanize-string"]) {
502
523
  return task.skip("Skipping. Already installed");
503
524
  }
504
- await execa("yarn", ["workspace", "web", "add", "humanize-string@2.1.0"]);
525
+ await addWorkspacePackages("web", ["humanize-string@2.1.0"]);
505
526
  addFunctionToRollback(async () => {
506
- await execa("yarn", ["workspace", "web", "remove", "humanize-string"]);
527
+ await removeWorkspacePackages("web", ["humanize-string"]);
507
528
  });
508
529
  };
530
+ const isAuthSetup = () => {
531
+ const extensions = ["ts", "js", "tsx", "jsx"];
532
+ return extensions.some(
533
+ (ext) => fs.existsSync(path.join(getPaths().web.src, "auth." + ext))
534
+ );
535
+ };
536
+ const ROUTE_TAG_RE = /<Route\s+([^>]*?)\/?>/g;
537
+ const extractRouteAttr = (tagAttrs, attrName) => tagAttrs.match(new RegExp(`\\b${attrName}=["']([^"']+)["']`))?.[1];
538
+ const getRoutesFileContent = () => {
539
+ const routesPath = getPaths().web.routes;
540
+ if (!fs.existsSync(routesPath)) {
541
+ return void 0;
542
+ }
543
+ return readFile(routesPath).toString();
544
+ };
545
+ const hasLoginRoute = () => {
546
+ const content = getRoutesFileContent();
547
+ if (!content) {
548
+ return false;
549
+ }
550
+ return Array.from(content.matchAll(ROUTE_TAG_RE)).some(
551
+ ([, attrs]) => extractRouteAttr(attrs, "name") === "login"
552
+ );
553
+ };
554
+ const findUnprotectedLandingPageRouteName = () => {
555
+ const content = getRoutesFileContent();
556
+ if (!content) {
557
+ return void 0;
558
+ }
559
+ const privateSetRanges = Array.from(
560
+ content.matchAll(/<PrivateSet\b[^>]*>([\s\S]*?)<\/PrivateSet>/g)
561
+ ).map((match) => ({
562
+ start: match.index ?? 0,
563
+ end: (match.index ?? 0) + match[0].length
564
+ }));
565
+ for (const match of content.matchAll(ROUTE_TAG_RE)) {
566
+ const [, attrs] = match;
567
+ if (extractRouteAttr(attrs, "path") !== "/") {
568
+ continue;
569
+ }
570
+ const tagStart = match.index ?? 0;
571
+ const isProtected = privateSetRanges.some(
572
+ (range) => tagStart >= range.start && tagStart < range.end
573
+ );
574
+ if (!isProtected) {
575
+ return extractRouteAttr(attrs, "name");
576
+ }
577
+ }
578
+ return void 0;
579
+ };
580
+ const getUnauthenticatedRedirectRoute = () => {
581
+ if (!isAuthSetup()) {
582
+ return void 0;
583
+ }
584
+ if (hasLoginRoute()) {
585
+ return "login";
586
+ }
587
+ return findUnprotectedLandingPageRouteName();
588
+ };
509
589
  const addSetImport = (task) => {
510
590
  const routesPath = getPaths().web.routes;
511
591
  const routesContent = readFile(routesPath).toString();
512
- const [redwoodRouterImport, importStart, spacing, importContent, importEnd] = routesContent.match(
592
+ const [cedarRouterImport, importStart, spacing, importContent, importEnd] = routesContent.match(
513
593
  /(import {)(\s*)([^]*)(} from ['"]@cedarjs\/router['"])/
514
594
  ) || [];
515
- if (!redwoodRouterImport) {
595
+ if (!cedarRouterImport) {
516
596
  task.skip(
517
597
  "Couldn't add Set import from @cedarjs/router to Routes.{jsx,tsx}"
518
598
  );
519
599
  return void 0;
520
600
  }
521
601
  const routerImports = importContent.replace(/\s/g, "").split(",");
522
- if (routerImports.includes(PACKAGE_SET)) {
602
+ const namesToImport = [
603
+ PACKAGE_SET,
604
+ ...getUnauthenticatedRedirectRoute() ? [PACKAGE_PRIVATE_SET] : []
605
+ ].filter((name) => !routerImports.includes(name));
606
+ if (!namesToImport.length) {
523
607
  return "Skipping Set import";
524
608
  }
525
609
  const newRoutesContent = routesContent.replace(
526
- redwoodRouterImport,
527
- importStart + spacing + PACKAGE_SET + `,` + spacing + importContent + importEnd
610
+ cedarRouterImport,
611
+ importStart + spacing + namesToImport.join("," + spacing) + `,` + spacing + importContent + importEnd
528
612
  );
529
613
  writeFile(routesPath, newRoutesContent, { overwriteExisting: true });
530
- return "Added Set import to Routes.{jsx,tsx}";
614
+ return `Added ${namesToImport.join(", ")} import to Routes.{jsx,tsx}`;
531
615
  };
532
- const addScaffoldSetToRouter = async (model, path2) => {
533
- const templateNames = getTemplateStrings(model, path2);
616
+ const addScaffoldSetToRouter = async (model, scaffoldPath) => {
617
+ const templateNames = getTemplateStrings(model, scaffoldPath);
534
618
  const nameVars = nameVariants(model);
535
619
  const title = nameVars.pluralPascalName;
536
620
  const titleTo = templateNames.pluralRouteName;
537
621
  const buttonLabel = `New ${nameVars.singularPascalName}`;
538
622
  const buttonTo = templateNames.newRouteName;
623
+ const unauthenticatedRoute = getUnauthenticatedRedirectRoute();
539
624
  return addRoutesToRouterTask(
540
- await routes({ model, path: path2 }),
625
+ await routes({ model, path: scaffoldPath }),
541
626
  "ScaffoldLayout",
542
- { title, titleTo, buttonLabel, buttonTo }
627
+ { title, titleTo, buttonLabel, buttonTo },
628
+ unauthenticatedRoute ? { unauthenticated: unauthenticatedRoute } : void 0
543
629
  );
544
630
  };
545
631
  const tasks = ({
@@ -549,25 +635,28 @@ const tasks = ({
549
635
  force,
550
636
  tests,
551
637
  typescript,
552
- javascript,
553
- tailwind
638
+ javascript: _javascript,
639
+ tailwind,
640
+ missingModels
554
641
  }) => {
555
642
  return new Listr(
556
643
  [
557
644
  {
558
645
  title: "Generating scaffold files...",
559
646
  task: async () => {
560
- const f = await files({
561
- docs,
562
- model,
563
- path: path2,
564
- tests,
565
- typescript,
566
- javascript,
567
- tailwind,
568
- force
569
- });
570
- return writeFilesTask(f, { overwriteExisting: force });
647
+ const f = {
648
+ ...await files({
649
+ docs,
650
+ model,
651
+ path: path2,
652
+ tests,
653
+ typescript,
654
+ tailwind,
655
+ force
656
+ }),
657
+ ...await sdlStubFiles(missingModels, model, { docs, typescript })
658
+ };
659
+ return writeFilesWithStubsTask(f, { overwriteExisting: force });
571
660
  }
572
661
  },
573
662
  {
@@ -632,6 +721,7 @@ const handler = async ({
632
721
  tailwind = shouldUseTailwindCSS(tailwind);
633
722
  try {
634
723
  const { name } = await verifyModelName({ name: model });
724
+ const missingModels = await missingRelatedModels(name);
635
725
  const t = tasks({
636
726
  docs,
637
727
  model: name,
@@ -639,15 +729,49 @@ const handler = async ({
639
729
  force,
640
730
  tests,
641
731
  typescript,
642
- tailwind
732
+ tailwind,
733
+ missingModels
643
734
  });
644
735
  if (rollback && !force) {
645
736
  prepareForRollback(t);
646
737
  }
647
738
  await t.run();
739
+ if (missingModels.length > 0) {
740
+ console.log();
741
+ console.log(
742
+ c.info(
743
+ `${name} has relations to models that don't have SDL files of their own yet: ${missingModels.join(", ")}`
744
+ )
745
+ );
746
+ console.log(
747
+ c.info(
748
+ "Read-only SDL stubs were generated for them, since GraphQL type generation fails otherwise."
749
+ )
750
+ );
751
+ console.log(
752
+ c.info("To replace a stub, run one of the following for each model:")
753
+ );
754
+ for (const stubModel of missingModels) {
755
+ console.log(
756
+ c.info(
757
+ ` ${formatCedarCommand(["generate", "sdl", stubModel])} (SDL + service only)`
758
+ )
759
+ );
760
+ console.log(
761
+ c.info(
762
+ ` ${formatCedarCommand(["generate", "scaffold", stubModel])} (adds pages, cells, and forms too)`
763
+ )
764
+ );
765
+ }
766
+ }
767
+ printRedactedFieldsNote(
768
+ await redactedSensitiveFields([name, ...missingModels])
769
+ );
648
770
  } catch (e) {
649
- console.log(c.error(e.message));
650
- process.exit(e?.existCode || 1);
771
+ const message = e instanceof Error ? e.message : String(e);
772
+ const exitCode = e instanceof Error && "exitCode" in e ? e.exitCode ?? 1 : 1;
773
+ console.log(c.error(message));
774
+ process.exit(exitCode);
651
775
  }
652
776
  };
653
777
  const splitPathAndModel = (pathSlashModel) => {
@@ -657,7 +781,10 @@ const splitPathAndModel = (pathSlashModel) => {
657
781
  };
658
782
  export {
659
783
  files,
784
+ getUnauthenticatedRedirectRoute,
660
785
  handler,
786
+ hasLoginRoute,
787
+ isAuthSetup,
661
788
  routes,
662
789
  shouldUseTailwindCSS,
663
790
  splitPathAndModel,
@@ -40,7 +40,7 @@ export const jsonTruncate = (obj: unknown) => {
40
40
  }
41
41
 
42
42
  export const timeTag = (dateTime?: string) => {
43
- let output: string | JSX.Element = ''
43
+ let output: string | React.JSX.Element = ''
44
44
 
45
45
  if (dateTime) {
46
46
  output = (
@@ -19,6 +19,7 @@ const builder = (yargs) => {
19
19
  Object.entries(getYargsDefaults()).forEach(([option, config]) => {
20
20
  yargs.option(option, config);
21
21
  });
22
+ return yargs;
22
23
  };
23
24
  const handler = createHandler("script");
24
25
  export {
@@ -1,9 +1,9 @@
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 { errorTelemetry } from "@cedarjs/telemetry";
6
- import c from "../../../lib/colors.js";
7
7
  import {
8
8
  getPaths,
9
9
  writeFilesTask,
@@ -35,7 +35,10 @@ const files = async ({ name, typescript = false }) => {
35
35
  }
36
36
  };
37
37
  };
38
- const handler = async ({ force, ...args }) => {
38
+ const handler = async ({
39
+ force,
40
+ ...args
41
+ }) => {
39
42
  recordTelemetryAttributes({
40
43
  command: "generate script",
41
44
  force,
@@ -74,9 +77,10 @@ const handler = async ({ force, ...args }) => {
74
77
  prepareForRollback(tasks);
75
78
  }
76
79
  await tasks.run();
77
- } catch (e) {
78
- errorTelemetry(process.argv, e.message);
79
- console.log(c.error(e.message));
80
+ } catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ errorTelemetry(process.argv, message);
83
+ console.log(c.error(message));
80
84
  process.exit(1);
81
85
  }
82
86
  };
@@ -3,12 +3,17 @@
3
3
  // To access your database uncomment the line below
4
4
  // import { db } from 'api/src/lib/db'
5
5
 
6
- interface Args {
7
- _: string[]
8
- [key: string]: unknown
6
+ interface ScriptArgs {
7
+ args: {
8
+ // positional args, e.g. `yarn cedar exec myScript foo 123` -> ['foo', 123]
9
+ // numeric-looking args are parsed as numbers, others as strings
10
+ _: Array<string | number>
11
+ // named flags, e.g. `--force` -> { force: true }
12
+ [flag: string]: unknown
13
+ }
9
14
  }
10
15
 
11
- export default async ({ args }: Args) => {
16
+ export default async ({ args }: ScriptArgs) => {
12
17
  // Your script here...
13
18
  console.log(':: Executing script with args ::')
14
19
  console.log(args)
@@ -4,6 +4,12 @@
4
4
  "allowJs": true,
5
5
  "esModuleInterop": true,
6
6
  "baseUrl": "./",
7
+ "rootDirs": [
8
+ "../api/src",
9
+ "../.cedar/types/mirror/api/src",
10
+ "../web/src",
11
+ "../.cedar/types/mirror/web/src"
12
+ ],
7
13
  "paths": {
8
14
  "$api/*": [
9
15
  "../api/*",
@@ -11,6 +17,14 @@
11
17
  "api/*": [
12
18
  "../api/*",
13
19
  ],
20
+ "$api/src/*": [
21
+ "../api/src/*",
22
+ "../.cedar/types/mirror/api/src/*"
23
+ ],
24
+ "api/src/*": [
25
+ "../api/src/*",
26
+ "../.cedar/types/mirror/api/src/*"
27
+ ],
14
28
  "$web/*": [
15
29
  "../web/*",
16
30
  ],
@@ -19,11 +33,11 @@
19
33
  ],
20
34
  "$web/src/*": [
21
35
  "../web/src/*",
22
- "../.redwood/types/mirror/web/src/*"
36
+ "../.cedar/types/mirror/web/src/*"
23
37
  ],
24
38
  "web/src/*": [
25
39
  "../web/src/*",
26
- "../.redwood/types/mirror/web/src/*"
40
+ "../.cedar/types/mirror/web/src/*"
27
41
  ],
28
42
  "types/*": ["../types/*", "../web/types/*", "../api/types/*"],
29
43
  },
@@ -1,6 +1,6 @@
1
1
  import { terminalLink } from "termi-link";
2
2
  import { createHandler, getYargsDefaults } from "../yargsCommandHelpers.js";
3
- const getDefaults = () => {
3
+ const getDefaultOptions = () => {
4
4
  return {
5
5
  ...getYargsDefaults(),
6
6
  crud: {
@@ -34,15 +34,16 @@ const builder = (yargs) => {
34
34
  "https://cedarjs.com/docs/cli-commands#generate-sdl"
35
35
  )}`
36
36
  );
37
- Object.entries(getDefaults()).forEach(([option, config]) => {
37
+ Object.entries(getDefaultOptions()).forEach(([option, config]) => {
38
38
  yargs.option(option, config);
39
39
  });
40
+ return yargs;
40
41
  };
41
42
  const handler = createHandler("sdl");
42
43
  export {
43
44
  builder,
44
45
  command,
45
46
  description,
46
- getDefaults,
47
+ getDefaultOptions,
47
48
  handler
48
49
  };