@cedarjs/cli 7.0.0 → 8.0.0-canary.3263

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 (168) 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 +1 -1
  5. package/dist/commands/deploy/baremetal.js +1 -1
  6. package/dist/commands/deploy/flightcontrolHandler.js +1 -1
  7. package/dist/commands/deploy/helpers/deployHandler.js +1 -1
  8. package/dist/commands/deploy/netlify.js +1 -1
  9. package/dist/commands/deploy/renderHandler.js +1 -1
  10. package/dist/commands/deploy/serverlessHandler.js +2 -1
  11. package/dist/commands/deploy/vercel.js +1 -1
  12. package/dist/commands/destroy/handlerHelpers.js +1 -1
  13. package/dist/commands/destroy/page/pageHandler.js +2 -1
  14. package/dist/commands/destroy/scaffold/scaffoldHandler.js +2 -1
  15. package/dist/commands/destroy/sdl/sdlHandler.js +2 -1
  16. package/dist/commands/dev/devHandler.js +3 -4
  17. package/dist/commands/dev/packageWatchCommands.js +8 -3
  18. package/dist/commands/dev.js +1 -1
  19. package/dist/commands/execHandler.js +2 -1
  20. package/dist/commands/experimental/live-queries/liveQueries.js +1 -1
  21. package/dist/commands/experimental/live-queries/liveQueriesHandler.js +3 -3
  22. package/dist/commands/experimental/setupInngest.js +1 -1
  23. package/dist/commands/experimental/setupInngestHandler.js +1 -1
  24. package/dist/commands/experimental/setupOpentelemetry.js +1 -1
  25. package/dist/commands/experimental/setupOpentelemetryHandler.js +2 -1
  26. package/dist/commands/experimental/setupReactCompiler.js +1 -1
  27. package/dist/commands/experimental/setupReactCompilerHandler.js +4 -4
  28. package/dist/commands/experimental/setupRsc.js +1 -1
  29. package/dist/commands/experimental/setupRscHandler.js +2 -1
  30. package/dist/commands/experimental/setupStreamingSsr.js +1 -1
  31. package/dist/commands/experimental/setupStreamingSsrHandler.js +3 -2
  32. package/dist/commands/generate/cell/cell.js +20 -0
  33. package/dist/commands/generate/cell/cellHandler.js +68 -20
  34. package/dist/commands/generate/cell/templates/cell.tsx.template +21 -2
  35. package/dist/commands/generate/cell/templates/cellFragment.tsx.template +43 -0
  36. package/dist/commands/generate/cell/templates/cellList.tsx.template +21 -2
  37. package/dist/commands/generate/cell/templates/storiesFragment.tsx.template +23 -0
  38. package/dist/commands/generate/cell/templates/test.js.template +1 -1
  39. package/dist/commands/generate/cell/templates/testFragment.js.template +30 -0
  40. package/dist/commands/generate/dataMigration/dataMigration.js +2 -1
  41. package/dist/commands/generate/dbAuth/dbAuthHandler.js +23 -3
  42. package/dist/commands/generate/dbAuth/templates/login.oauth.tsx.template +164 -0
  43. package/dist/commands/generate/dbAuth/templates/signup.oauth.tsx.template +147 -0
  44. package/dist/commands/generate/directive/directiveHandler.js +2 -1
  45. package/dist/commands/generate/function/functionHandler.js +2 -1
  46. package/dist/commands/generate/job/jobHandler.js +2 -1
  47. package/dist/commands/generate/model/modelHandler.js +2 -1
  48. package/dist/commands/generate/ogImage/ogImageHandler.js +2 -1
  49. package/dist/commands/generate/package/filesTask.js +9 -12
  50. package/dist/commands/generate/package/packageHandler.js +3 -4
  51. package/dist/commands/generate/page/pageHandler.js +2 -1
  52. package/dist/commands/generate/realtime/realtime.js +1 -1
  53. package/dist/commands/generate/realtime/realtimeHandler.js +2 -9
  54. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +1 -1
  55. package/dist/commands/generate/scaffold/scaffoldHandler.js +10 -5
  56. package/dist/commands/generate/scaffold/templates/components/NameForm.tsx.template +3 -3
  57. package/dist/commands/generate/scaffold/templates/lib/formatters.test.tsx.template +11 -0
  58. package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +13 -1
  59. package/dist/commands/generate/script/scriptHandler.js +2 -1
  60. package/dist/commands/generate/sdl/sdlHandler.js +2 -1
  61. package/dist/commands/generate/secret/secret.js +1 -1
  62. package/dist/commands/generate/service/serviceHandler.js +47 -38
  63. package/dist/commands/generate/service/templates/service.ts.template +22 -8
  64. package/dist/commands/generate/service/templates/test.ts.template +1 -1
  65. package/dist/commands/generate/yargsCommandHelpers.js +1 -1
  66. package/dist/commands/generate/yargsHandlerHelpers.js +2 -1
  67. package/dist/commands/generate.js +1 -1
  68. package/dist/commands/info.js +1 -1
  69. package/dist/commands/lint.js +1 -1
  70. package/dist/commands/prerenderHandler.js +11 -4
  71. package/dist/commands/prismaHandler.js +7 -2
  72. package/dist/commands/record/init.js +1 -1
  73. package/dist/commands/serve.js +2 -1
  74. package/dist/commands/setup/auth/auth.js +2 -4
  75. package/dist/commands/setup/cache/cache.js +1 -1
  76. package/dist/commands/setup/cache/cacheHandler.js +2 -1
  77. package/dist/commands/setup/database/postgres.js +1 -1
  78. package/dist/commands/setup/database/postgresHandler.js +3 -1
  79. package/dist/commands/setup/deploy/providers/baremetalHandler.js +2 -1
  80. package/dist/commands/setup/deploy/providers/coherence.js +1 -1
  81. package/dist/commands/setup/deploy/providers/coherenceHandler.js +7 -6
  82. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +2 -1
  83. package/dist/commands/setup/deploy/providers/netlifyHandler.js +2 -1
  84. package/dist/commands/setup/deploy/providers/renderHandler.js +2 -1
  85. package/dist/commands/setup/deploy/providers/serverlessHandler.js +2 -1
  86. package/dist/commands/setup/deploy/providers/universalDeployHandler.js +4 -6
  87. package/dist/commands/setup/deploy/providers/vercelHandler.js +2 -1
  88. package/dist/commands/setup/docker/docker.js +1 -1
  89. package/dist/commands/setup/docker/dockerHandler.js +2 -1
  90. package/dist/commands/setup/generator/generator.js +1 -1
  91. package/dist/commands/setup/generator/generatorHandler.js +1 -1
  92. package/dist/commands/setup/graphql/features/fragments/fragments.js +1 -1
  93. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +3 -5
  94. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +1 -1
  95. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +2 -1
  96. package/dist/commands/setup/i18n/i18n.js +1 -1
  97. package/dist/commands/setup/i18n/i18nHandler.js +1 -1
  98. package/dist/commands/setup/jobs/jobs.js +1 -1
  99. package/dist/commands/setup/jobs/jobsHandler.js +2 -1
  100. package/dist/commands/setup/mailer/mailer.js +1 -1
  101. package/dist/commands/setup/mailer/mailerHandler.js +2 -1
  102. package/dist/commands/setup/middleware/ogImage/ogImage.js +1 -1
  103. package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +2 -1
  104. package/dist/commands/setup/monitoring/sentry/sentry.js +1 -1
  105. package/dist/commands/setup/monitoring/sentry/sentryHandler.js +8 -7
  106. package/dist/commands/setup/neon/neon.js +1 -1
  107. package/dist/commands/setup/neon/neonHandler.js +5 -9
  108. package/dist/commands/setup/package/package.js +1 -1
  109. package/dist/commands/setup/package/packageHandler.js +4 -4
  110. package/dist/commands/setup/realtime/addRealtimeToGraphql.js +1 -1
  111. package/dist/commands/setup/realtime/realtime.js +1 -1
  112. package/dist/commands/setup/realtime/realtimeHandler.js +4 -16
  113. package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +1 -1
  114. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +1 -1
  115. package/dist/commands/setup/server-file/serverFile.js +1 -1
  116. package/dist/commands/setup/server-file/serverFileHandler.js +2 -1
  117. package/dist/commands/setup/tenancy/authCodemod.js +66 -0
  118. package/dist/commands/setup/tenancy/dbCodemod.js +64 -0
  119. package/dist/commands/setup/tenancy/graphqlCodemod.js +88 -0
  120. package/dist/commands/setup/tenancy/preflight.js +49 -0
  121. package/dist/commands/setup/tenancy/schemaPrisma.js +81 -0
  122. package/dist/commands/setup/tenancy/signupCodemod.js +153 -0
  123. package/dist/commands/setup/tenancy/templates/InvitePage.tsx.template +63 -0
  124. package/dist/commands/setup/tenancy/templates/OrgScope.tsx.template +40 -0
  125. package/dist/commands/setup/tenancy/templates/ensureDefaultOrganizations.dataMigration.ts.template +39 -0
  126. package/dist/commands/setup/tenancy/templates/organizations.scenarios.ts.template +59 -0
  127. package/dist/commands/setup/tenancy/templates/organizations.sdl.ts.template +89 -0
  128. package/dist/commands/setup/tenancy/templates/organizations.test.ts.template +389 -0
  129. package/dist/commands/setup/tenancy/templates/organizations.ts.template +394 -0
  130. package/dist/commands/setup/tenancy/templates/requireMembership.test.ts.template +35 -0
  131. package/dist/commands/setup/tenancy/templates/requireMembership.ts.template +25 -0
  132. package/dist/commands/setup/tenancy/tenancy.js +30 -0
  133. package/dist/commands/setup/tenancy/tenancyHandler.js +425 -0
  134. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +2 -1
  135. package/dist/commands/setup/ui/libraries/mantineHandler.js +2 -1
  136. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +2 -1
  137. package/dist/commands/setup/uploads/schemaPrisma.js +41 -0
  138. package/dist/commands/setup/uploads/serverFile.js +151 -0
  139. package/dist/commands/setup/uploads/templates/requireUploadToken.ts.template +15 -0
  140. package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +23 -24
  141. package/dist/commands/setup/uploads/templates/uploads.sdl.ts.template +79 -0
  142. package/dist/commands/setup/uploads/templates/uploads.ts.template +89 -0
  143. package/dist/commands/setup/uploads/templates/withDataUri.ts.template +14 -0
  144. package/dist/commands/setup/uploads/templates/withSignedUrl.ts.template +16 -0
  145. package/dist/commands/setup/uploads/uploads.js +49 -7
  146. package/dist/commands/setup/uploads/uploadsHandler.js +256 -69
  147. package/dist/commands/setup.js +2 -1
  148. package/dist/commands/studio.js +1 -1
  149. package/dist/commands/test/testHandler.js +25 -71
  150. package/dist/commands/test/viteVersionCheck.js +75 -0
  151. package/dist/commands/test.js +10 -18
  152. package/dist/commands/type-checkHandler.js +1 -1
  153. package/dist/commands/upgrade/preUpgradeScripts.js +3 -3
  154. package/dist/commands/upgrade/upgrade.js +1 -1
  155. package/dist/commands/upgrade/upgradeHandler.js +2 -1
  156. package/dist/index.js +5 -8
  157. package/dist/lib/exit.js +1 -1
  158. package/dist/lib/index.js +6 -25
  159. package/dist/lib/loadEnvFiles.js +1 -1
  160. package/dist/lib/plugin.js +1 -1
  161. package/dist/lib/test.js +1 -1
  162. package/dist/lib/updateCheck.js +4 -4
  163. package/dist/middleware/checkNodeVersion.js +4 -4
  164. package/package.json +18 -18
  165. package/dist/commands/setup/uploads/dbCodemod.js +0 -28
  166. package/dist/commands/setup/uploads/templates/signedUrl.ts.template +0 -21
  167. package/dist/commands/test/testHandlerEsm.js +0 -109
  168. package/dist/commands/testEsm.js +0 -41
