@cedarjs/cli 7.1.0 → 7.1.1-next.469

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 (194) hide show
  1. package/dist/commands/build/buildHandler.js +2 -1
  2. package/dist/commands/build.js +1 -1
  3. package/dist/commands/check.js +2 -1
  4. package/dist/commands/deploy/baremetal/baremetalHandler.js +364 -73
  5. package/dist/commands/deploy/baremetal/monitors.js +66 -0
  6. package/dist/commands/deploy/baremetal.js +7 -1
  7. package/dist/commands/deploy/flightcontrolHandler.js +1 -1
  8. package/dist/commands/deploy/helpers/deployHandler.js +1 -1
  9. package/dist/commands/deploy/netlify.js +1 -1
  10. package/dist/commands/deploy/renderHandler.js +1 -1
  11. package/dist/commands/deploy/serverlessHandler.js +2 -1
  12. package/dist/commands/deploy/vercel.js +1 -1
  13. package/dist/commands/destroy/handlerHelpers.js +1 -1
  14. package/dist/commands/destroy/page/pageHandler.js +2 -1
  15. package/dist/commands/destroy/scaffold/scaffoldHandler.js +65 -26
  16. package/dist/commands/destroy/sdl/sdlHandler.js +2 -1
  17. package/dist/commands/dev/devHandler.js +3 -4
  18. package/dist/commands/dev/packageWatchCommands.js +8 -3
  19. package/dist/commands/dev.js +1 -1
  20. package/dist/commands/execHandler.js +2 -1
  21. package/dist/commands/experimental/live-queries/liveQueries.js +1 -1
  22. package/dist/commands/experimental/live-queries/liveQueriesHandler.js +3 -3
  23. package/dist/commands/experimental/setupInngest.js +1 -1
  24. package/dist/commands/experimental/setupInngestHandler.js +1 -1
  25. package/dist/commands/experimental/setupOpentelemetry.js +1 -1
  26. package/dist/commands/experimental/setupOpentelemetryHandler.js +2 -1
  27. package/dist/commands/experimental/setupReactCompiler.js +1 -1
  28. package/dist/commands/experimental/setupReactCompilerHandler.js +4 -4
  29. package/dist/commands/experimental/setupRsc.js +1 -1
  30. package/dist/commands/experimental/setupRscHandler.js +2 -1
  31. package/dist/commands/experimental/setupStreamingSsr.js +1 -1
  32. package/dist/commands/experimental/setupStreamingSsrHandler.js +3 -2
  33. package/dist/commands/generate/cell/cell.js +20 -0
  34. package/dist/commands/generate/cell/cellHandler.js +68 -20
  35. package/dist/commands/generate/cell/templates/cell.tsx.template +21 -2
  36. package/dist/commands/generate/cell/templates/cellFragment.tsx.template +43 -0
  37. package/dist/commands/generate/cell/templates/cellList.tsx.template +21 -2
  38. package/dist/commands/generate/cell/templates/storiesFragment.tsx.template +23 -0
  39. package/dist/commands/generate/cell/templates/test.js.template +1 -1
  40. package/dist/commands/generate/cell/templates/testFragment.js.template +30 -0
  41. package/dist/commands/generate/dataMigration/dataMigration.js +2 -1
  42. package/dist/commands/generate/dbAuth/dbAuth.js +6 -2
  43. package/dist/commands/generate/dbAuth/dbAuthHandler.js +80 -17
  44. package/dist/commands/generate/dbAuth/templates/changePassword.tsx.template +131 -0
  45. package/dist/commands/generate/dbAuth/templates/login.oauth.tsx.template +164 -0
  46. package/dist/commands/generate/dbAuth/templates/login.webAuthn.tsx.template +20 -12
  47. package/dist/commands/generate/dbAuth/templates/signup.oauth.tsx.template +147 -0
  48. package/dist/commands/generate/directive/directiveHandler.js +2 -1
  49. package/dist/commands/generate/function/functionHandler.js +2 -1
  50. package/dist/commands/generate/helpers.js +26 -0
  51. package/dist/commands/generate/job/jobHandler.js +2 -1
  52. package/dist/commands/generate/model/modelHandler.js +2 -1
  53. package/dist/commands/generate/ogImage/ogImageHandler.js +2 -1
  54. package/dist/commands/generate/ogImage/templates/ogImage.og.tsx.template +1 -1
  55. package/dist/commands/generate/package/filesTask.js +9 -12
  56. package/dist/commands/generate/package/packageHandler.js +3 -4
  57. package/dist/commands/generate/package/templates/tsconfig.json.template +1 -0
  58. package/dist/commands/generate/page/pageHandler.js +2 -1
  59. package/dist/commands/generate/realtime/realtime.js +1 -1
  60. package/dist/commands/generate/realtime/realtimeHandler.js +2 -9
  61. package/dist/commands/generate/realtime/templates/liveQueries/blank/blank.service.ts.template +12 -4
  62. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.service.ts.template +2 -2
  63. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +4 -4
  64. package/dist/commands/generate/scaffold/scaffold.js +1 -1
  65. package/dist/commands/generate/scaffold/scaffoldHandler.js +93 -49
  66. package/dist/commands/generate/scaffold/templates/assets/scaffold.tailwind.css.template +12 -7
  67. package/dist/commands/generate/scaffold/templates/components/EditNameCell.tsx.template +5 -7
  68. package/dist/commands/generate/scaffold/templates/components/NameForm.tsx.template +10 -9
  69. package/dist/commands/generate/scaffold/templates/layouts/NamesScaffoldLayout.tsx.template +18 -0
  70. package/dist/commands/generate/scaffold/templates/lib/formatters.test.tsx.template +11 -0
  71. package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +16 -4
  72. package/dist/commands/generate/script/scriptHandler.js +2 -1
  73. package/dist/commands/generate/script/templates/tsconfig.json.template +1 -0
  74. package/dist/commands/generate/sdl/sdlHandler.js +10 -4
  75. package/dist/commands/generate/secret/secret.js +1 -1
  76. package/dist/commands/generate/service/serviceHandler.js +79 -49
  77. package/dist/commands/generate/service/templates/service.ts.template +40 -13
  78. package/dist/commands/generate/service/templates/test.ts.template +8 -6
  79. package/dist/commands/generate/yargsCommandHelpers.js +1 -1
  80. package/dist/commands/generate/yargsHandlerHelpers.js +2 -1
  81. package/dist/commands/generate.js +1 -1
  82. package/dist/commands/info.js +1 -1
  83. package/dist/commands/jobsHandler.js +5 -3
  84. package/dist/commands/lint.js +1 -1
  85. package/dist/commands/prerenderHandler.js +11 -4
  86. package/dist/commands/prismaHandler.js +7 -2
  87. package/dist/commands/record/init.js +1 -1
  88. package/dist/commands/serve.js +2 -1
  89. package/dist/commands/setup/auth/auth.js +2 -4
  90. package/dist/commands/setup/cache/cache.js +1 -1
  91. package/dist/commands/setup/cache/cacheHandler.js +2 -1
  92. package/dist/commands/setup/cache/templates/memcached.ts.template +14 -17
  93. package/dist/commands/setup/cache/templates/redis.ts.template +12 -20
  94. package/dist/commands/setup/database/postgres.js +1 -1
  95. package/dist/commands/setup/database/postgresHandler.js +3 -1
  96. package/dist/commands/setup/deploy/providers/baremetal.js +7 -0
  97. package/dist/commands/setup/deploy/providers/baremetalHandler.js +130 -21
  98. package/dist/commands/setup/deploy/providers/coherence.js +1 -1
  99. package/dist/commands/setup/deploy/providers/coherenceHandler.js +7 -6
  100. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +2 -1
  101. package/dist/commands/setup/deploy/providers/netlifyHandler.js +2 -1
  102. package/dist/commands/setup/deploy/providers/renderHandler.js +2 -1
  103. package/dist/commands/setup/deploy/providers/serverlessHandler.js +2 -1
  104. package/dist/commands/setup/deploy/providers/universalDeployHandler.js +4 -6
  105. package/dist/commands/setup/deploy/providers/vercelHandler.js +2 -1
  106. package/dist/commands/setup/deploy/templates/baremetal.js +119 -9
  107. package/dist/commands/setup/deploy/templates/netlifyUD.js +3 -0
  108. package/dist/commands/setup/docker/docker.js +1 -1
  109. package/dist/commands/setup/docker/dockerHandler.js +2 -1
  110. package/dist/commands/setup/generator/generator.js +1 -1
  111. package/dist/commands/setup/generator/generatorHandler.js +1 -1
  112. package/dist/commands/setup/graphql/features/fragments/fragments.js +1 -1
  113. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +3 -5
  114. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +1 -1
  115. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +2 -1
  116. package/dist/commands/setup/i18n/i18n.js +1 -1
  117. package/dist/commands/setup/i18n/i18nHandler.js +1 -1
  118. package/dist/commands/setup/jobs/jobs.js +1 -1
  119. package/dist/commands/setup/jobs/jobsHandler.js +4 -1
  120. package/dist/commands/setup/mailer/mailer.js +1 -1
  121. package/dist/commands/setup/mailer/mailerHandler.js +2 -1
  122. package/dist/commands/setup/middleware/ogImage/ogImage.js +1 -1
  123. package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +2 -1
  124. package/dist/commands/setup/monitoring/sentry/sentry.js +1 -1
  125. package/dist/commands/setup/monitoring/sentry/sentryHandler.js +13 -9
  126. package/dist/commands/setup/monitoring/sentry/templates/sentryApi.ts.template +1 -4
  127. package/dist/commands/setup/monitoring/sentry/templates/sentryWeb.ts.template +7 -4
  128. package/dist/commands/setup/neon/neon.js +1 -1
  129. package/dist/commands/setup/neon/neonHandler.js +5 -9
  130. package/dist/commands/setup/package/package.js +1 -1
  131. package/dist/commands/setup/package/packageHandler.js +4 -4
  132. package/dist/commands/setup/realtime/addRealtimeToGraphql.js +1 -1
  133. package/dist/commands/setup/realtime/realtime.js +1 -1
  134. package/dist/commands/setup/realtime/realtimeHandler.js +4 -16
  135. package/dist/commands/setup/realtime/templates/defer/fastAndSlowFields/fastAndSlowFields.ts.template +4 -1
  136. package/dist/commands/setup/realtime/templates/liveQueries/auctions/auctions.ts.template +12 -4
  137. package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +1 -1
  138. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +2 -2
  139. package/dist/commands/setup/server-file/serverFile.js +1 -1
  140. package/dist/commands/setup/server-file/serverFileHandler.js +2 -1
  141. package/dist/commands/setup/tenancy/authCodemod.js +66 -0
  142. package/dist/commands/setup/tenancy/dbCodemod.js +64 -0
  143. package/dist/commands/setup/tenancy/graphqlCodemod.js +88 -0
  144. package/dist/commands/setup/tenancy/preflight.js +49 -0
  145. package/dist/commands/setup/tenancy/schemaPrisma.js +81 -0
  146. package/dist/commands/setup/tenancy/signupCodemod.js +154 -0
  147. package/dist/commands/setup/tenancy/templates/InvitePage.tsx.template +72 -0
  148. package/dist/commands/setup/tenancy/templates/OrgScope.tsx.template +40 -0
  149. package/dist/commands/setup/tenancy/templates/ensureDefaultOrganizations.dataMigration.ts.template +39 -0
  150. package/dist/commands/setup/tenancy/templates/organizations.scenarios.ts.template +57 -0
  151. package/dist/commands/setup/tenancy/templates/organizations.sdl.ts.template +89 -0
  152. package/dist/commands/setup/tenancy/templates/organizations.test.ts.template +381 -0
  153. package/dist/commands/setup/tenancy/templates/organizations.ts.template +394 -0
  154. package/dist/commands/setup/tenancy/templates/requireMembership.test.ts.template +35 -0
  155. package/dist/commands/setup/tenancy/templates/requireMembership.ts.template +25 -0
  156. package/dist/commands/setup/tenancy/tenancy.js +30 -0
  157. package/dist/commands/setup/tenancy/tenancyHandler.js +425 -0
  158. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +2 -1
  159. package/dist/commands/setup/ui/libraries/mantineHandler.js +2 -1
  160. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +63 -82
  161. package/dist/commands/setup/uploads/gitignore.js +17 -0
  162. package/dist/commands/setup/uploads/schemaPrisma.js +41 -0
  163. package/dist/commands/setup/uploads/serverFile.js +217 -0
  164. package/dist/commands/setup/uploads/templates/requireUploadToken.ts.template +15 -0
  165. package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +23 -24
  166. package/dist/commands/setup/uploads/templates/uploads.sdl.ts.template +79 -0
  167. package/dist/commands/setup/uploads/templates/uploads.ts.template +98 -0
  168. package/dist/commands/setup/uploads/templates/withDataUri.ts.template +14 -0
  169. package/dist/commands/setup/uploads/templates/withSignedUrl.ts.template +16 -0
  170. package/dist/commands/setup/uploads/uploads.js +49 -7
  171. package/dist/commands/setup/uploads/uploadsHandler.js +277 -69
  172. package/dist/commands/setup.js +2 -1
  173. package/dist/commands/studio.js +1 -1
  174. package/dist/commands/test/testHandler.js +25 -71
  175. package/dist/commands/test/viteVersionCheck.js +75 -0
  176. package/dist/commands/test.js +10 -18
  177. package/dist/commands/type-checkHandler.js +1 -1
  178. package/dist/commands/upgrade/preUpgradeScripts.js +3 -3
  179. package/dist/commands/upgrade/upgrade.js +1 -1
  180. package/dist/commands/upgrade/upgradeHandler.js +2 -1
  181. package/dist/index.js +5 -8
  182. package/dist/lib/exit.js +1 -1
  183. package/dist/lib/index.js +16 -31
  184. package/dist/lib/loadEnvFiles.js +1 -1
  185. package/dist/lib/plugin.js +1 -1
  186. package/dist/lib/test.js +1 -1
  187. package/dist/lib/updateCheck.js +4 -4
  188. package/dist/middleware/checkNodeVersion.js +4 -4
  189. package/package.json +27 -27
  190. package/dist/commands/setup/ui/templates/postcss.config.cjs.template +0 -9
  191. package/dist/commands/setup/uploads/dbCodemod.js +0 -28
  192. package/dist/commands/setup/uploads/templates/signedUrl.ts.template +0 -21
  193. package/dist/commands/test/testHandlerEsm.js +0 -109
  194. package/dist/commands/testEsm.js +0 -41
