@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
|
@@ -2,13 +2,14 @@ import ansis from "ansis";
|
|
|
2
2
|
import boxen from "boxen";
|
|
3
3
|
import camelcase from "camelcase";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
|
-
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";
|
|
6
8
|
import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
|
|
7
9
|
import { getConfig } from "@cedarjs/project-config";
|
|
8
10
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
9
|
-
import { pluralize } from "
|
|
10
|
-
import
|
|
11
|
-
import { transformTSToJS, writeFilesTask } from "../../../lib/index.js";
|
|
11
|
+
import { pluralize } from "@cedarjs/utils/cedarPluralize";
|
|
12
|
+
import { transformTSToJS } from "../../../lib/index.js";
|
|
12
13
|
import {
|
|
13
14
|
prepareForRollback,
|
|
14
15
|
addFunctionToRollback
|
|
@@ -18,9 +19,14 @@ import {
|
|
|
18
19
|
getEnum,
|
|
19
20
|
verifyModelName
|
|
20
21
|
} from "../../../lib/schemaHelpers.js";
|
|
21
|
-
import { relationsForModel } from "../helpers.js";
|
|
22
|
+
import { redactedModelFields, relationsForModel } from "../helpers.js";
|
|
22
23
|
import { files as serviceFiles } from "../service/serviceHandler.js";
|
|
23
24
|
import { templateForFile } from "../yargsHandlerHelpers.js";
|
|
25
|
+
import {
|
|
26
|
+
addStubHeader,
|
|
27
|
+
missingRelatedModels,
|
|
28
|
+
writeFilesWithStubsTask
|
|
29
|
+
} from "./stubFiles.js";
|
|
24
30
|
const DEFAULT_IGNORE_FIELDS_FOR_INPUT = ["createdAt", "updatedAt"];
|
|
25
31
|
const missingIdConsoleMessage = () => {
|
|
26
32
|
const line1 = ansis.bold.yellow("WARNING") + ": Cannot generate CRUD SDL without an `@id` database column.";
|
|
@@ -47,12 +53,8 @@ const addFieldGraphQLComment = (field, str) => {
|
|
|
47
53
|
const modelFieldToSDL = ({
|
|
48
54
|
field,
|
|
49
55
|
required = true,
|
|
50
|
-
types = {},
|
|
51
56
|
docs = false
|
|
52
57
|
}) => {
|
|
53
|
-
if (Object.entries(types).length) {
|
|
54
|
-
field.type = field.kind === "object" ? idType(types[field.type]) : field.type;
|
|
55
|
-
}
|
|
56
58
|
const prismaTypeToGraphqlType = {
|
|
57
59
|
Json: "JSON",
|
|
58
60
|
Decimal: "Float",
|
|
@@ -68,40 +70,45 @@ const modelFieldToSDL = ({
|
|
|
68
70
|
return fieldContent;
|
|
69
71
|
}
|
|
70
72
|
};
|
|
73
|
+
const modelRedactedFields = (model) => {
|
|
74
|
+
return redactedModelFields(model.fields.map((field) => field.name));
|
|
75
|
+
};
|
|
71
76
|
const querySDL = (model, docs = false) => {
|
|
72
|
-
|
|
77
|
+
const redactedFields = modelRedactedFields(model);
|
|
78
|
+
return model.fields.filter((field) => !redactedFields.includes(field.name)).map((field) => modelFieldToSDL({ field, docs }));
|
|
73
79
|
};
|
|
74
|
-
const inputSDL = (model, required,
|
|
75
|
-
const ignoredFields =
|
|
80
|
+
const inputSDL = (model, required, docs = false) => {
|
|
81
|
+
const ignoredFields = [
|
|
82
|
+
...DEFAULT_IGNORE_FIELDS_FOR_INPUT,
|
|
83
|
+
...modelRedactedFields(model)
|
|
84
|
+
];
|
|
85
|
+
const idField = model.fields.find((field) => field.isId);
|
|
86
|
+
if (idField?.default !== void 0) {
|
|
87
|
+
ignoredFields.push(idField.name);
|
|
88
|
+
}
|
|
76
89
|
return model.fields.filter((field) => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
ignoredFields.push(idField.name);
|
|
80
|
-
}
|
|
81
|
-
return ignoredFields.indexOf(field.name) === -1 && field.kind !== "object";
|
|
82
|
-
}).map((field) => modelFieldToSDL({ field, required, types, docs }));
|
|
90
|
+
return !ignoredFields.includes(field.name) && field.kind !== "object";
|
|
91
|
+
}).map((field) => modelFieldToSDL({ field, required, docs }));
|
|
83
92
|
};
|
|
84
|
-
|
|
93
|
+
function idInputSDL(idType2, docs) {
|
|
85
94
|
if (!Array.isArray(idType2)) {
|
|
86
95
|
return [];
|
|
87
96
|
}
|
|
88
|
-
return idType2.map(
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
return idType2.map((field) => modelFieldToSDL({ field, required: true, docs }));
|
|
98
|
+
}
|
|
99
|
+
const createInputSDL = (model, docs = false) => {
|
|
100
|
+
return inputSDL(model, true, docs);
|
|
91
101
|
};
|
|
92
|
-
const
|
|
93
|
-
return inputSDL(model,
|
|
102
|
+
const updateInputSDL = (model, docs = false) => {
|
|
103
|
+
return inputSDL(model, false, docs);
|
|
94
104
|
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
};
|
|
98
|
-
const idType = (model, crud) => {
|
|
99
|
-
if (!crud) {
|
|
105
|
+
function idType(model, crud) {
|
|
106
|
+
if (!crud || !model) {
|
|
100
107
|
return void 0;
|
|
101
108
|
}
|
|
102
109
|
if (model.primaryKey?.fields.length) {
|
|
103
110
|
const { fields: fieldNames } = model.primaryKey;
|
|
104
|
-
return fieldNames.map((name) => model.fields.find((f) => f.name === name));
|
|
111
|
+
return fieldNames.map((name) => model.fields.find((f) => f.name === name)).filter((f) => f !== void 0);
|
|
105
112
|
}
|
|
106
113
|
const idField = model.fields.find((field) => field.isId);
|
|
107
114
|
if (!idField) {
|
|
@@ -109,7 +116,7 @@ const idType = (model, crud) => {
|
|
|
109
116
|
throw new Error("Failed: Could not generate SDL");
|
|
110
117
|
}
|
|
111
118
|
return idField.type;
|
|
112
|
-
}
|
|
119
|
+
}
|
|
113
120
|
const idName = (model, crud) => {
|
|
114
121
|
if (!crud) {
|
|
115
122
|
return void 0;
|
|
@@ -122,13 +129,13 @@ const idName = (model, crud) => {
|
|
|
122
129
|
return idField.name;
|
|
123
130
|
};
|
|
124
131
|
const sdlFromSchemaModel = async (name, crud, docs = false) => {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
const schemaResult = await getSchema(name);
|
|
133
|
+
if (!schemaResult || !("fields" in schemaResult)) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`No schema definition found for \`${name}\` in schema.prisma file`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
const model = schemaResult;
|
|
132
139
|
const enums = (await Promise.all(
|
|
133
140
|
model.fields.filter((field) => field.kind === "enum").map(async (field) => {
|
|
134
141
|
const enumDef = await getEnum(field.type);
|
|
@@ -142,8 +149,8 @@ const sdlFromSchemaModel = async (name, crud, docs = false) => {
|
|
|
142
149
|
modelName,
|
|
143
150
|
modelDescription,
|
|
144
151
|
query: querySDL(model, docs).join("\n "),
|
|
145
|
-
createInput: createInputSDL(model,
|
|
146
|
-
updateInput: updateInputSDL(model,
|
|
152
|
+
createInput: createInputSDL(model, docs).join("\n "),
|
|
153
|
+
updateInput: updateInputSDL(model, docs).join("\n "),
|
|
147
154
|
idInput: idInputSDL(idTypeRes, docs).join("\n "),
|
|
148
155
|
idType: idType(model, crud),
|
|
149
156
|
idName: idName(model, crud),
|
|
@@ -181,6 +188,55 @@ const files = async ({
|
|
|
181
188
|
})
|
|
182
189
|
};
|
|
183
190
|
};
|
|
191
|
+
const stubFiles = async (models, generatedFor, { docs = false, typescript }) => {
|
|
192
|
+
const generatedFiles = {};
|
|
193
|
+
for (const stubModel of models) {
|
|
194
|
+
const stubModelFiles = await files({
|
|
195
|
+
name: stubModel,
|
|
196
|
+
crud: false,
|
|
197
|
+
docs,
|
|
198
|
+
tests: false,
|
|
199
|
+
typescript
|
|
200
|
+
});
|
|
201
|
+
for (const [stubPath, stubContent] of Object.entries(stubModelFiles)) {
|
|
202
|
+
generatedFiles[stubPath] = addStubHeader({
|
|
203
|
+
content: stubContent,
|
|
204
|
+
stubModel,
|
|
205
|
+
generatedFor
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return generatedFiles;
|
|
210
|
+
};
|
|
211
|
+
const redactedSensitiveFields = async (modelNames) => {
|
|
212
|
+
const redacted = [];
|
|
213
|
+
for (const modelName of modelNames) {
|
|
214
|
+
const model = await getSchema(modelName);
|
|
215
|
+
if (!model || !("fields" in model)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
for (const fieldName of modelRedactedFields(model)) {
|
|
219
|
+
redacted.push(`${model.name}.${fieldName}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return redacted;
|
|
223
|
+
};
|
|
224
|
+
const printRedactedFieldsNote = (redactedFields) => {
|
|
225
|
+
if (redactedFields.length === 0) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
console.log();
|
|
229
|
+
console.log(
|
|
230
|
+
c.warning(
|
|
231
|
+
`The following fields were excluded from the generated SDL because they may contain sensitive data: ${redactedFields.join(", ")}`
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
console.log(
|
|
235
|
+
c.warning(
|
|
236
|
+
"If you want to expose any of them through your GraphQL API you can add them to the SDL file manually."
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
};
|
|
184
240
|
const handler = async ({
|
|
185
241
|
model,
|
|
186
242
|
crud,
|
|
@@ -204,13 +260,21 @@ const handler = async ({
|
|
|
204
260
|
});
|
|
205
261
|
try {
|
|
206
262
|
const { name } = await verifyModelName({ name: model });
|
|
263
|
+
const missingModels = await missingRelatedModels(name);
|
|
264
|
+
const redactedFields = await redactedSensitiveFields([
|
|
265
|
+
name,
|
|
266
|
+
...missingModels
|
|
267
|
+
]);
|
|
207
268
|
const tasks = new Listr(
|
|
208
269
|
[
|
|
209
270
|
{
|
|
210
271
|
title: "Generating SDL files...",
|
|
211
272
|
task: async () => {
|
|
212
|
-
const f =
|
|
213
|
-
|
|
273
|
+
const f = {
|
|
274
|
+
...await files({ name, tests, crud, typescript, docs }),
|
|
275
|
+
...await stubFiles(missingModels, name, { typescript, docs })
|
|
276
|
+
};
|
|
277
|
+
return writeFilesWithStubsTask(f, { overwriteExisting: force });
|
|
214
278
|
}
|
|
215
279
|
},
|
|
216
280
|
{
|
|
@@ -237,13 +301,38 @@ const handler = async ({
|
|
|
237
301
|
prepareForRollback(tasks);
|
|
238
302
|
}
|
|
239
303
|
await tasks.run();
|
|
304
|
+
if (missingModels.length > 0) {
|
|
305
|
+
console.log();
|
|
306
|
+
console.log(
|
|
307
|
+
c.info(
|
|
308
|
+
`${name} has relations to models that don't have SDL files of their own yet: ${missingModels.join(", ")}`
|
|
309
|
+
)
|
|
310
|
+
);
|
|
311
|
+
console.log(
|
|
312
|
+
c.info(
|
|
313
|
+
"Read-only SDL stubs were generated for them, since GraphQL type generation fails otherwise."
|
|
314
|
+
)
|
|
315
|
+
);
|
|
316
|
+
console.log(c.info("To replace a stub with a full SDL and service, run"));
|
|
317
|
+
for (const stubModel of missingModels) {
|
|
318
|
+
console.log(
|
|
319
|
+
c.info(` ${formatCedarCommand(["generate", "sdl", stubModel])}`)
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
printRedactedFieldsNote(redactedFields);
|
|
240
324
|
} catch (e) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
process.
|
|
325
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
326
|
+
const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
|
|
327
|
+
errorTelemetry(process.argv, message);
|
|
328
|
+
console.error(c.error(message));
|
|
329
|
+
process.exit(exitCode);
|
|
244
330
|
}
|
|
245
331
|
};
|
|
246
332
|
export {
|
|
247
333
|
files,
|
|
248
|
-
handler
|
|
334
|
+
handler,
|
|
335
|
+
printRedactedFieldsNote,
|
|
336
|
+
redactedSensitiveFields,
|
|
337
|
+
stubFiles
|
|
249
338
|
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { Listr } from "listr2";
|
|
5
|
+
import { getPaths } from "@cedarjs/project-config";
|
|
6
|
+
import { writeFile } from "../../../lib/index.js";
|
|
7
|
+
import { getSchema } from "../../../lib/schemaHelpers.js";
|
|
8
|
+
const STUB_HASH_MARKER = "@cedar-generator-stub-hash";
|
|
9
|
+
const STUB_HASH_MARKER_REGEX = new RegExp(
|
|
10
|
+
`^// ${STUB_HASH_MARKER} ([0-9a-f]+)$`,
|
|
11
|
+
"m"
|
|
12
|
+
);
|
|
13
|
+
function stubHash(contents) {
|
|
14
|
+
return crypto.createHash("sha256").update(contents).digest("hex").slice(0, 16);
|
|
15
|
+
}
|
|
16
|
+
function addStubHeader({
|
|
17
|
+
content,
|
|
18
|
+
stubModel,
|
|
19
|
+
generatedFor
|
|
20
|
+
}) {
|
|
21
|
+
const body = "\n\n" + content;
|
|
22
|
+
const marker = `// ${STUB_HASH_MARKER} PLACEHOLDER`;
|
|
23
|
+
const header = [
|
|
24
|
+
`// Generated as a read-only stub by \`cedar generate sdl ${generatedFor}\`,`,
|
|
25
|
+
`// because ${generatedFor} has a relation to ${stubModel}, which had no SDL yet.`,
|
|
26
|
+
`// Run \`cedar generate sdl ${stubModel}\` to replace this stub with the real thing.`,
|
|
27
|
+
`// If you edit this file, the hash below will stop matching and you'll`,
|
|
28
|
+
`// need to pass \`--force\` to overwrite it.`,
|
|
29
|
+
marker
|
|
30
|
+
].join("\n");
|
|
31
|
+
const contentToHash = header + body;
|
|
32
|
+
const hash = stubHash(contentToHash);
|
|
33
|
+
const finalMarker = `// ${STUB_HASH_MARKER} ${hash}`;
|
|
34
|
+
return (header + body).replace(marker, finalMarker);
|
|
35
|
+
}
|
|
36
|
+
function isPristineStub(contents) {
|
|
37
|
+
const match = STUB_HASH_MARKER_REGEX.exec(contents);
|
|
38
|
+
if (!match) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const contentToHash = contents.replace(
|
|
42
|
+
match[0],
|
|
43
|
+
`// ${STUB_HASH_MARKER} PLACEHOLDER`
|
|
44
|
+
);
|
|
45
|
+
return stubHash(contentToHash) === match[1];
|
|
46
|
+
}
|
|
47
|
+
function readExistingSdlFiles() {
|
|
48
|
+
const graphqlDir = getPaths().api.graphql;
|
|
49
|
+
if (!fs.existsSync(graphqlDir)) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const contents = [];
|
|
53
|
+
const dirsToWalk = [graphqlDir];
|
|
54
|
+
while (dirsToWalk.length > 0) {
|
|
55
|
+
const dir = dirsToWalk.shift();
|
|
56
|
+
if (!dir) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
60
|
+
const entryPath = path.join(dir, entry.name);
|
|
61
|
+
if (entry.isDirectory()) {
|
|
62
|
+
dirsToWalk.push(entryPath);
|
|
63
|
+
} else if (/\.sdl\.(js|ts)$/.test(entry.name)) {
|
|
64
|
+
contents.push(fs.readFileSync(entryPath, "utf-8"));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return contents;
|
|
69
|
+
}
|
|
70
|
+
async function missingRelatedModels(modelName) {
|
|
71
|
+
const existingSdls = readExistingSdlFiles();
|
|
72
|
+
const isDefined = (typeName) => existingSdls.some(
|
|
73
|
+
(sdl) => new RegExp(`\\btype\\s+${typeName}\\b`).test(sdl)
|
|
74
|
+
);
|
|
75
|
+
const seen = /* @__PURE__ */ new Set([modelName]);
|
|
76
|
+
const missing = [];
|
|
77
|
+
const queue = [modelName];
|
|
78
|
+
while (queue.length > 0) {
|
|
79
|
+
const current = queue.shift();
|
|
80
|
+
if (!current) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
const model = await getSchema(current);
|
|
84
|
+
if (!model || !("fields" in model)) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
for (const field of model.fields) {
|
|
88
|
+
if (!field.relationName || seen.has(field.type)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
seen.add(field.type);
|
|
92
|
+
queue.push(field.type);
|
|
93
|
+
if (!isDefined(field.type)) {
|
|
94
|
+
missing.push(field.type);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return missing;
|
|
99
|
+
}
|
|
100
|
+
function writeFilesWithStubsTask(files, { overwriteExisting = false } = {}) {
|
|
101
|
+
const { base } = getPaths();
|
|
102
|
+
return new Listr(
|
|
103
|
+
Object.entries(files).map(([file, contents]) => ({
|
|
104
|
+
title: `...waiting to write file \`./${path.relative(base, file)}\`...`,
|
|
105
|
+
task: (_ctx, task) => {
|
|
106
|
+
let canOverwrite = overwriteExisting;
|
|
107
|
+
if (!canOverwrite && fs.existsSync(file)) {
|
|
108
|
+
const existingContents = fs.readFileSync(file, "utf-8");
|
|
109
|
+
if (isPristineStub(existingContents)) {
|
|
110
|
+
canOverwrite = true;
|
|
111
|
+
} else if (STUB_HASH_MARKER_REGEX.test(existingContents)) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`${file} started out as a generated stub, but has since been edited. Use \`--force\` to overwrite it.`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return writeFile(
|
|
118
|
+
file,
|
|
119
|
+
contents,
|
|
120
|
+
{ overwriteExisting: canOverwrite },
|
|
121
|
+
task
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}))
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
addStubHeader,
|
|
129
|
+
isPristineStub,
|
|
130
|
+
missingRelatedModels,
|
|
131
|
+
writeFilesWithStubsTask
|
|
132
|
+
};
|
|
@@ -30,6 +30,7 @@ export const schema = gql`
|
|
|
30
30
|
<% } %>${singularCamelName}(${idName}: ${idType}!): ${singularPascalName} @requireAuth<% } %>
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
<% if (crud) { %>
|
|
33
34
|
<% if (docs) { %>
|
|
34
35
|
"""Autogenerated input type of Input${singularPascalName}."""
|
|
35
36
|
<% } %>
|
|
@@ -51,7 +52,7 @@ export const schema = gql`
|
|
|
51
52
|
<% } %>
|
|
52
53
|
input Update${singularPascalName}Input {
|
|
53
54
|
${updateInput}
|
|
54
|
-
}
|
|
55
|
+
}
|
|
55
56
|
|
|
56
57
|
<% if (docs) { %>
|
|
57
58
|
"""About mutations"""
|
|
@@ -30,6 +30,7 @@ export const schema = gql`
|
|
|
30
30
|
<% } %>${singularCamelName}(${idName}: ${idType}!): ${singularPascalName} @requireAuth<% } %>
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
<% if (crud) { %>
|
|
33
34
|
<% if (docs) { %>
|
|
34
35
|
"""Autogenerated input type of Input${singularPascalName}."""
|
|
35
36
|
<% } %>
|
|
@@ -51,7 +52,7 @@ export const schema = gql`
|
|
|
51
52
|
<% } %>
|
|
52
53
|
input Update${singularPascalName}Input {
|
|
53
54
|
${updateInput}
|
|
54
|
-
}
|
|
55
|
+
}
|
|
55
56
|
|
|
56
57
|
<% if (docs) { %>
|
|
57
58
|
"""About mutations"""
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { terminalLink } from "termi-link";
|
|
3
|
-
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
3
|
+
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
|
|
4
4
|
const DEFAULT_LENGTH = 32;
|
|
5
5
|
const generateSecret = (length = DEFAULT_LENGTH) => {
|
|
6
|
-
return crypto.randomBytes(length).toString("base64");
|
|
6
|
+
return crypto.randomBytes(Math.trunc(length)).toString("base64");
|
|
7
7
|
};
|
|
8
8
|
const command = "secret";
|
|
9
9
|
const description = "Generates a secret key using a cryptographically-secure source of entropy";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}).option("raw", {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
10
|
+
function builder(yargs) {
|
|
11
|
+
return yargs.option("length", {
|
|
12
|
+
description: "Length of the generated secret",
|
|
13
|
+
type: "number",
|
|
14
|
+
default: DEFAULT_LENGTH
|
|
15
|
+
}).option("raw", {
|
|
16
|
+
description: "Prints just the raw secret",
|
|
17
|
+
type: "boolean",
|
|
18
|
+
default: false
|
|
19
|
+
}).epilogue(
|
|
20
|
+
`Also see the ${terminalLink(
|
|
21
|
+
"CedarJS CLI Reference",
|
|
22
|
+
"https://cedarjs.com/docs/cli-commands#generate-secret"
|
|
23
|
+
)}`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
function handler({ length, raw }) {
|
|
27
27
|
recordTelemetryAttributes({
|
|
28
28
|
command: "generate secret",
|
|
29
29
|
length,
|
|
@@ -41,7 +41,7 @@ const handler = ({ length, raw }) => {
|
|
|
41
41
|
);
|
|
42
42
|
console.info("");
|
|
43
43
|
console.info("Keep it secret, keep it safe!");
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
export {
|
|
46
46
|
DEFAULT_LENGTH,
|
|
47
47
|
builder,
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
createHandler,
|
|
6
6
|
getYargsDefaults
|
|
7
7
|
} from "../yargsCommandHelpers.js";
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const getDefaultOptions = () => {
|
|
9
|
+
return {
|
|
10
10
|
...getYargsDefaults(),
|
|
11
11
|
tests: {
|
|
12
12
|
description: "Generate test files",
|
|
@@ -18,7 +18,6 @@ const defaults = () => {
|
|
|
18
18
|
type: "boolean"
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
|
-
return defaults2;
|
|
22
21
|
};
|
|
23
22
|
const command = createCommand("service");
|
|
24
23
|
const description = createDescription("service");
|
|
@@ -36,15 +35,16 @@ const builder = (yargs) => {
|
|
|
36
35
|
"https://cedarjs.com/docs/cli-commands#generate-service"
|
|
37
36
|
)}`
|
|
38
37
|
);
|
|
39
|
-
Object.entries(
|
|
38
|
+
Object.entries(getDefaultOptions()).forEach(([option, config]) => {
|
|
40
39
|
yargs.option(option, config);
|
|
41
40
|
});
|
|
41
|
+
return yargs;
|
|
42
42
|
};
|
|
43
43
|
const handler = createHandler("service");
|
|
44
44
|
export {
|
|
45
45
|
builder,
|
|
46
46
|
command,
|
|
47
|
-
defaults,
|
|
48
47
|
description,
|
|
48
|
+
getDefaultOptions,
|
|
49
49
|
handler
|
|
50
50
|
};
|