@@ -3,7 +3,9 @@ import type { ${operationName}, ${operationName}Variables } from 'types/graphql
3
3
  import type {
4
4
  CellSuccessProps,
5
5
  CellFailureProps,
6
- TypedDocumentNode,
6
+ TypedDocumentNode,<% if (beforeQuery) { %>
7
+ CellBeforeQueryResult,<% } %><% if (afterQuery || isEmpty) { %>
8
+ DataObject,<% } %>
7
9
  } from '@cedarjs/web'
8
10
 
9
11
  export const QUERY: TypedDocumentNode<
@@ -16,7 +18,24 @@ export const QUERY: TypedDocumentNode<
16
18
  }
17
19
  }
18
20
  `
19
-
21
+ <% if (beforeQuery) { %>
22
+ export const beforeQuery = (
23
+ props: ${operationName}Variables,
24
+ ): CellBeforeQueryResult<${operationName}Variables> => {
25
+ return { variables: props, fetchPolicy: 'cache-and-network' }
26
+ }
27
+ <% } %><% if (isEmpty) { %>
28
+ export const isEmpty = (
29
+ data: DataObject,
30
+ { isDataEmpty }: { isDataEmpty: (data: DataObject) => boolean },
31
+ ) => {
32
+ return isDataEmpty(data)
33
+ }
34
+ <% } %><% if (afterQuery) { %>
35
+ export const afterQuery = (data: DataObject): DataObject => {
36
+ return data
37
+ }
38
+ <% } %>
20
39
  export const Loading = () => <div>Loading...</div>
21
40
 
22
41
  export const Empty = () => <div>Empty</div>
@@ -0,0 +1,23 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+
3
+ import { Empty, Success } from './${pascalName}Cell'
4
+ import { standard } from './${pascalName}Cell.mock'
5
+
6
+ const meta: Meta = {
7
+ title: 'Cells/${pascalName}Cell',
8
+ tags: ['autodocs']
9
+ }
10
+
11
+ export default meta
12
+
13
+ export const empty: StoryObj<typeof Empty> = {
14
+ render: () => {
15
+ return Empty ? <Empty /> : <></>
16
+ }
17
+ }
18
+
19
+ export const success: StoryObj<typeof Success> = {
20
+ render: (args) => {
21
+ return Success ? <Success {...standard()} {...args} /> : <></>
22
+ }
23
+ }
@@ -7,7 +7,7 @@ import { standard } from './${pascalName}Cell.mock'
7
7
  // and can fail without adjustments, e.g. Float and DateTime types.
8
8
  // Please refer to the RedwoodJS Testing Docs:
9
9
  // https://cedarjs.com/docs/testing#testing-cells
10
- // https://cedarjs.com/docs/testing#jest-expect-type-considerations
10
+ // https://cedarjs.com/docs/testing#expect-type-considerations
11
11
 
12
12
  describe('${pascalName}Cell', () => {
13
13
  it('renders Loading successfully', () => {
@@ -0,0 +1,30 @@
1
+ import { render } from '@cedarjs/testing/web'
2
+
3
+ import { Empty, Success } from './${pascalName}Cell'
4
+ import { standard } from './${pascalName}Cell.mock'
5
+
6
+ // Generated boilerplate tests do not account for all circumstances
7
+ // and can fail without adjustments, e.g. Float and DateTime types.
8
+ // Please refer to the RedwoodJS Testing Docs:
9
+ // https://cedarjs.com/docs/testing#testing-cells
10
+ // https://cedarjs.com/docs/testing#expect-type-considerations
11
+
12
+ describe('${pascalName}Cell', () => {
13
+ it('renders Empty successfully', async () => {
14
+ expect(() => {
15
+ render(<Empty />)
16
+ }).not.toThrow()
17
+ })
18
+
19
+ // When you're ready to test the actual output of your component render
20
+ // you could test that, for example, certain text is present:
21
+ //
22
+ // 1. import { screen } from '@cedarjs/testing/web'
23
+ // 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()
24
+
25
+ it('renders Success successfully', async () => {
26
+ expect(() => {
27
+ render(<Success ${camelName}={standard().${camelName}} />)
28
+ }).not.toThrow()
29
+ })
30
+ })
@@ -2,8 +2,9 @@ import path from "node:path";
2
2
  import { paramCase } from "change-case";
3
3
  import { Listr } from "listr2";
4
4
  import { terminalLink } from "termi-link";
5
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
6
  import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
7
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
7
8
  import { getDataMigrationsPath } from "@cedarjs/project-config";
8
9
  import {
9
10
  generateTemplate,
@@ -4,9 +4,10 @@ import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
4
4
  import { camelCase } from "camel-case";
5
5
  import { Listr } from "listr2";
6
6
  import { titleCase } from "title-case";
7
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
7
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
8
8
  import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
9
9
  import { runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
10
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
10
11
  import {
11
12
  addRoutesToRouterTask,
12
13
  addScaffoldImport,
@@ -75,12 +76,14 @@ const files = async ({
75
76
  skipReset,
76
77
  skipSignup,
77
78
  webauthn,
79
+ oauth,
78
80
  usernameLabel,
79
81
  passwordLabel
80
82
  }) => {
81
83
  const filesList = [];
82
84
  usernameLabel = usernameLabel || "username";
83
85
  passwordLabel = passwordLabel || "password";
86
+ const oauthEnabled = oauth ?? isOAuthEnabled();
84
87
  const templateVars = {
85
88
  usernameLowerCase: usernameLabel.toLowerCase(),
86
89
  usernameCamelCase: camelCase(usernameLabel),
@@ -110,7 +113,7 @@ const files = async ({
110
113
  extension: typescript ? ".tsx" : ".jsx",
111
114
  webPathSection: "pages",
112
115
  generator: "dbAuth",
113
- templatePath: webauthn ? "login.webAuthn.tsx.template" : "login.tsx.template",
116
+ templatePath: loginTemplatePath(webauthn, oauthEnabled),
114
117
  templateVars
115
118
  })
116
119
  );
@@ -136,7 +139,7 @@ const files = async ({
136
139
  extension: typescript ? ".tsx" : ".jsx",
137
140
  webPathSection: "pages",
138
141
  generator: "dbAuth",
139
- templatePath: "signup.tsx.template",
142
+ templatePath: oauthEnabled ? "signup.oauth.tsx.template" : "signup.tsx.template",
140
143
  templateVars
141
144
  })
142
145
  );
@@ -378,6 +381,23 @@ function isWebAuthnEnabled() {
378
381
  );
379
382
  return webPackageJson.includes('"@simplewebauthn/browser": ');
380
383
  }
384
+ function isOAuthEnabled() {
385
+ const apiPackageJsonPath = path.join(getPaths().base, "api", "package.json");
386
+ if (!fs.existsSync(apiPackageJsonPath)) {
387
+ return false;
388
+ }
389
+ const apiPackageJson = fs.readFileSync(apiPackageJsonPath, "utf-8");
390
+ return apiPackageJson.includes('"@cedarjs/auth-dbauth-oauth": ');
391
+ }
392
+ function loginTemplatePath(webauthn, oauth) {
393
+ if (webauthn) {
394
+ return "login.webAuthn.tsx.template";
395
+ }
396
+ if (oauth) {
397
+ return "login.oauth.tsx.template";
398
+ }
399
+ return "login.tsx.template";
400
+ }
381
401
  export {
382
402
  files,
383
403
  handler
@@ -0,0 +1,164 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ import {
4
+ Form,
5
+ Label,
6
+ TextField,
7
+ PasswordField,
8
+ Submit,
9
+ FieldError,
10
+ } from '@cedarjs/forms'
11
+ import { Link, navigate, routes } from '@cedarjs/router'
12
+ import { Metadata } from '@cedarjs/web'
13
+ import { toast, Toaster } from '@cedarjs/web/toast'
14
+
15
+ import { getOAuthUrl, getOAuthError } from '@cedarjs/auth-dbauth-web/oauth'
16
+
17
+ import { useAuth } from 'src/auth'
18
+
19
+ const LoginPage = () => {
20
+ const { isAuthenticated, logIn } = useAuth()
21
+
22
+ useEffect(() => {
23
+ if (isAuthenticated) {
24
+ navigate(routes.home())
25
+ }
26
+ }, [isAuthenticated])
27
+
28
+ // Surface an error that the OAuth provider redirect sent back, e.g.
29
+ // after the user cancels the provider's consent screen.
30
+ useEffect(() => {
31
+ const oauthError = getOAuthError(window.location.search)
32
+
33
+ if (oauthError) {
34
+ toast.error('Could not log in: ' + oauthError)
35
+ }
36
+ }, [])
37
+
38
+ const ${usernameCamelCase}Ref = useRef<HTMLInputElement>(null)
39
+ useEffect(() => {
40
+ ${usernameCamelCase}Ref.current?.focus()
41
+ }, [])
42
+
43
+ const onSubmit = async (data: Record<string, string>) => {
44
+ const response = await logIn({ username: data.${usernameCamelCase}, password: data.${passwordCamelCase} })
45
+
46
+ if (response.message) {
47
+ toast(response.message)
48
+ } else if (response.error) {
49
+ toast.error(response.error)
50
+ } else {
51
+ toast.success('Welcome back!')
52
+ }
53
+ }
54
+
55
+ return (
56
+ <>
57
+ <Metadata title="Login" />
58
+
59
+ <main className="rw-main">
60
+ <Toaster toastOptions={{ className: 'rw-toast', duration: 6000 }} />
61
+ <div className="rw-scaffold rw-login-container">
62
+ <div className="rw-segment">
63
+ <header className="rw-segment-header">
64
+ <h2 className="rw-heading rw-heading-secondary">Login</h2>
65
+ </header>
66
+
67
+ <div className="rw-segment-main">
68
+ <div className="rw-form-wrapper">
69
+ <Form onSubmit={onSubmit} className="rw-form-wrapper">
70
+ <Label
71
+ name="${usernameCamelCase}"
72
+ className="rw-label"
73
+ errorClassName="rw-label rw-label-error"
74
+ >
75
+ ${usernameTitleCase}
76
+ </Label>
77
+ <TextField
78
+ name="${usernameCamelCase}"
79
+ className="rw-input"
80
+ errorClassName="rw-input rw-input-error"
81
+ ref={${usernameCamelCase}Ref}
82
+ validation={{
83
+ required: {
84
+ value: true,
85
+ message: '${usernameTitleCase} is required',
86
+ },
87
+ }}
88
+ />
89
+
90
+ <FieldError name="${usernameCamelCase}" className="rw-field-error" />
91
+
92
+ <Label
93
+ name="${passwordCamelCase}"
94
+ className="rw-label"
95
+ errorClassName="rw-label rw-label-error"
96
+ >
97
+ ${passwordTitleCase}
98
+ </Label>
99
+ <PasswordField
100
+ name="${passwordCamelCase}"
101
+ className="rw-input"
102
+ errorClassName="rw-input rw-input-error"
103
+ autoComplete="current-password"
104
+ validation={{
105
+ required: {
106
+ value: true,
107
+ message: '${passwordTitleCase} is required',
108
+ },
109
+ }}
110
+ />
111
+
112
+ <div className="rw-forgot-link">
113
+ <Link
114
+ to={routes.forgotPassword()}
115
+ className="rw-forgot-link"
116
+ >
117
+ Forgot ${passwordTitleCase}?
118
+ </Link>
119
+ </div>
120
+
121
+ <FieldError name="${passwordCamelCase}" className="rw-field-error" />
122
+
123
+ <div className="rw-button-group">
124
+ <Submit className="rw-button rw-button-blue">Login</Submit>
125
+ </div>
126
+ </Form>
127
+
128
+ {/*
129
+ * OAuth login buttons. Delete the ones for providers you
130
+ * haven't configured in `cedar setup auth dbAuth --oauth`.
131
+ * Each link is a full-page navigation to the provider's
132
+ * authorize route — it must not be turned into a fetch/XHR
133
+ * call.
134
+ */}
135
+ <div className="rw-button-group">
136
+ <a
137
+ href={getOAuthUrl('google', { flow: 'login' })}
138
+ className="rw-button rw-button-blue"
139
+ >
140
+ Continue with Google
141
+ </a>
142
+ <a
143
+ href={getOAuthUrl('github', { flow: 'login' })}
144
+ className="rw-button rw-button-blue"
145
+ >
146
+ Continue with GitHub
147
+ </a>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ <div className="rw-login-link">
153
+ <span>Don&apos;t have an account?</span>{' '}
154
+ <Link to={routes.signup()} className="rw-link">
155
+ Sign up!
156
+ </Link>
157
+ </div>
158
+ </div>
159
+ </main>
160
+ </>
161
+ )
162
+ }
163
+
164
+ export default LoginPage
@@ -0,0 +1,147 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ import {
4
+ Form,
5
+ Label,
6
+ TextField,
7
+ PasswordField,
8
+ FieldError,
9
+ Submit,
10
+ } from '@cedarjs/forms'
11
+ import { Link, navigate, routes } from '@cedarjs/router'
12
+ import { Metadata } from '@cedarjs/web'
13
+ import { toast, Toaster } from '@cedarjs/web/toast'
14
+
15
+ import { getOAuthUrl } from '@cedarjs/auth-dbauth-web/oauth'
16
+
17
+ import { useAuth } from 'src/auth'
18
+
19
+ const SignupPage = () => {
20
+ const { isAuthenticated, signUp } = useAuth()
21
+
22
+ useEffect(() => {
23
+ if (isAuthenticated) {
24
+ navigate(routes.home())
25
+ }
26
+ }, [isAuthenticated])
27
+
28
+ // focus on ${usernameLowerCase} box on page load
29
+ const ${usernameCamelCase}Ref = useRef<HTMLInputElement>(null)
30
+ useEffect(() => {
31
+ ${usernameCamelCase}Ref.current?.focus()
32
+ }, [])
33
+
34
+ const onSubmit = async (data: Record<string, string>) => {
35
+ const response = await signUp({ username: data.${usernameCamelCase}, password: data.${passwordCamelCase} })
36
+
37
+ if (response.message) {
38
+ toast(response.message)
39
+ } else if (response.error) {
40
+ toast.error(response.error)
41
+ } else {
42
+ // user is signed in automatically
43
+ toast.success('Welcome!')
44
+ }
45
+ }
46
+
47
+ return (
48
+ <>
49
+ <Metadata title="Signup" />
50
+
51
+ <main className="rw-main">
52
+ <Toaster toastOptions={{ className: 'rw-toast', duration: 6000 }} />
53
+ <div className="rw-scaffold rw-login-container">
54
+ <div className="rw-segment">
55
+ <header className="rw-segment-header">
56
+ <h2 className="rw-heading rw-heading-secondary">Signup</h2>
57
+ </header>
58
+
59
+ <div className="rw-segment-main">
60
+ <div className="rw-form-wrapper">
61
+ <Form onSubmit={onSubmit} className="rw-form-wrapper">
62
+ <Label
63
+ name="${usernameCamelCase}"
64
+ className="rw-label"
65
+ errorClassName="rw-label rw-label-error"
66
+ >
67
+ ${usernameTitleCase}
68
+ </Label>
69
+ <TextField
70
+ name="${usernameCamelCase}"
71
+ className="rw-input"
72
+ errorClassName="rw-input rw-input-error"
73
+ ref={${usernameCamelCase}Ref}
74
+ validation={{
75
+ required: {
76
+ value: true,
77
+ message: '${usernameTitleCase} is required',
78
+ },
79
+ }}
80
+ />
81
+ <FieldError name="${usernameCamelCase}" className="rw-field-error" />
82
+
83
+ <Label
84
+ name="${passwordCamelCase}"
85
+ className="rw-label"
86
+ errorClassName="rw-label rw-label-error"
87
+ >
88
+ ${passwordTitleCase}
89
+ </Label>
90
+ <PasswordField
91
+ name="${passwordCamelCase}"
92
+ className="rw-input"
93
+ errorClassName="rw-input rw-input-error"
94
+ autoComplete="current-password"
95
+ validation={{
96
+ required: {
97
+ value: true,
98
+ message: '${passwordTitleCase} is required',
99
+ },
100
+ }}
101
+ />
102
+ <FieldError name="${passwordCamelCase}" className="rw-field-error" />
103
+
104
+ <div className="rw-button-group">
105
+ <Submit className="rw-button rw-button-blue">
106
+ Sign Up
107
+ </Submit>
108
+ </div>
109
+ </Form>
110
+
111
+ {/*
112
+ * OAuth signup buttons. Delete the ones for providers you
113
+ * haven't configured in `cedar setup auth dbAuth --oauth`.
114
+ * Each link is a full-page navigation to the provider's
115
+ * authorize route — it must not be turned into a fetch/XHR
116
+ * call.
117
+ */}
118
+ <div className="rw-button-group">
119
+ <a
120
+ href={getOAuthUrl('google', { flow: 'signup' })}
121
+ className="rw-button rw-button-blue"
122
+ >
123
+ Continue with Google
124
+ </a>
125
+ <a
126
+ href={getOAuthUrl('github', { flow: 'signup' })}
127
+ className="rw-button rw-button-blue"
128
+ >
129
+ Continue with GitHub
130
+ </a>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ <div className="rw-login-link">
136
+ <span>Already have an account?</span>{' '}
137
+ <Link to={routes.login()} className="rw-link">
138
+ Log in!
139
+ </Link>
140
+ </div>
141
+ </div>
142
+ </main>
143
+ </>
144
+ )
145
+ }
146
+
147
+ export default SignupPage
@@ -1,8 +1,9 @@
1
1
  import camelcase from "camelcase";
2
2
  import { Listr } from "listr2";
3
3
  import prompts from "prompts";
4
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
4
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
5
5
  import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
6
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
6
7
  import { getConfig } from "@cedarjs/project-config";
7
8
  import { writeFilesTask, transformTSToJSMap } from "../../../lib/index.js";
8
9
  import {
@@ -1,6 +1,7 @@
1
1
  import { Listr } from "listr2";
2
2
  import { terminalLink } from "termi-link";
3
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
3
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
4
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
4
5
  import { errorTelemetry } from "@cedarjs/telemetry";
5
6
  import { transformTSToJSMap, writeFilesTask } from "../../../lib/index.js";
6
7
  import { prepareForRollback } from "../../../lib/rollback.js";
@@ -2,8 +2,9 @@ import path from "node:path";
2
2
  import { pathToFileURL } from "node:url";
3
3
  import * as changeCase from "change-case";
4
4
  import { Listr } from "listr2";
5
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
6
  import { runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
7
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
7
8
  import { errorTelemetry } from "@cedarjs/telemetry";
8
9
  import {
9
10
  getPaths,
@@ -1,6 +1,7 @@
1
1
  import path from "path";
2
2
  import { Listr } from "listr2";
3
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
3
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
4
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
4
5
  import {
5
6
  getPaths,
6
7
  writeFilesTask,
@@ -2,7 +2,8 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import fg from "fast-glob";
4
4
  import { Listr } from "listr2";
5
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
6
7
  import { ensurePosixPath } from "@cedarjs/project-config";
7
8
  import { errorTelemetry } from "@cedarjs/telemetry";
8
9
  import {
@@ -8,7 +8,6 @@ const files = async ({
8
8
  fileName,
9
9
  typescript,
10
10
  tests: generateTests = true,
11
- esm = false,
12
11
  ...rest
13
12
  }) => {
14
13
  const extension = typescript ? ".ts" : ".js";
@@ -59,17 +58,15 @@ const files = async ({
59
58
  outputPath: path.join(folderName, "src", `${fileName}.test${extension}`)
60
59
  });
61
60
  outputFiles.push(testFile);
62
- if (esm) {
63
- const vitestConfigFile = await templateForFile({
64
- name,
65
- side: "packages",
66
- generator: "package",
67
- templatePath: "vitest.config.ts.template",
68
- templateVars: { folderName, ...rest },
69
- outputPath: path.join(folderName, `vitest.config${extension}`)
70
- });
71
- outputFiles.push(vitestConfigFile);
72
- }
61
+ const vitestConfigFile = await templateForFile({
62
+ name,
63
+ side: "packages",
64
+ generator: "package",
65
+ templatePath: "vitest.config.ts.template",
66
+ templateVars: { folderName, ...rest },
67
+ outputPath: path.join(folderName, `vitest.config${extension}`)
68
+ });
69
+ outputFiles.push(vitestConfigFile);
73
70
  }
74
71
  return outputFiles.reduce(async (accP, [outputPath, content]) => {
75
72
  const acc = await accP;
@@ -6,12 +6,13 @@ import { modify, applyEdits } from "jsonc-parser";
6
6
  import { Listr } from "listr2";
7
7
  import { terminalLink } from "termi-link";
8
8
  import ts from "typescript";
9
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
9
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
10
10
  import { workspacePackageSpecifier } from "@cedarjs/cli-helpers/packageManager";
11
11
  import { runScript, runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
12
12
  import { installPackages } from "@cedarjs/cli-helpers/packageManager/packages";
13
13
  import { addWorkspaceDir } from "@cedarjs/cli-helpers/packageManager/workspaces";
14
- import { getConfig, projectIsEsm } from "@cedarjs/project-config";
14
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
15
+ import { getConfig } from "@cedarjs/project-config";
15
16
  import { getPackageManager } from "@cedarjs/project-config/packageManager";
16
17
  import { errorTelemetry } from "@cedarjs/telemetry";
17
18
  import { getPaths, writeFilesTask } from "../../../lib/index.js";
@@ -342,8 +343,6 @@ const handler = async ({
342
343
  task: async (ctx) => {
343
344
  packageFiles = await files({
344
345
  ...ctx.nameVariants,
345
- // Only Vitest projects get a config generated for them
346
- esm: projectIsEsm(),
347
346
  ...rest
348
347
  });
349
348
  return writeFilesTask(packageFiles, { overwriteExisting: force });
@@ -2,7 +2,8 @@ import { execSync } from "child_process";
2
2
  import camelcase from "camelcase";
3
3
  import { Listr } from "listr2";
4
4
  import pascalcase from "pascalcase";
5
- import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
6
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
6
7
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
7
8
  import { getConfig } from "@cedarjs/project-config";
8
9
  import { errorTelemetry } from "@cedarjs/telemetry";
@@ -1,4 +1,4 @@
1
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
1
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
2
2
  const command = "realtime <name>";
3
3
  const description = "Generate a subscription or live query used with RedwoodJS Realtime";
4
4
  function builder(yargs) {
@@ -4,9 +4,8 @@ import { Listr } from "listr2";
4
4
  import pascalcase from "pascalcase";
5
5
  import pluralize from "pluralize";
6
6
  import prompts from "prompts";
7
- import { colors as c } from "@cedarjs/cli-helpers";
7
+ import { colors as c } from "@cedarjs/cli-helpers/colors";
8
8
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
9
- import { projectIsEsm } from "@cedarjs/project-config";
10
9
  import { errorTelemetry } from "@cedarjs/telemetry";
11
10
  import {
12
11
  generateTemplate,
@@ -120,16 +119,10 @@ async function handler({
120
119
  exampleFile,
121
120
  exampleSubscriptionTemplateContent
122
121
  );
123
- let blankTemplateContent = await generateTemplate(
122
+ const blankTemplateContent = await generateTemplate(
124
123
  setupScriptContent,
125
124
  templateVariables(name)
126
125
  );
127
- if (projectIsEsm()) {
128
- blankTemplateContent = blankTemplateContent.replace(
129
- "import gql from 'graphql-tag'",
130
- "import { gql } from 'graphql-tag'"
131
- );
132
- }
133
126
  return [
134
127
  writeFile(
135
128
  sdlFile,
@@ -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