@@ -1,16 +1,17 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
3
  import { Listr } from "listr2";
4
+ import { colors } from "@cedarjs/cli-helpers/colors";
5
+ import { prettify, writeFilesTask } from "@cedarjs/cli-helpers/fileHelpers";
4
6
  import {
5
7
  addApiPackages,
8
+ addWebPackages
9
+ } from "@cedarjs/cli-helpers/installHelpers";
10
+ import { getPaths } from "@cedarjs/cli-helpers/paths";
11
+ import {
6
12
  addEnvVarTask,
7
- addWebPackages,
8
- colors,
9
- getPaths,
10
- isTypeScriptProject,
11
- prettify,
12
- writeFilesTask
13
- } from "@cedarjs/cli-helpers";
13
+ isTypeScriptProject
14
+ } from "@cedarjs/cli-helpers/project";
14
15
  import { getConfigPath } from "@cedarjs/project-config";
15
16
  import { errorTelemetry } from "@cedarjs/telemetry";
16
17
  const rwPaths = getPaths();
@@ -75,7 +76,6 @@ const handler = async ({ force }) => {
75
76
  "export const handler = createGraphQLHandler({",
76
77
  "extraPlugins: [useSentry({",
77
78
  " includeRawResult: true,",
78
- " includeResolverArgs: true,",
79
79
  " includeExecuteVariables: true,",
80
80
  "})],"
81
81
  );
