@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.
- package/README.md +7 -10
- package/dist/cfw.js +10 -6
- package/dist/commands/build/buildHandler.js +220 -45
- package/dist/commands/build/buildPackagesTask.js +21 -20
- package/dist/commands/build.js +13 -2
- package/dist/commands/check.js +4 -6
- package/dist/commands/console.js +6 -4
- package/dist/commands/deploy/baremetal/SshExecutor.js +13 -4
- package/dist/commands/deploy/baremetal/baremetalHandler.js +116 -50
- package/dist/commands/deploy/baremetal.js +11 -4
- package/dist/commands/deploy/flightcontrolHandler.js +28 -15
- package/dist/commands/deploy/helpers/deployHandler.js +11 -6
- package/dist/commands/deploy/netlify.js +1 -1
- package/dist/commands/deploy/packing/nft.js +1 -2
- package/dist/commands/deploy/render.js +1 -1
- package/dist/commands/deploy/renderHandler.js +24 -13
- package/dist/commands/deploy/serverlessHandler.js +69 -27
- package/dist/commands/deploy/vercel.js +1 -1
- package/dist/commands/destroy/component/component.js +2 -3
- package/dist/commands/destroy/directive/directive.js +1 -3
- package/dist/commands/destroy/directive/directiveHandler.js +2 -4
- package/dist/commands/destroy/function/function.js +1 -3
- package/dist/commands/destroy/handlerHelpers.js +17 -17
- package/dist/commands/destroy/helpers.js +8 -2
- package/dist/commands/destroy/layout/layout.js +1 -2
- package/dist/commands/destroy/page/pageHandler.js +3 -3
- package/dist/commands/destroy/scaffold/scaffoldHandler.js +31 -12
- package/dist/commands/destroy/sdl/sdlHandler.js +3 -3
- package/dist/commands/dev/apiDebugFlag.js +5 -4
- package/dist/commands/dev/devHandler.js +219 -68
- package/dist/commands/dev/packageWatchCommands.js +8 -3
- package/dist/commands/dev.js +16 -6
- package/dist/commands/execHandler.js +49 -29
- package/dist/commands/experimental/live-queries/liveQueries.js +32 -0
- package/dist/commands/experimental/live-queries/liveQueriesHandler.js +448 -0
- package/dist/commands/experimental/live-queries/templates/liveQueriesListener.ts.template +153 -0
- package/dist/commands/experimental/live-queries/templates/migration.sql.template +100 -0
- package/dist/commands/experimental/setupInngest.js +2 -2
- package/dist/commands/experimental/setupInngestHandler.js +13 -12
- package/dist/commands/experimental/setupOpentelemetry.js +2 -2
- package/dist/commands/experimental/setupOpentelemetryHandler.js +14 -10
- package/dist/commands/experimental/setupReactCompiler.js +2 -2
- package/dist/commands/experimental/setupReactCompilerHandler.js +48 -33
- package/dist/commands/experimental/setupRsc.js +1 -1
- package/dist/commands/experimental/setupRscHandler.js +20 -16
- package/dist/commands/experimental/setupStreamingSsr.js +2 -2
- package/dist/commands/experimental/setupStreamingSsrHandler.js +49 -34
- package/dist/commands/experimental/templates/opentelemetry.ts.template +2 -1
- package/dist/commands/experimental/templates/rsc/Document.tsx.template +1 -1
- package/dist/commands/experimental/templates/rsc/entry.client.tsx.template +8 -8
- package/dist/commands/experimental/templates/streamingSsr/Document.tsx.template +1 -1
- package/dist/commands/experimental/templates/streamingSsr/entry.client.tsx.template +6 -6
- package/dist/commands/experimental/templates/streamingSsr/tsconfig.json.template +6 -6
- package/dist/commands/experimental/util.js +27 -25
- package/dist/commands/experimental.js +3 -2
- package/dist/commands/generate/cell/cell.js +20 -0
- package/dist/commands/generate/cell/cellHandler.js +89 -40
- package/dist/commands/generate/cell/templates/cell.tsx.template +21 -2
- package/dist/commands/generate/cell/templates/cellFragment.tsx.template +43 -0
- package/dist/commands/generate/cell/templates/cellList.tsx.template +21 -2
- package/dist/commands/generate/cell/templates/storiesFragment.tsx.template +23 -0
- package/dist/commands/generate/cell/templates/test.js.template +1 -1
- package/dist/commands/generate/cell/templates/testFragment.js.template +30 -0
- package/dist/commands/generate/component/componentHandler.js +14 -16
- package/dist/commands/generate/dataMigration/dataMigration.js +36 -18
- package/dist/commands/generate/dataMigration/templates/dataMigration.js.template +1 -1
- package/dist/commands/generate/dataMigration/templates/dataMigration.ts.template +1 -1
- package/dist/commands/generate/dbAuth/dbAuth.js +1 -0
- package/dist/commands/generate/dbAuth/dbAuthHandler.js +63 -34
- package/dist/commands/generate/dbAuth/templates/login.oauth.tsx.template +164 -0
- package/dist/commands/generate/dbAuth/templates/signup.oauth.tsx.template +147 -0
- package/dist/commands/generate/directive/directiveHandler.js +14 -16
- package/dist/commands/generate/function/function.js +1 -0
- package/dist/commands/generate/function/functionHandler.js +14 -19
- package/dist/commands/generate/helpers.js +34 -18
- package/dist/commands/generate/job/job.js +1 -0
- package/dist/commands/generate/job/jobHandler.js +20 -24
- package/dist/commands/generate/layout/layoutHandler.js +13 -16
- package/dist/commands/generate/model/model.js +1 -0
- package/dist/commands/generate/model/modelHandler.js +11 -5
- package/dist/commands/generate/ogImage/ogImage.js +1 -0
- package/dist/commands/generate/ogImage/ogImageHandler.js +18 -11
- package/dist/commands/generate/package/filesTask.js +9 -0
- package/dist/commands/generate/package/packageHandler.js +50 -61
- package/dist/commands/generate/package/templates/test.ts.template +2 -2
- package/dist/commands/generate/package/templates/vitest.config.ts.template +9 -0
- package/dist/commands/generate/page/pageHandler.js +27 -24
- package/dist/commands/generate/realtime/realtime.js +2 -2
- package/dist/commands/generate/realtime/realtimeHandler.js +51 -32
- package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +1 -1
- package/dist/commands/generate/scaffold/scaffold.js +1 -0
- package/dist/commands/generate/scaffold/scaffoldHandler.js +176 -49
- package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +1 -1
- package/dist/commands/generate/script/script.js +1 -0
- package/dist/commands/generate/script/scriptHandler.js +10 -6
- package/dist/commands/generate/script/templates/script.ts.template +9 -4
- package/dist/commands/generate/script/templates/tsconfig.json.template +16 -2
- package/dist/commands/generate/sdl/sdl.js +4 -3
- package/dist/commands/generate/sdl/sdlHandler.js +135 -46
- package/dist/commands/generate/sdl/stubFiles.js +132 -0
- package/dist/commands/generate/sdl/templates/sdl.js.template +2 -1
- package/dist/commands/generate/sdl/templates/sdl.ts.template +2 -1
- package/dist/commands/generate/secret/secret.js +20 -20
- package/dist/commands/generate/service/service.js +5 -5
- package/dist/commands/generate/service/serviceHandler.js +126 -61
- package/dist/commands/generate/service/templates/scenarios.ts.template +4 -2
- package/dist/commands/generate/service/templates/service.ts.template +22 -8
- package/dist/commands/generate/service/templates/test.ts.template +2 -2
- package/dist/commands/generate/yargsCommandHelpers.js +7 -2
- package/dist/commands/generate/yargsHandlerHelpers.js +20 -18
- package/dist/commands/generate.js +4 -4
- package/dist/commands/info.js +2 -2
- package/dist/commands/jobsHandler.js +7 -4
- package/dist/commands/lint.js +26 -69
- package/dist/commands/prerenderHandler.js +95 -58
- package/dist/commands/prismaHandler.js +51 -26
- package/dist/commands/record/init.js +2 -2
- package/dist/commands/record.js +4 -3
- package/dist/commands/serve.js +245 -31
- package/dist/commands/serveApiHandler.js +7 -6
- package/dist/commands/serveBothHandler.js +22 -13
- package/dist/commands/serveWebHandler.js +3 -2
- package/dist/commands/setup/auth/auth.js +15 -11
- package/dist/commands/setup/cache/cache.js +1 -1
- package/dist/commands/setup/cache/cacheHandler.js +15 -9
- package/dist/commands/setup/database/database.js +15 -0
- package/dist/commands/setup/database/postgres.js +19 -0
- package/dist/commands/setup/database/postgresHandler.js +196 -0
- package/dist/commands/setup/database/templates/db.ts.template +32 -0
- package/dist/commands/setup/deploy/deploy.js +4 -3
- package/dist/commands/setup/deploy/helpers/helpers.js +5 -1
- package/dist/commands/setup/deploy/helpers/index.js +132 -6
- package/dist/commands/setup/deploy/providers/baremetalHandler.js +28 -6
- package/dist/commands/setup/deploy/providers/coherence.js +1 -1
- package/dist/commands/setup/deploy/providers/coherenceHandler.js +60 -31
- package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +69 -51
- package/dist/commands/setup/deploy/providers/netlify.js +6 -0
- package/dist/commands/setup/deploy/providers/netlifyHandler.js +114 -13
- package/dist/commands/setup/deploy/providers/renderHandler.js +44 -41
- package/dist/commands/setup/deploy/providers/serverlessHandler.js +7 -5
- package/dist/commands/setup/deploy/providers/universal-deploy.js +11 -0
- package/dist/commands/setup/deploy/providers/universalDeployHandler.js +186 -0
- package/dist/commands/setup/deploy/providers/vercel.js +6 -0
- package/dist/commands/setup/deploy/providers/vercelHandler.js +115 -14
- package/dist/commands/setup/deploy/templates/baremetal.js +3 -2
- package/dist/commands/setup/deploy/templates/flightcontrol.js +60 -49
- package/dist/commands/setup/deploy/templates/netlify.js +2 -1
- package/dist/commands/setup/deploy/templates/netlifyUD.js +31 -0
- package/dist/commands/setup/deploy/templates/render.js +32 -17
- package/dist/commands/setup/docker/docker.js +2 -2
- package/dist/commands/setup/docker/dockerHandler.js +74 -39
- package/dist/commands/setup/docker/templates/Dockerfile.npm +119 -0
- package/dist/commands/setup/docker/templates/Dockerfile.pnpm +112 -0
- package/dist/commands/setup/docker/templates/{Dockerfile → Dockerfile.yarn} +4 -7
- package/dist/commands/setup/docker/templates/docker-compose.dev.yml +3 -3
- package/dist/commands/setup/docker/templates/docker-compose.prod.yml +2 -5
- package/dist/commands/setup/docker/templates/dockerignore +1 -0
- package/dist/commands/setup/generator/generator.js +1 -1
- package/dist/commands/setup/generator/generatorHandler.js +5 -4
- package/dist/commands/setup/graphql/features/fragments/appGqlConfigTransform.js +6 -3
- package/dist/commands/setup/graphql/features/fragments/fragments.js +1 -1
- package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +5 -7
- package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +1 -1
- package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +4 -3
- package/dist/commands/setup/i18n/i18n.js +1 -1
- package/dist/commands/setup/i18n/i18nHandler.js +21 -17
- package/dist/commands/setup/jobs/jobs.js +1 -1
- package/dist/commands/setup/jobs/jobsHandler.js +17 -12
- package/dist/commands/setup/mailer/mailer.js +1 -1
- package/dist/commands/setup/mailer/mailerHandler.js +13 -11
- package/dist/commands/setup/middleware/ogImage/ogImage.js +1 -1
- package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +2 -1
- package/dist/commands/setup/monitoring/sentry/sentry.js +1 -1
- package/dist/commands/setup/monitoring/sentry/sentryHandler.js +18 -12
- package/dist/commands/setup/neon/neon.js +35 -0
- package/dist/commands/setup/neon/neonHandler.js +264 -0
- package/dist/commands/setup/package/package.js +1 -1
- package/dist/commands/setup/package/packageHandler.js +18 -14
- package/dist/commands/setup/realtime/addRealtimeToGraphql.js +1 -1
- package/dist/commands/setup/realtime/realtime.js +1 -1
- package/dist/commands/setup/realtime/realtimeHandler.js +26 -37
- package/dist/commands/setup/realtime/templates/realtime.ts.template +1 -1
- package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +1 -1
- package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +1 -1
- package/dist/commands/setup/server-file/serverFile.js +1 -1
- package/dist/commands/setup/server-file/serverFileHandler.js +18 -10
- package/dist/commands/setup/tenancy/authCodemod.js +66 -0
- package/dist/commands/setup/tenancy/dbCodemod.js +64 -0
- package/dist/commands/setup/tenancy/graphqlCodemod.js +88 -0
- package/dist/commands/setup/tenancy/preflight.js +49 -0
- package/dist/commands/setup/tenancy/schemaPrisma.js +81 -0
- package/dist/commands/setup/tenancy/signupCodemod.js +153 -0
- package/dist/commands/setup/tenancy/templates/InvitePage.tsx.template +63 -0
- package/dist/commands/setup/tenancy/templates/OrgScope.tsx.template +40 -0
- package/dist/commands/setup/tenancy/templates/ensureDefaultOrganizations.dataMigration.ts.template +39 -0
- package/dist/commands/setup/tenancy/templates/organizations.scenarios.ts.template +59 -0
- package/dist/commands/setup/tenancy/templates/organizations.sdl.ts.template +89 -0
- package/dist/commands/setup/tenancy/templates/organizations.test.ts.template +389 -0
- package/dist/commands/setup/tenancy/templates/organizations.ts.template +394 -0
- package/dist/commands/setup/tenancy/templates/requireMembership.test.ts.template +35 -0
- package/dist/commands/setup/tenancy/templates/requireMembership.ts.template +25 -0
- package/dist/commands/setup/tenancy/tenancy.js +30 -0
- package/dist/commands/setup/tenancy/tenancyHandler.js +425 -0
- package/dist/commands/setup/ui/helpers/helpers.js +5 -1
- package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +16 -8
- package/dist/commands/setup/ui/libraries/mantineHandler.js +26 -16
- package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +40 -29
- package/dist/commands/setup/uploads/schemaPrisma.js +41 -0
- package/dist/commands/setup/uploads/serverFile.js +151 -0
- package/dist/commands/setup/uploads/templates/requireUploadToken.ts.template +15 -0
- package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +23 -24
- package/dist/commands/setup/uploads/templates/uploads.sdl.ts.template +79 -0
- package/dist/commands/setup/uploads/templates/uploads.ts.template +89 -0
- package/dist/commands/setup/uploads/templates/withDataUri.ts.template +14 -0
- package/dist/commands/setup/uploads/templates/withSignedUrl.ts.template +16 -0
- package/dist/commands/setup/uploads/uploads.js +49 -7
- package/dist/commands/setup/uploads/uploadsHandler.js +266 -72
- package/dist/commands/setup.js +5 -4
- package/dist/commands/studio.js +1 -1
- package/dist/commands/studioHandler.js +2 -2
- package/dist/commands/test/datasourceWarning.js +42 -0
- package/dist/commands/test/testHandler.js +104 -0
- package/dist/commands/test/viteVersionCheck.js +75 -0
- package/dist/commands/test.js +16 -19
- package/dist/commands/type-check.js +2 -1
- package/dist/commands/type-checkHandler.js +25 -18
- package/dist/commands/upgrade/preUpgradeScripts.js +11 -11
- package/dist/commands/upgrade/upgrade.js +4 -2
- package/dist/commands/upgrade/upgradeHandler.js +97 -73
- package/dist/index.js +15 -11
- package/dist/lib/background.js +22 -1
- package/dist/lib/configureStorybook.js +2 -2
- package/dist/lib/exec.js +68 -63
- package/dist/lib/exit.js +20 -5
- package/dist/lib/extendFile.js +23 -13
- package/dist/lib/generatePrismaClient.js +48 -12
- package/dist/lib/index.js +137 -106
- package/dist/lib/loadEnvFiles.js +1 -1
- package/dist/lib/locking.js +8 -4
- package/dist/lib/merge/algorithms.js +4 -1
- package/dist/lib/merge/index.js +78 -41
- package/dist/lib/merge/semanticIdentity.js +18 -6
- package/dist/lib/merge/strategy.js +86 -36
- package/dist/lib/packages.js +23 -13
- package/dist/lib/plugin.js +13 -7
- package/dist/lib/pluralHelpers.js +6 -2
- package/dist/lib/project.js +3 -1
- package/dist/lib/rollback.js +7 -7
- package/dist/lib/schemaHelpers.js +16 -19
- package/dist/lib/test.js +20 -5
- package/dist/lib/updateCheck.js +47 -18
- package/dist/middleware/checkNodeVersion.js +9 -4
- package/dist/middleware/{detectProjectRxVersion.js → detectProjectCedarVersion.js} +2 -2
- package/dist/plugin.js +18 -12
- package/dist/telemetry/exporter.js +12 -5
- package/dist/telemetry/index.js +4 -3
- package/dist/telemetry/resource.js +9 -12
- package/dist/telemetry/send.js +14 -10
- package/dist/testLib/cells.js +5 -3
- package/package.json +44 -41
- package/LICENSE +0 -21
- package/dist/commands/consoleHandler.js +0 -68
- package/dist/commands/setup/tsconfig/tsconfig.js +0 -25
- package/dist/commands/setup/tsconfig/tsconfigHandler.js +0 -59
- package/dist/commands/setup/uploads/dbCodemod.js +0 -28
- package/dist/commands/setup/uploads/templates/signedUrl.ts.template +0 -21
- package/dist/commands/setup/vite/templates/vite.config.ts.template +0 -19
- package/dist/commands/setup/vite/vite.js +0 -38
- package/dist/commands/setup/vite/viteHandler.js +0 -83
- package/dist/commands/testEsm.js +0 -36
- package/dist/commands/testHandler.js +0 -137
- package/dist/commands/testHandlerEsm.js +0 -85
- package/dist/commands/ts-to-js.js +0 -20
- package/dist/lib/cedarPluralize.js +0 -56
- package/dist/lib/colors.js +0 -18
- package/dist/testLib/getFilesWithPattern.js +0 -21
- /package/dist/{index.d.js → global.d.js} +0 -0
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import { paramCase } from "change-case";
|
|
4
3
|
import { Listr } from "listr2";
|
|
5
4
|
import { terminalLink } from "termi-link";
|
|
6
|
-
import {
|
|
5
|
+
import { colors as c } from "@cedarjs/cli-helpers/colors";
|
|
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
|
-
import
|
|
9
|
-
|
|
9
|
+
import {
|
|
10
|
+
generateTemplate,
|
|
11
|
+
getPaths,
|
|
12
|
+
writeFilesTask
|
|
13
|
+
} from "../../../lib/index.js";
|
|
10
14
|
import { prepareForRollback } from "../../../lib/rollback.js";
|
|
11
15
|
import { validateName } from "../helpers.js";
|
|
12
|
-
|
|
13
|
-
const
|
|
16
|
+
function getPostRunInstructions() {
|
|
17
|
+
const text = c.warning("After writing your migration, you can run it with:");
|
|
18
|
+
const command2 = formatCedarCommand(["dataMigrate", "up"]);
|
|
19
|
+
return `Next steps...
|
|
14
20
|
|
|
15
|
-
${
|
|
16
|
-
"After writing your migration, you can run it with:"
|
|
17
|
-
)}
|
|
21
|
+
${text}
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
${command2}
|
|
20
24
|
`;
|
|
25
|
+
}
|
|
21
26
|
const TEMPLATE_PATHS = {
|
|
22
27
|
js: path.resolve(
|
|
23
28
|
import.meta.dirname,
|
|
@@ -40,30 +45,42 @@ const files = async ({ name, typescript }) => {
|
|
|
40
45
|
getPaths().api.prismaConfig
|
|
41
46
|
);
|
|
42
47
|
const outputPath = path.join(dataMigrationsPath, outputFilename);
|
|
48
|
+
const prismaImportSource = "src/lib/db";
|
|
43
49
|
return {
|
|
44
|
-
[outputPath]:
|
|
50
|
+
[outputPath]: await generateTemplate(TEMPLATE_PATHS[extension], {
|
|
51
|
+
name,
|
|
52
|
+
prismaImportSource
|
|
53
|
+
})
|
|
45
54
|
};
|
|
46
55
|
};
|
|
47
56
|
const command = "data-migration <name>";
|
|
48
57
|
const aliases = ["dataMigration", "dm"];
|
|
49
58
|
const description = "Generate a data migration";
|
|
50
59
|
const builder = (yargs) => {
|
|
51
|
-
yargs.positional("name", {
|
|
60
|
+
return yargs.positional("name", {
|
|
52
61
|
description: "A descriptor of what this data migration does",
|
|
53
|
-
type: "string"
|
|
62
|
+
type: "string",
|
|
63
|
+
demandOption: true
|
|
54
64
|
}).option("rollback", {
|
|
55
65
|
description: "Revert all generator actions if an error occurs",
|
|
56
66
|
type: "boolean",
|
|
57
67
|
default: true
|
|
68
|
+
}).option("force", {
|
|
69
|
+
alias: "f",
|
|
70
|
+
default: false,
|
|
71
|
+
description: "Overwrite existing files",
|
|
72
|
+
type: "boolean"
|
|
73
|
+
}).option("typescript", {
|
|
74
|
+
alias: "ts",
|
|
75
|
+
default: false,
|
|
76
|
+
description: "Generate TypeScript files",
|
|
77
|
+
type: "boolean"
|
|
58
78
|
}).epilogue(
|
|
59
79
|
`Also see the ${terminalLink(
|
|
60
80
|
"CedarJS CLI Reference",
|
|
61
81
|
"https://cedarjs.com/docs/cli-commands#generate-datamigration"
|
|
62
82
|
)}`
|
|
63
83
|
);
|
|
64
|
-
Object.entries(getYargsDefaults()).forEach(([option, config]) => {
|
|
65
|
-
yargs.option(option, config);
|
|
66
|
-
});
|
|
67
84
|
};
|
|
68
85
|
const handler = async (args) => {
|
|
69
86
|
recordTelemetryAttributes({
|
|
@@ -83,7 +100,7 @@ const handler = async (args) => {
|
|
|
83
100
|
{
|
|
84
101
|
title: "Next steps...",
|
|
85
102
|
task: (_ctx, task) => {
|
|
86
|
-
task.title =
|
|
103
|
+
task.title = getPostRunInstructions();
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
106
|
].filter(Boolean),
|
|
@@ -95,7 +112,7 @@ const handler = async (args) => {
|
|
|
95
112
|
}
|
|
96
113
|
await tasks.run();
|
|
97
114
|
} catch (e) {
|
|
98
|
-
console.log(c.error(e.message));
|
|
115
|
+
console.log(c.error(e instanceof Error ? e.message : String(e)));
|
|
99
116
|
process.exit(1);
|
|
100
117
|
}
|
|
101
118
|
};
|
|
@@ -105,5 +122,6 @@ export {
|
|
|
105
122
|
command,
|
|
106
123
|
description,
|
|
107
124
|
files,
|
|
125
|
+
getPostRunInstructions,
|
|
108
126
|
handler
|
|
109
127
|
};
|
|
@@ -2,11 +2,12 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
4
4
|
import { camelCase } from "camel-case";
|
|
5
|
-
import execa from "execa";
|
|
6
5
|
import { Listr } from "listr2";
|
|
7
6
|
import { titleCase } from "title-case";
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
7
|
+
import { colors as c } from "@cedarjs/cli-helpers/colors";
|
|
8
|
+
import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
|
|
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,
|
|
@@ -37,7 +38,11 @@ function getPostInstallMessage(isDbAuthSetup2) {
|
|
|
37
38
|
" logged in. Also take a look in the onSubmit() functions in ForgotPasswordPage",
|
|
38
39
|
" and ResetPasswordPage to change where the user redirects to after submitting",
|
|
39
40
|
" those forms.\n",
|
|
40
|
-
!isDbAuthSetup2 &&
|
|
41
|
+
!isDbAuthSetup2 && ` Oh, and if you haven't already, add the necessary dbAuth functions and
|
|
42
|
+
app setup by running:
|
|
43
|
+
|
|
44
|
+
${formatCedarCommand(["setup", "auth", "dbAuth"])}
|
|
45
|
+
`,
|
|
41
46
|
" Happy authenticating!"
|
|
42
47
|
].filter(Boolean).join("\n");
|
|
43
48
|
}
|
|
@@ -56,24 +61,29 @@ function getPostInstallWebauthnMessage(isDbAuthSetup2) {
|
|
|
56
61
|
" logged in. Also take a look in the onSubmit() functions in ForgotPasswordPage",
|
|
57
62
|
" and ResetPasswordPage to change where the user redirects to after submitting",
|
|
58
63
|
" those forms.\n",
|
|
59
|
-
!isDbAuthSetup2 &&
|
|
64
|
+
!isDbAuthSetup2 && ` Oh, and if you haven't already, add the necessary dbAuth functions and
|
|
65
|
+
app setup by running:
|
|
66
|
+
|
|
67
|
+
${formatCedarCommand(["setup", "auth", "dbAuth"])}
|
|
68
|
+
`,
|
|
60
69
|
" Happy authenticating!"
|
|
61
70
|
].filter(Boolean).join("\n");
|
|
62
71
|
}
|
|
63
72
|
const files = async ({
|
|
64
|
-
_tests,
|
|
65
73
|
typescript,
|
|
66
74
|
skipForgot,
|
|
67
75
|
skipLogin,
|
|
68
76
|
skipReset,
|
|
69
77
|
skipSignup,
|
|
70
78
|
webauthn,
|
|
79
|
+
oauth,
|
|
71
80
|
usernameLabel,
|
|
72
81
|
passwordLabel
|
|
73
82
|
}) => {
|
|
74
|
-
const
|
|
83
|
+
const filesList = [];
|
|
75
84
|
usernameLabel = usernameLabel || "username";
|
|
76
85
|
passwordLabel = passwordLabel || "password";
|
|
86
|
+
const oauthEnabled = oauth ?? isOAuthEnabled();
|
|
77
87
|
const templateVars = {
|
|
78
88
|
usernameLowerCase: usernameLabel.toLowerCase(),
|
|
79
89
|
usernameCamelCase: camelCase(usernameLabel),
|
|
@@ -83,7 +93,7 @@ const files = async ({
|
|
|
83
93
|
passwordTitleCase: titleCase(passwordLabel)
|
|
84
94
|
};
|
|
85
95
|
if (!skipForgot) {
|
|
86
|
-
|
|
96
|
+
filesList.push(
|
|
87
97
|
await templateForComponentFile({
|
|
88
98
|
name: "ForgotPassword",
|
|
89
99
|
suffix: "Page",
|
|
@@ -96,20 +106,20 @@ const files = async ({
|
|
|
96
106
|
);
|
|
97
107
|
}
|
|
98
108
|
if (!skipLogin) {
|
|
99
|
-
|
|
109
|
+
filesList.push(
|
|
100
110
|
await templateForComponentFile({
|
|
101
111
|
name: "Login",
|
|
102
112
|
suffix: "Page",
|
|
103
113
|
extension: typescript ? ".tsx" : ".jsx",
|
|
104
114
|
webPathSection: "pages",
|
|
105
115
|
generator: "dbAuth",
|
|
106
|
-
templatePath: webauthn
|
|
116
|
+
templatePath: loginTemplatePath(webauthn, oauthEnabled),
|
|
107
117
|
templateVars
|
|
108
118
|
})
|
|
109
119
|
);
|
|
110
120
|
}
|
|
111
121
|
if (!skipReset) {
|
|
112
|
-
|
|
122
|
+
filesList.push(
|
|
113
123
|
await templateForComponentFile({
|
|
114
124
|
name: "ResetPassword",
|
|
115
125
|
suffix: "Page",
|
|
@@ -122,19 +132,19 @@ const files = async ({
|
|
|
122
132
|
);
|
|
123
133
|
}
|
|
124
134
|
if (!skipSignup) {
|
|
125
|
-
|
|
135
|
+
filesList.push(
|
|
126
136
|
await templateForComponentFile({
|
|
127
137
|
name: "Signup",
|
|
128
138
|
suffix: "Page",
|
|
129
139
|
extension: typescript ? ".tsx" : ".jsx",
|
|
130
140
|
webPathSection: "pages",
|
|
131
141
|
generator: "dbAuth",
|
|
132
|
-
templatePath: "signup.tsx.template",
|
|
142
|
+
templatePath: oauthEnabled ? "signup.oauth.tsx.template" : "signup.tsx.template",
|
|
133
143
|
templateVars
|
|
134
144
|
})
|
|
135
145
|
);
|
|
136
146
|
}
|
|
137
|
-
if (
|
|
147
|
+
if (filesList.length === 0) {
|
|
138
148
|
console.info(c.error("\nNo files to generate.\n"));
|
|
139
149
|
process.exit(0);
|
|
140
150
|
}
|
|
@@ -147,25 +157,27 @@ const files = async ({
|
|
|
147
157
|
),
|
|
148
158
|
{ name: "scaffold" }
|
|
149
159
|
);
|
|
150
|
-
|
|
160
|
+
filesList.push([scaffoldOutputPath, scaffoldTemplate]);
|
|
151
161
|
}
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
return filesList.reduce(
|
|
163
|
+
async (accP, [outputPath, content]) => {
|
|
164
|
+
const acc = await accP;
|
|
165
|
+
let template = content;
|
|
166
|
+
if (outputPath.match(/\.[jt]sx?/) && !typescript) {
|
|
167
|
+
template = await transformTSToJS(outputPath, content);
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
[outputPath]: template,
|
|
171
|
+
...acc
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
Promise.resolve({})
|
|
175
|
+
);
|
|
163
176
|
};
|
|
164
177
|
const tasks = ({
|
|
165
178
|
enquirer,
|
|
166
179
|
listr2,
|
|
167
180
|
force,
|
|
168
|
-
tests,
|
|
169
181
|
typescript,
|
|
170
182
|
skipForgot,
|
|
171
183
|
skipLogin,
|
|
@@ -276,7 +288,6 @@ const tasks = ({
|
|
|
276
288
|
title: "Creating pages...",
|
|
277
289
|
task: async () => {
|
|
278
290
|
const filesObj = await files({
|
|
279
|
-
tests,
|
|
280
291
|
typescript,
|
|
281
292
|
skipForgot,
|
|
282
293
|
skipLogin,
|
|
@@ -304,7 +315,7 @@ const tasks = ({
|
|
|
304
315
|
{
|
|
305
316
|
title: "Generate types...",
|
|
306
317
|
task: () => {
|
|
307
|
-
|
|
318
|
+
runBinSync("cedar", ["g", "types"]);
|
|
308
319
|
}
|
|
309
320
|
},
|
|
310
321
|
{
|
|
@@ -314,7 +325,7 @@ const tasks = ({
|
|
|
314
325
|
}
|
|
315
326
|
],
|
|
316
327
|
{
|
|
317
|
-
silentRendererCondition: () => listr2?.silentRendererCondition,
|
|
328
|
+
silentRendererCondition: () => listr2?.silentRendererCondition ?? false,
|
|
318
329
|
rendererOptions: { collapseSubtasks: false },
|
|
319
330
|
ctx: { enquirer },
|
|
320
331
|
exitOnError: true
|
|
@@ -328,7 +339,7 @@ const handler = async (yargs) => {
|
|
|
328
339
|
skipLogin: yargs.skipLogin,
|
|
329
340
|
skipReset: yargs.skipReset,
|
|
330
341
|
skipSignup: yargs.skipSignup,
|
|
331
|
-
webauthn: yargs.webauthn,
|
|
342
|
+
webauthn: yargs.webauthn ?? void 0,
|
|
332
343
|
force: yargs.force,
|
|
333
344
|
rollback: yargs.rollback
|
|
334
345
|
});
|
|
@@ -340,10 +351,11 @@ const handler = async (yargs) => {
|
|
|
340
351
|
await t.run();
|
|
341
352
|
console.log("");
|
|
342
353
|
console.log(
|
|
343
|
-
yargs.webauthn || t.ctx
|
|
354
|
+
yargs.webauthn || t.ctx?.webauthn ? getPostInstallWebauthnMessage(isDbAuthSetup()) : getPostInstallMessage(isDbAuthSetup())
|
|
344
355
|
);
|
|
345
356
|
} catch (e) {
|
|
346
|
-
|
|
357
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
358
|
+
console.log(c.error(msg));
|
|
347
359
|
}
|
|
348
360
|
};
|
|
349
361
|
function isDbAuthSetup() {
|
|
@@ -357,7 +369,7 @@ function isDbAuthSetup() {
|
|
|
357
369
|
"auth." + webAuthExtension
|
|
358
370
|
);
|
|
359
371
|
return /^import (.*) from ['"]@cedarjs\/auth-dbauth-web['"]/m.test(
|
|
360
|
-
fs.readFileSync(webAuthPath)
|
|
372
|
+
fs.readFileSync(webAuthPath, "utf-8")
|
|
361
373
|
);
|
|
362
374
|
}
|
|
363
375
|
return false;
|
|
@@ -369,6 +381,23 @@ function isWebAuthnEnabled() {
|
|
|
369
381
|
);
|
|
370
382
|
return webPackageJson.includes('"@simplewebauthn/browser": ');
|
|
371
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
|
+
}
|
|
372
401
|
export {
|
|
373
402
|
files,
|
|
374
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'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
|