@@ -111,7 +111,11 @@ const handler = async ({ force }) => {
111
111
  contentLines.splice(
112
112
  boundaryOpenIndex,
113
113
  1,
114
- "<Sentry.ErrorBoundary fallback={FatalErrorPage}>"
114
+ "<Sentry.ErrorBoundary",
115
+ " fallback={({ error }) => (",
116
+ " <FatalErrorPage error={error instanceof Error ? error : undefined} />",
117
+ " )}",
118
+ ">"
115
119
  );
116
120
  const boundaryCloseIndex = contentLines.findLastIndex(
117
121
  (line) => line.includes("</FatalErrorBoundary>")
@@ -3,10 +3,7 @@ import * as Sentry from '@sentry/node'
3
3
  Sentry.init({
4
4
  dsn: process.env.SENTRY_DSN,
5
5
  environment: process.env.NODE_ENV,
6
- integrations: [
7
- Sentry.prismaIntegration(),
8
- Sentry.httpIntegration(),
9
- ],
6
+ integrations: [Sentry.prismaIntegration(), Sentry.httpIntegration()],
10
7
  tracesSampleRate: 1.0,
11
8
  })
12
9
 
@@ -1,9 +1,12 @@
1
1
  import * as Sentry from '@sentry/react'
2
2
 
3
+ const sentryDsn =
4
+ typeof process === 'undefined' ? undefined : process.env?.SENTRY_DSN
5
+
3
6
  let dsn = ''
4
7
  let environment = 'development'
5
8
 
6
- if (typeof process === 'undefined' || !process.env?.SENTRY_DSN) {
9
+ if (!sentryDsn) {
7
10
  console.error(
8
11
  'Missing SENTRY_DSN environment variable. Did you forget to add it to ' +
9
12
  'your cedar.toml (or redwood.toml) in `includeEnvironmentVariables`?'
@@ -17,14 +20,14 @@ if (typeof process === 'undefined' || !process.env?.SENTRY_DSN) {
17
20
  `)
18
21
  console.error('Sentry is disabled for now')
19
22
  } else {
20
- dsn = process.env.SENTRY_DSN
21
- environment = process.env.NODE_ENV
23
+ dsn = sentryDsn
24
+ environment = process.env.NODE_ENV ?? 'development'
22
25
  }
23
26
 
24
27
  Sentry.init({
25
28
  dsn,
26
29
  environment,
27
- integrations: [ Sentry.browserTracingIntegration() ],
30
+ integrations: [Sentry.browserTracingIntegration()],
28
31
  tracesSampleRate: 1.0,
29
32
  })
30
33
 
@@ -1,4 +1,4 @@
1
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
1
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
2
2
  const command = "neon";
3
3
  const description = "Provision a Neon Postgres database and configure your project";
4
4
  function builder(yargs) {
@@ -3,8 +3,11 @@ import path from "node:path";
3
3
  import execa from "execa";
4
4
  import { Listr } from "listr2";
5
5
  import prompts from "prompts";
6
- import { colors, getPaths, installPackages } from "@cedarjs/cli-helpers";
6
+ import { colors } from "@cedarjs/cli-helpers/colors";
7
+ import { installPackages } from "@cedarjs/cli-helpers/installHelpers";
7
8
  import { prettyPrintCedarCommand } from "@cedarjs/cli-helpers/packageManager";
9
+ import { getPaths } from "@cedarjs/cli-helpers/paths";
10
+ import { requireTTYOrExit } from "@cedarjs/cli-helpers/tty";
8
11
  import { errorTelemetry } from "@cedarjs/telemetry";
9
12
  import {
10
13
  checkProjectShape,
@@ -54,14 +57,7 @@ async function handler({ force, migrations, verbose }) {
54
57
  }
55
58
  let runMigrations = migrations;
56
59
  if (!skipProvisioning && runMigrations === void 0) {
57
- if (!process.stdin.isTTY) {
58
- const error = new Error(
59
- "Cannot prompt for confirmation in a non-interactive terminal. Please pass --migrations or --no-migrations explicitly."
60
- );
61
- errorTelemetry(process.argv, error.message);
62
- console.error(colors.error(error.message));
63
- process.exit(1);
64
- }
60
+ requireTTYOrExit("--migrations or --no-migrations");
65
61
  const response = await prompts({
66
62
  type: "toggle",
67
63
  name: "runMigrations",
@@ -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,7 +1,7 @@
1
1
  import enq from "enquirer";
2
- import semver from "semver";
3
- import { getCompatibilityData } from "@cedarjs/cli-helpers";
2
+ import { isGreaterThanOrEqual, isLessThan, tryParse } from "verkit";
4
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
6
  async function handler({
7
7
  npmPackage,
@@ -16,7 +16,7 @@ async function handler({
16
16
  console.log(
17
17
  "No compatibility check will be performed because you used the --force flag."
18
18
  );
19
- if (semver.parse(packageVersion) !== null && semver.lt(packageVersion, "1.0.0")) {
19
+ if (tryParse(packageVersion) !== null && isLessThan(packageVersion, "1.0.0")) {
20
20
  console.log(
21
21
  "Be aware that this package is under version 1.0.0 and so should be considered experimental."
22
22
  );
@@ -86,7 +86,7 @@ The latest version compatible with your project is ${latestCompatibleVersionText
86
86
  await runPackage(packageName, versionToUse, additionalOptionsToForward);
87
87
  }
88
88
  async function showExperimentalWarning(version) {
89
- if (version === void 0 || semver.parse(version) === null || semver.gte(version, "1.0.0")) {
89
+ if (version === void 0 || tryParse(version) === null || isGreaterThanOrEqual(version, "1.0.0")) {
90
90
  return;
91
91
  }
92
92
  const decision = await promptWithChoices(
@@ -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) {
@@ -2,10 +2,10 @@ import fs from "node:fs";
2
2
  import path from "path";
3
3
  import { Listr } from "listr2";
4
4
  import prompts from "prompts";
5
- import { addApiPackages, colors as c } from "@cedarjs/cli-helpers";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
+ import { addApiPackages } from "@cedarjs/cli-helpers/installHelpers";
6
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
10
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
11
11
  import { isTypeScriptProject, serverFileExists } from "../../../lib/project.js";
@@ -77,7 +77,7 @@ async function handler(args) {
77
77
  title: "Adding Countdown example subscription...",
78
78
  enabled: () => includeExamples,
79
79
  task: async () => {
80
- let exampleSubscriptionTemplateContent = fs.readFileSync(
80
+ const exampleSubscriptionTemplateContent = fs.readFileSync(
81
81
  path.resolve(
82
82
  import.meta.dirname,
83
83
  "templates",
@@ -87,12 +87,6 @@ async function handler(args) {
87
87
  ),
88
88
  "utf-8"
89
89
  );
90
- if (projectIsEsm()) {
91
- exampleSubscriptionTemplateContent = exampleSubscriptionTemplateContent.replace(
92
- "import gql from 'graphql-tag'",
93
- "import { gql } from 'graphql-tag'"
94
- );
95
- }
96
90
  const exampleFile = path.join(
97
91
  cedarPaths.api.subscriptions,
98
92
  "countdown",
@@ -144,7 +138,7 @@ async function handler(args) {
144
138
  `rooms.${isTypeScriptProject() ? "ts" : "js"}`
145
139
  );
146
140
  const serviceContent = ts ? exampleServiceTemplateContent : await transformTSToJS(serviceFile, exampleServiceTemplateContent);
147
- let exampleSubscriptionTemplateContent = fs.readFileSync(
141
+ const exampleSubscriptionTemplateContent = fs.readFileSync(
148
142
  path.resolve(
149
143
  import.meta.dirname,
150
144
  "templates",
@@ -154,12 +148,6 @@ async function handler(args) {
154
148
  ),
155
149
  "utf-8"
156
150
  );
157
- if (projectIsEsm()) {
158
- exampleSubscriptionTemplateContent = exampleSubscriptionTemplateContent.replace(
159
- "import gql from 'graphql-tag'",
160
- "import { gql } from 'graphql-tag'"
161
- );
162
- }
163
151
  const exampleFile = path.join(
164
152
  cedarPaths.api.subscriptions,
165
153
  "newMessage",
@@ -7,7 +7,10 @@ export const fastField = async () => {
7
7
  return 'I am fast'
8
8
  }
9
9
 
10
- export const slowField = async (_, { waitFor = 5000 }) => {
10
+ export const slowField = async (
11
+ _: unknown,
12
+ { waitFor = 5000 }: { waitFor?: number }
13
+ ) => {
11
14
  logger.debug('waiting on slowField')
12
15
  await wait(waitFor)
13
16
  return 'I am slow'
@@ -1,8 +1,16 @@
1
+ import type { BidInput } from 'types/graphql'
2
+
1
3
  import type { LiveQueryStorageMechanism } from '@cedarjs/realtime'
2
4
 
3
5
  import { logger } from 'src/lib/logger'
4
6
 
5
- const auctions = [
7
+ interface AuctionData {
8
+ id: string
9
+ title: string
10
+ bids: { amount: number }[]
11
+ }
12
+
13
+ const auctions: AuctionData[] = [
6
14
  { id: '1', title: 'RedwoodJS Logo Shirt', bids: [{ amount: 20 }] },
7
15
  { id: '2', title: 'RedwoodJS Lapel Pin', bids: [{ amount: 5 }] },
8
16
  { id: '3', title: 'RedwoodJS Beanie', bids: [{ amount: 15 }] },
@@ -34,14 +42,14 @@ const auctions = [
34
42
  * }
35
43
  * }
36
44
  */
37
- export const auction = async ({ id }) => {
45
+ export const auction = async ({ id }: { id: string }) => {
38
46
  const foundAuction = auctions.find((a) => a.id === id)
39
47
  logger.debug({ id, auction: foundAuction }, 'auction')
40
48
  return foundAuction
41
49
  }
42
50
 
43
51
  export const bid = async (
44
- { input },
52
+ { input }: { input: BidInput },
45
53
  { context }: { context: { liveQueryStore: LiveQueryStorageMechanism } }
46
54
  ) => {
47
55
  const { auctionId, amount } = input
@@ -62,7 +70,7 @@ export const bid = async (
62
70
  }
63
71
 
64
72
  export const Auction = {
65
- highestBid: (obj, { root }) => {
73
+ highestBid: (obj: unknown, { root }: { root: AuctionData }) => {
66
74
  const [max] = root.bids.sort((a, b) => b.amount - a.amount)
67
75
 
68
76
  logger.debug({ obj, root }, 'highestBid')
@@ -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
 
@@ -48,7 +48,7 @@ const newMessage = {
48
48
 
49
49
  return pubSub.subscribe('newMessage', roomId)
50
50
  },
51
- resolve: (payload) => {
51
+ resolve: (payload: NewMessageChannel['newMessage'][1]) => {
52
52
  logger.debug({ payload }, 'newMessage subscription resolve')
53
53
 
54
54
  return payload
@@ -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,7 +1,8 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
3
  import { Listr } from "listr2";
4
- import { addApiPackages, colors as c } 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
7
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
7
8
  import { isTypeScriptProject } from "../../../lib/project.js";
@@ -0,0 +1,66 @@
1
+ import j from "jscodeshift";
2
+ function buildMembershipsSelectProperty() {
3
+ const snippet = `
4
+ const __tenancySnippet = {
5
+ memberships: {
6
+ select: {
7
+ id: true,
8
+ organizationId: true,
9
+ role: true,
10
+ organization: { select: { id: true, slug: true, name: true } },
11
+ },
12
+ },
13
+ }
14
+ `;
15
+ const property = j.withParser("ts")(snippet).find(j.ObjectProperty, { key: { name: "memberships" } }).nodes()[0];
16
+ if (!property) {
17
+ throw new Error("CEDAR_CODEMOD_ERR_AUTH_SHAPE_NOT_FOUND");
18
+ }
19
+ return property;
20
+ }
21
+ function transform(fileInfo) {
22
+ const root = j.withParser("tsx")(fileInfo.source);
23
+ let selectFound = false;
24
+ root.find(j.CallExpression, {
25
+ callee: {
26
+ type: "MemberExpression",
27
+ object: {
28
+ type: "MemberExpression",
29
+ object: { name: "db" },
30
+ property: { name: "user" }
31
+ },
32
+ property: { name: "findUnique" }
33
+ }
34
+ }).forEach((path) => {
35
+ const [args] = path.node.arguments;
36
+ if (!j.ObjectExpression.check(args)) {
37
+ return;
38
+ }
39
+ const selectProperty = args.properties.find(
40
+ (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "select"
41
+ );
42
+ if (!selectProperty || !j.ObjectProperty.check(selectProperty) || !j.ObjectExpression.check(selectProperty.value)) {
43
+ return;
44
+ }
45
+ const alreadyHasMemberships = selectProperty.value.properties.some(
46
+ (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "memberships"
47
+ );
48
+ if (!alreadyHasMemberships) {
49
+ selectProperty.value.properties.push(buildMembershipsSelectProperty());
50
+ }
51
+ selectFound = true;
52
+ });
53
+ if (!selectFound) {
54
+ throw new Error("CEDAR_CODEMOD_ERR_AUTH_SHAPE_NOT_FOUND");
55
+ }
56
+ const tenancyExportSnippet = `export { hasOrgRole, requireMembership } from '@cedarjs/tenancy'
57
+ `;
58
+ const tenancyExport = j.withParser("ts")(tenancyExportSnippet).find(j.ExportNamedDeclaration).nodes()[0];
59
+ root.find(j.Program).forEach((path) => {
60
+ path.node.body.push(tenancyExport);
61
+ });
62
+ return root.toSource();
63
+ }
64
+ export {
65
+ transform as default
66
+ };
@@ -0,0 +1,64 @@
1
+ import j from "jscodeshift";
2
+ const DEFAULT_GLOBAL_MODELS = ["user", "organization", "membership"];
3
+ function transform(fileInfo, _api, options) {
4
+ const root = j.withParser("tsx")(fileInfo.source);
5
+ const tenantField = typeof options.tenantField === "string" ? options.tenantField : void 0;
6
+ const imports = root.find(j.ImportDeclaration);
7
+ imports.at(-1).insertAfter(
8
+ j.importDeclaration(
9
+ [j.importSpecifier(j.identifier("createTenancyExtension"))],
10
+ j.literal("@cedarjs/tenancy")
11
+ )
12
+ );
13
+ const configProperties = [
14
+ ...tenantField ? [
15
+ j.objectProperty(
16
+ j.identifier("tenantField"),
17
+ j.stringLiteral(tenantField)
18
+ )
19
+ ] : [],
20
+ j.objectProperty(
21
+ j.identifier("models"),
22
+ j.objectExpression([
23
+ j.objectProperty(
24
+ j.identifier("allExcept"),
25
+ j.arrayExpression(
26
+ DEFAULT_GLOBAL_MODELS.map((name) => j.stringLiteral(name))
27
+ )
28
+ )
29
+ ])
30
+ )
31
+ ];
32
+ let found = false;
33
+ root.find(j.VariableDeclaration, { declarations: [{ id: { name: "db" } }] }).forEach((path) => {
34
+ const dbDeclaration = path.node.declarations[0];
35
+ if (!j.VariableDeclarator.check(dbDeclaration)) {
36
+ return;
37
+ }
38
+ if (j.NewExpression.check(dbDeclaration.init)) {
39
+ throw new Error("CEDAR_CODEMOD_ERR_OLD_FORMAT");
40
+ }
41
+ if (!j.Expression.check(dbDeclaration.init)) {
42
+ return;
43
+ }
44
+ found = true;
45
+ const extensionCall = j.callExpression(
46
+ j.identifier("createTenancyExtension"),
47
+ [j.objectExpression(configProperties)]
48
+ );
49
+ dbDeclaration.init = j.callExpression(
50
+ j.memberExpression(dbDeclaration.init, j.identifier("$extends")),
51
+ [extensionCall]
52
+ );
53
+ });
54
+ if (!found) {
55
+ throw new Error("CEDAR_CODEMOD_ERR_DB_SHAPE_NOT_FOUND");
56
+ }
57
+ return root.toSource().replace(
58
+ "createTenancyExtension(",
59
+ "createTenancyExtension<typeof prismaClient>("
60
+ );
61
+ }
62
+ export {
63
+ transform as default
64
+ };
@@ -0,0 +1,88 @@
1
+ import j from "jscodeshift";
2
+ function buildContextProperty() {
3
+ const snippet = `
4
+ const __tenancySnippet = {
5
+ context: async ({ context: gqlContext }) => {
6
+ const { currentUser, event, request, params } = gqlContext
7
+
8
+ // A user whose getCurrentUser result doesn't carry memberships
9
+ // can't be matched to an organization, so the request runs with
10
+ // no current organization set.
11
+ if (!isUserWithMemberships(currentUser)) {
12
+ return {}
13
+ }
14
+
15
+ // Yoga can populate either \`event\` (Lambda-style deployments) or
16
+ // \`request\` (Fetch-API-style deployments); resolveCurrentOrg reads
17
+ // the organization header off either.
18
+ const requestEvent = event ?? request
19
+
20
+ if (!requestEvent) {
21
+ return {}
22
+ }
23
+
24
+ const currentOrg = await resolveCurrentOrg({
25
+ event: requestEvent,
26
+ variables: params.variables,
27
+ currentUser,
28
+ lookupOrg: async (idOrSlug) =>
29
+ (await db.organization.findUnique({
30
+ where: { id: idOrSlug },
31
+ select: { id: true, slug: true },
32
+ })) ??
33
+ db.organization.findUnique({
34
+ where: { slug: idOrSlug },
35
+ select: { id: true, slug: true },
36
+ }),
37
+ })
38
+
39
+ return { currentOrg }
40
+ },
41
+ }
42
+ `;
43
+ const property = j.withParser("ts")(snippet).find(j.ObjectProperty, { key: { name: "context" } }).nodes()[0];
44
+ if (!property) {
45
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
46
+ }
47
+ return property;
48
+ }
49
+ function addNamedImport(root, names, source) {
50
+ const imports = root.find(j.ImportDeclaration);
51
+ imports.at(-1).insertAfter(
52
+ j.importDeclaration(
53
+ names.map((name) => j.importSpecifier(j.identifier(name))),
54
+ j.literal(source)
55
+ )
56
+ );
57
+ }
58
+ function transform(fileInfo) {
59
+ const root = j.withParser("tsx")(fileInfo.source);
60
+ const handlerCalls = root.find(j.CallExpression, {
61
+ callee: { name: "createGraphQLHandler" }
62
+ });
63
+ if (handlerCalls.length === 0) {
64
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
65
+ }
66
+ handlerCalls.forEach((path) => {
67
+ const [config] = path.node.arguments;
68
+ if (!j.ObjectExpression.check(config)) {
69
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_HANDLER_NOT_FOUND");
70
+ }
71
+ const hasContext = config.properties.some(
72
+ (prop) => j.ObjectProperty.check(prop) && j.Identifier.check(prop.key) && prop.key.name === "context"
73
+ );
74
+ if (hasContext) {
75
+ throw new Error("CEDAR_CODEMOD_ERR_GRAPHQL_CONTEXT_EXISTS");
76
+ }
77
+ config.properties.push(buildContextProperty());
78
+ });
79
+ addNamedImport(
80
+ root,
81
+ ["isUserWithMemberships", "resolveCurrentOrg"],
82
+ "@cedarjs/tenancy"
83
+ );
84
+ return root.toSource();
85
+ }
86
+ export {
87
+ transform as default
88
+ };
@@ -0,0 +1,49 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
4
+ const WEB_AUTH_EXTENSIONS = ["ts", "tsx", "js", "jsx"];
5
+ function hasWebAuthFile(webSrcPath) {
6
+ return WEB_AUTH_EXTENSIONS.some(
7
+ (extension) => fs.existsSync(path.join(webSrcPath, `auth.${extension}`))
8
+ );
9
+ }
10
+ function authNotSetUpMessage() {
11
+ return [
12
+ "Auth is not set up in this project.",
13
+ "",
14
+ "Tenancy builds on your app's auth: it adds memberships to",
15
+ "`getCurrentUser`, and resolves the current organization from the",
16
+ "signed-in user's memberships. Set up auth first, then run this command",
17
+ "again:",
18
+ "",
19
+ ` ${formatCedarCommand(["setup", "auth", "dbAuth"])}`,
20
+ "",
21
+ "Any provider works. See https://cedarjs.com/docs/authentication"
22
+ ].join("\n");
23
+ }
24
+ function noUserModelMessage(schemaPath) {
25
+ return [
26
+ `No \`User\` model found in ${schemaPath}.`,
27
+ "",
28
+ "Tenancy hangs memberships off your app's `User` model, so it needs one",
29
+ "before it can add `Organization` and `Membership`.",
30
+ "",
31
+ "dbAuth adds this model for you. Providers that authenticate against an",
32
+ "external service leave it to you: give `User` its own id and store the",
33
+ "provider's id in a column beside it, so memberships keep working if you",
34
+ "switch providers or add a second one.",
35
+ "",
36
+ `Add a model like this one, run \`${formatCedarCommand(["prisma", "migrate", "dev"])}\`, then`,
37
+ "run this command again:",
38
+ "",
39
+ " model User {",
40
+ " id String @id @default(cuid())",
41
+ " email String @unique",
42
+ " }"
43
+ ].join("\n");
44
+ }
45
+ export {
46
+ authNotSetUpMessage,
47
+ hasWebAuthFile,
48
+ noUserModelMessage
49
+ };