@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
|
@@ -4,9 +4,15 @@ import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
|
4
4
|
import execa from "execa";
|
|
5
5
|
import { Listr } from "listr2";
|
|
6
6
|
import { terminalLink } from "termi-link";
|
|
7
|
-
import {
|
|
7
|
+
import { colors as c } from "@cedarjs/cli-helpers/colors";
|
|
8
|
+
import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
|
|
9
|
+
import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
|
|
10
|
+
import {
|
|
11
|
+
addRootPackages,
|
|
12
|
+
addWorkspacePackages
|
|
13
|
+
} from "@cedarjs/cli-helpers/packageManager/packages";
|
|
14
|
+
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
|
|
8
15
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
9
|
-
import c from "../../../../lib/colors.js";
|
|
10
16
|
import { getPaths, usingVSCode } from "../../../../lib/index.js";
|
|
11
17
|
const tailwindDirectives = [
|
|
12
18
|
"@tailwind base;",
|
|
@@ -20,7 +26,7 @@ const tailwindImportsAndNotes = [
|
|
|
20
26
|
"/**",
|
|
21
27
|
" * START --- SETUP TAILWINDCSS EDIT",
|
|
22
28
|
" *",
|
|
23
|
-
|
|
29
|
+
` * \`${formatCedarCommand(["setup", "ui", "tailwindcss"])}\` placed these directives here`,
|
|
24
30
|
" * to inject Tailwind's styles into your CSS.",
|
|
25
31
|
" * For more information, see: https://tailwindcss.com/docs/installation",
|
|
26
32
|
" */",
|
|
@@ -69,17 +75,19 @@ async function recommendExtensionsToInstall() {
|
|
|
69
75
|
});
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
|
-
const handler = async ({
|
|
78
|
+
const handler = async ({
|
|
79
|
+
force,
|
|
80
|
+
install
|
|
81
|
+
}) => {
|
|
73
82
|
recordTelemetryAttributes({
|
|
74
83
|
command: "setup ui tailwindcss",
|
|
75
84
|
force,
|
|
76
85
|
install
|
|
77
86
|
});
|
|
78
87
|
const rwPaths = getPaths();
|
|
79
|
-
const projectPackages = ["prettier-plugin-tailwindcss@^0.
|
|
88
|
+
const projectPackages = ["prettier-plugin-tailwindcss@^0.8.0"];
|
|
80
89
|
const webWorkspacePackages = [
|
|
81
90
|
"postcss",
|
|
82
|
-
"postcss-loader",
|
|
83
91
|
"tailwindcss@^3.4.17",
|
|
84
92
|
"autoprefixer"
|
|
85
93
|
];
|
|
@@ -94,8 +102,9 @@ const handler = async ({ force, install }) => {
|
|
|
94
102
|
{
|
|
95
103
|
title: `Install ${projectPackages.join(", ")}`,
|
|
96
104
|
task: async () => {
|
|
97
|
-
await
|
|
98
|
-
cwd: rwPaths.base
|
|
105
|
+
await addRootPackages(projectPackages, {
|
|
106
|
+
cwd: rwPaths.base,
|
|
107
|
+
dev: true
|
|
99
108
|
});
|
|
100
109
|
}
|
|
101
110
|
}
|
|
@@ -113,19 +122,16 @@ const handler = async ({ force, install }) => {
|
|
|
113
122
|
{
|
|
114
123
|
title: `Install ${webWorkspacePackages.join(", ")}`,
|
|
115
124
|
task: async () => {
|
|
116
|
-
await
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
env
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
);
|
|
125
|
+
await addWorkspacePackages("web", webWorkspacePackages, {
|
|
126
|
+
cwd: rwPaths.base,
|
|
127
|
+
env: {
|
|
128
|
+
// For some reason yarn started installing deprecated
|
|
129
|
+
// typescript types when installing tailwind. This
|
|
130
|
+
// prevents it from happening. (yarn-only env var.)
|
|
131
|
+
YARN_TS_ENABLE_AUTO_TYPES: "false"
|
|
132
|
+
},
|
|
133
|
+
dev: true
|
|
134
|
+
});
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
],
|
|
@@ -170,7 +176,7 @@ const handler = async ({ force, install }) => {
|
|
|
170
176
|
);
|
|
171
177
|
}
|
|
172
178
|
}
|
|
173
|
-
await
|
|
179
|
+
await runBin("tailwindcss", ["init", tailwindConfigPath], {
|
|
174
180
|
cwd: rwPaths.web.base
|
|
175
181
|
});
|
|
176
182
|
const tailwindConfig = fs.readFileSync(tailwindConfigPath, "utf-8");
|
|
@@ -235,7 +241,7 @@ const handler = async ({ force, install }) => {
|
|
|
235
241
|
rwPaths.base,
|
|
236
242
|
".vscode/extensions.json"
|
|
237
243
|
);
|
|
238
|
-
let originalExtensionsJson = {
|
|
244
|
+
let originalExtensionsJson = {};
|
|
239
245
|
if (fs.existsSync(VS_CODE_EXTENSIONS_PATH)) {
|
|
240
246
|
const originalExtensionsFile = fs.readFileSync(
|
|
241
247
|
VS_CODE_EXTENSIONS_PATH,
|
|
@@ -246,7 +252,7 @@ const handler = async ({ force, install }) => {
|
|
|
246
252
|
const newExtensionsJson = {
|
|
247
253
|
...originalExtensionsJson,
|
|
248
254
|
recommendations: [
|
|
249
|
-
...originalExtensionsJson.recommendations,
|
|
255
|
+
...originalExtensionsJson.recommendations ?? [],
|
|
250
256
|
...recommendedVSCodeExtensions
|
|
251
257
|
]
|
|
252
258
|
};
|
|
@@ -281,7 +287,10 @@ const handler = async ({ force, install }) => {
|
|
|
281
287
|
const originalSettingsJson = JSON.parse(
|
|
282
288
|
originalSettingsFile || "{}"
|
|
283
289
|
);
|
|
284
|
-
const
|
|
290
|
+
const existingAttributes = originalSettingsJson["tailwindCSS.classAttributes"];
|
|
291
|
+
const originalTwClassAttributesJson = Array.isArray(
|
|
292
|
+
existingAttributes
|
|
293
|
+
) ? existingAttributes : [];
|
|
285
294
|
const mergedClassAttributes = Array.from(
|
|
286
295
|
/* @__PURE__ */ new Set([...classAttributes, ...originalTwClassAttributesJson])
|
|
287
296
|
);
|
|
@@ -343,7 +352,7 @@ const handler = async ({ force, install }) => {
|
|
|
343
352
|
const pluginsMatch = newPrettierConfig.match(
|
|
344
353
|
/plugins: \[[\sa-z\(\)'\-,]*]/
|
|
345
354
|
);
|
|
346
|
-
const matched = pluginsMatch
|
|
355
|
+
const matched = pluginsMatch != null ? pluginsMatch[0] : void 0;
|
|
347
356
|
if (matched && (matched.includes("'prettier-plugin-tailwindcss'") || matched.includes('"prettier-plugin-tailwindcss"'))) {
|
|
348
357
|
task.skip(
|
|
349
358
|
"tailwindcss-plugin-prettier already required in plugins"
|
|
@@ -371,9 +380,11 @@ const handler = async ({ force, install }) => {
|
|
|
371
380
|
await tasks.run();
|
|
372
381
|
await recommendExtensionsToInstall();
|
|
373
382
|
} catch (e) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
process.
|
|
383
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
384
|
+
const exitCode = e instanceof Error && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
|
|
385
|
+
errorTelemetry(process.argv, msg);
|
|
386
|
+
console.error(c.error(msg));
|
|
387
|
+
process.exit(exitCode);
|
|
377
388
|
}
|
|
378
389
|
};
|
|
379
390
|
export {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const UPLOAD_MODEL = `model Upload {
|
|
2
|
+
id String @id @default(cuid())
|
|
3
|
+
/// Name of the storage target, as configured in api/src/lib/uploads
|
|
4
|
+
target String
|
|
5
|
+
/// "pending" | "completed" | "failed"
|
|
6
|
+
status String @default("pending")
|
|
7
|
+
filename String
|
|
8
|
+
mimeType String
|
|
9
|
+
/// Bytes. BigInt because Int caps at 2 GB.
|
|
10
|
+
size BigInt
|
|
11
|
+
/// Provider-specific reference: S3 object key, filename on disk, or null
|
|
12
|
+
/// for files stored inline
|
|
13
|
+
storageKey String?
|
|
14
|
+
/// Inline bytes, only for DB targets
|
|
15
|
+
data Bytes?
|
|
16
|
+
/// The user the file belongs to, when it belongs to one
|
|
17
|
+
userId String?
|
|
18
|
+
/// Id of the upload token that created this row
|
|
19
|
+
tokenId String?
|
|
20
|
+
/// The organization the file belongs to, in multi-tenant apps
|
|
21
|
+
organizationId String?
|
|
22
|
+
createdAt DateTime @default(now())
|
|
23
|
+
updatedAt DateTime @updatedAt
|
|
24
|
+
}`;
|
|
25
|
+
function hasModel(schema, modelName) {
|
|
26
|
+
return new RegExp(`\\bmodel\\s+${modelName}\\s*\\{`).test(schema);
|
|
27
|
+
}
|
|
28
|
+
function addUploadModel(schema) {
|
|
29
|
+
if (hasModel(schema, "Upload")) {
|
|
30
|
+
return schema;
|
|
31
|
+
}
|
|
32
|
+
return `${schema.trimEnd()}
|
|
33
|
+
|
|
34
|
+
${UPLOAD_MODEL}
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
UPLOAD_MODEL,
|
|
39
|
+
addUploadModel,
|
|
40
|
+
hasModel
|
|
41
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const START_LINE = /^([ \t]*)await server\.start\(\)/m;
|
|
2
|
+
const FACTORY_IMPORT = /import\s*\{[^}]*\bcreateAuthDecoder\b[^}]*\}\s*from\s*['"](@cedarjs\/auth-[a-z0-9-]+-api)['"]/;
|
|
3
|
+
const DECODER_IMPORT = /import\s*\{[^}]*\bauthDecoder\b[^}]*\}\s*from\s*['"](@cedarjs\/auth-[a-z0-9-]+-api)['"]/;
|
|
4
|
+
function detectServerAuth(graphqlSource) {
|
|
5
|
+
const factory = FACTORY_IMPORT.exec(graphqlSource);
|
|
6
|
+
if (factory) {
|
|
7
|
+
return { decoderPackage: factory[1], usesFactory: true };
|
|
8
|
+
}
|
|
9
|
+
const decoder = DECODER_IMPORT.exec(graphqlSource);
|
|
10
|
+
if (decoder) {
|
|
11
|
+
return { decoderPackage: decoder[1], usesFactory: false };
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function importedBindings(source) {
|
|
16
|
+
const names = /* @__PURE__ */ new Set();
|
|
17
|
+
const statements = source.matchAll(
|
|
18
|
+
/^import\s+(type\s+)?([^;]*?)\s+from\s+['"][^'"]+['"]/gm
|
|
19
|
+
);
|
|
20
|
+
for (const [, typeOnly, clause] of statements) {
|
|
21
|
+
if (typeOnly) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const braces = /\{([^}]*)\}/.exec(clause);
|
|
25
|
+
const defaultOrNamespace = clause.replace(/\{[^}]*\}/, "");
|
|
26
|
+
for (const part of defaultOrNamespace.split(",")) {
|
|
27
|
+
const local = part.replace(/^\s*\*\s+as\s+/, "").trim();
|
|
28
|
+
if (local) {
|
|
29
|
+
names.add(local);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
for (const specifier of braces?.[1].split(",") ?? []) {
|
|
33
|
+
const trimmed = specifier.trim();
|
|
34
|
+
if (!trimmed || trimmed.startsWith("type ")) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const alias = / as (\w+)$/.exec(trimmed);
|
|
38
|
+
names.add(alias ? alias[1] : trimmed);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return names;
|
|
42
|
+
}
|
|
43
|
+
function hasBinding(source, name) {
|
|
44
|
+
const declared = new RegExp(
|
|
45
|
+
`^(?:export\\s+)?(?:const|let|var|function)\\s+${name}\\b`,
|
|
46
|
+
"m"
|
|
47
|
+
);
|
|
48
|
+
return importedBindings(source).has(name) || declared.test(source);
|
|
49
|
+
}
|
|
50
|
+
function uploadsServerImports(source, auth) {
|
|
51
|
+
const packageSpecs = [];
|
|
52
|
+
const srcSpecs = [];
|
|
53
|
+
if (auth) {
|
|
54
|
+
if (auth.usesFactory) {
|
|
55
|
+
if (!hasBinding(source, "authDecoder")) {
|
|
56
|
+
packageSpecs.push({
|
|
57
|
+
names: ["createAuthDecoder"],
|
|
58
|
+
from: auth.decoderPackage
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
packageSpecs.push({ names: ["authDecoder"], from: auth.decoderPackage });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
packageSpecs.push({
|
|
66
|
+
names: auth ? ["cedarUploadsPlugin", "createUploadAuthenticator"] : ["cedarUploadsPlugin"],
|
|
67
|
+
from: "@cedarjs/uploads"
|
|
68
|
+
});
|
|
69
|
+
if (auth) {
|
|
70
|
+
const authNames = ["getCurrentUser"];
|
|
71
|
+
if (auth.usesFactory && !hasBinding(source, "authDecoder")) {
|
|
72
|
+
authNames.unshift("cookieName");
|
|
73
|
+
}
|
|
74
|
+
srcSpecs.push({ names: authNames, from: "src/lib/auth" });
|
|
75
|
+
}
|
|
76
|
+
srcSpecs.push({ names: ["db"], from: "src/lib/db" });
|
|
77
|
+
srcSpecs.push({ names: ["targets"], from: "src/lib/uploads" });
|
|
78
|
+
const render = (specs) => specs.map((spec) => ({
|
|
79
|
+
...spec,
|
|
80
|
+
names: spec.names.filter((name) => !hasBinding(source, name))
|
|
81
|
+
})).filter((spec) => spec.names.length > 0).map((spec) => `import { ${spec.names.join(", ")} } from '${spec.from}'`);
|
|
82
|
+
const packageLines = render(packageSpecs);
|
|
83
|
+
const srcLines = render(srcSpecs);
|
|
84
|
+
if (packageLines.length > 0 && srcLines.length > 0) {
|
|
85
|
+
return [...packageLines, "", ...srcLines];
|
|
86
|
+
}
|
|
87
|
+
return [...packageLines, ...srcLines];
|
|
88
|
+
}
|
|
89
|
+
function uploadsServerRegistration(source, auth) {
|
|
90
|
+
if (!auth) {
|
|
91
|
+
return ` await server.register(cedarUploadsPlugin, {
|
|
92
|
+
tokenSecret: process.env.UPLOAD_TOKEN_SECRET,
|
|
93
|
+
targets,
|
|
94
|
+
db,
|
|
95
|
+
// Once the app has auth, bind upload tokens to the logged-in user:
|
|
96
|
+
//
|
|
97
|
+
// authenticate: createUploadAuthenticator({ authDecoder, getCurrentUser }),
|
|
98
|
+
})
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
const decoder = auth.usesFactory && !hasBinding(source, "authDecoder") ? " const authDecoder = createAuthDecoder(cookieName)\n\n" : "";
|
|
102
|
+
return `${decoder} await server.register(cedarUploadsPlugin, {
|
|
103
|
+
tokenSecret: process.env.UPLOAD_TOKEN_SECRET,
|
|
104
|
+
targets,
|
|
105
|
+
db,
|
|
106
|
+
// Binds upload tokens to the logged-in user through the same auth
|
|
107
|
+
// pipeline the GraphQL server uses
|
|
108
|
+
authenticate: createUploadAuthenticator({ authDecoder, getCurrentUser }),
|
|
109
|
+
})
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
function hasUploadsPlugin(source) {
|
|
113
|
+
return /^[ \t]*(?:(?:await|void)\s+|(?:const|let|var)\s+\w+\s*=\s*)?[\w.]+\.register\(\s*cedarUploadsPlugin\b/m.test(
|
|
114
|
+
source
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
function addUploadsPlugin(source, { auth = null } = {}) {
|
|
118
|
+
if (hasUploadsPlugin(source)) {
|
|
119
|
+
return source;
|
|
120
|
+
}
|
|
121
|
+
const start = START_LINE.exec(source);
|
|
122
|
+
if (!start) {
|
|
123
|
+
throw new Error("CEDAR_UPLOADS_ERR_NO_START");
|
|
124
|
+
}
|
|
125
|
+
const lines = source.split("\n");
|
|
126
|
+
let lastImport = -1;
|
|
127
|
+
for (const [index, line] of lines.entries()) {
|
|
128
|
+
if (/^import\s/.test(line)) {
|
|
129
|
+
lastImport = index;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const withImports = [
|
|
133
|
+
...lines.slice(0, lastImport + 1),
|
|
134
|
+
...uploadsServerImports(source, auth),
|
|
135
|
+
...lines.slice(lastImport + 1)
|
|
136
|
+
].join("\n");
|
|
137
|
+
return withImports.replace(
|
|
138
|
+
START_LINE,
|
|
139
|
+
(line) => `${uploadsServerRegistration(source, auth)}
|
|
140
|
+
${line}`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
addUploadsPlugin,
|
|
145
|
+
detectServerAuth,
|
|
146
|
+
hasBinding,
|
|
147
|
+
hasUploadsPlugin,
|
|
148
|
+
importedBindings,
|
|
149
|
+
uploadsServerImports,
|
|
150
|
+
uploadsServerRegistration
|
|
151
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRequireUploadTokenDirective } from '@cedarjs/uploads'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Requires a valid upload token in the x-upload-token request header and
|
|
5
|
+
* makes its claims available to the resolver through
|
|
6
|
+
* `getUploadTokenPayload(context)`. The token must have been issued to the
|
|
7
|
+
* requesting user.
|
|
8
|
+
*/
|
|
9
|
+
const requireUploadToken = createRequireUploadTokenDirective({
|
|
10
|
+
secret: process.env.UPLOAD_TOKEN_SECRET ?? '',
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export const schema = requireUploadToken.schema
|
|
14
|
+
|
|
15
|
+
export default requireUploadToken
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
__PATH_IMPORT____S3_IMPORTS__import {
|
|
2
|
+
__FS_IMPORT__
|
|
3
|
+
__DB_IMPORT__
|
|
4
|
+
__DB_MAX_IMPORT__
|
|
5
|
+
defineStorageTargets,
|
|
6
|
+
defineUploadProfiles,
|
|
7
|
+
} from '@cedarjs/uploads'
|
|
8
|
+
__GET_PATHS_IMPORT__
|
|
9
|
+
__S3_CLIENT__
|
|
10
|
+
/**
|
|
11
|
+
* Where files live. Each target is a provider instance; the Upload row
|
|
12
|
+
* records which target holds a file so it can be read, served, and deleted
|
|
13
|
+
* later. Look one up by name with `resolveTarget(targets, upload.target)`.
|
|
14
|
+
*/
|
|
15
|
+
export const targets = defineStorageTargets({
|
|
16
|
+
__TARGETS__})
|
|
4
17
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
export const urlSigner = new UrlSigner({
|
|
15
|
-
secret: process.env.UPLOADS_SECRET,
|
|
16
|
-
endpoint: '/signedUrl',
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
const { saveFiles, storagePrismaExtension } = setupStorage({
|
|
20
|
-
uploadsConfig,
|
|
21
|
-
storageAdapter: fsStorage,
|
|
22
|
-
urlSigner,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
export { saveFiles, storagePrismaExtension }
|
|
18
|
+
/**
|
|
19
|
+
* What clients may upload. A profile names a target and the constraints the
|
|
20
|
+
* server signs into every upload token issued for it. The client never
|
|
21
|
+
* supplies constraints; it names a profile.
|
|
22
|
+
*/
|
|
23
|
+
export const profiles = defineUploadProfiles({
|
|
24
|
+
__PROFILES__})
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export const schema = gql`
|
|
2
|
+
type Upload {
|
|
3
|
+
id: String!
|
|
4
|
+
target: String!
|
|
5
|
+
status: String!
|
|
6
|
+
filename: String!
|
|
7
|
+
mimeType: String!
|
|
8
|
+
size: BigInt!
|
|
9
|
+
storageKey: String
|
|
10
|
+
userId: String
|
|
11
|
+
organizationId: String
|
|
12
|
+
createdAt: DateTime!
|
|
13
|
+
updatedAt: DateTime!
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type UploadToken {
|
|
17
|
+
token: String!
|
|
18
|
+
"""
|
|
19
|
+
The profile's constraints, echoed for client-side UX (file-picker
|
|
20
|
+
filters, pre-upload validation). The authoritative copy is inside the
|
|
21
|
+
signed token.
|
|
22
|
+
"""
|
|
23
|
+
allowedMimeTypes: [String!]!
|
|
24
|
+
maxFileSize: BigInt!
|
|
25
|
+
maxFiles: Int!
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type PresignedUploadUrl {
|
|
29
|
+
uploadId: String!
|
|
30
|
+
url: String!
|
|
31
|
+
method: String!
|
|
32
|
+
headers: JSON!
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
input CreatePresignedUploadUrlInput {
|
|
36
|
+
filename: String!
|
|
37
|
+
contentType: String!
|
|
38
|
+
size: BigInt!
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
input UploadFileInput {
|
|
42
|
+
filename: String!
|
|
43
|
+
mimeType: String!
|
|
44
|
+
"""
|
|
45
|
+
The file's bytes, base64-encoded. Only for profiles whose target stores
|
|
46
|
+
files inline in the database.
|
|
47
|
+
"""
|
|
48
|
+
data: String!
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type Query {
|
|
52
|
+
"""
|
|
53
|
+
Issues an upload token for a server-defined profile. The profile name
|
|
54
|
+
must match a key of \`profiles\` in api/src/lib/uploads.
|
|
55
|
+
"""
|
|
56
|
+
requestUploadToken(profile: String!): UploadToken! @requireAuth
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type Mutation {
|
|
60
|
+
"""
|
|
61
|
+
Direct-to-storage uploads: returns a presigned URL for one file. Send the
|
|
62
|
+
upload token in the x-upload-token header.
|
|
63
|
+
"""
|
|
64
|
+
createPresignedUploadUrl(
|
|
65
|
+
input: CreatePresignedUploadUrlInput!
|
|
66
|
+
): PresignedUploadUrl! @requireAuth @requireUploadToken
|
|
67
|
+
|
|
68
|
+
"""
|
|
69
|
+
Confirms a direct-to-storage upload once the client has PUT the bytes.
|
|
70
|
+
"""
|
|
71
|
+
confirmUpload(uploadId: String!): Upload! @requireAuth
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
Stores a small file sent as base64, for profiles whose target keeps files
|
|
75
|
+
inline in the database.
|
|
76
|
+
"""
|
|
77
|
+
uploadFile(profile: String!, input: UploadFileInput!): Upload! @requireAuth
|
|
78
|
+
}
|
|
79
|
+
`
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
confirmUpload as confirmUploadRecord,
|
|
3
|
+
createPresignedUpload,
|
|
4
|
+
getUploadTokenPayload,
|
|
5
|
+
isMimeTypeAllowed,
|
|
6
|
+
issueUploadToken,
|
|
7
|
+
resolveProfile,
|
|
8
|
+
resolveTarget,
|
|
9
|
+
storeFile,
|
|
10
|
+
UploadError,
|
|
11
|
+
} from '@cedarjs/uploads'
|
|
12
|
+
|
|
13
|
+
import { db } from 'src/lib/db'
|
|
14
|
+
import { profiles, targets } from 'src/lib/uploads'
|
|
15
|
+
|
|
16
|
+
const secret = () => {
|
|
17
|
+
if (!process.env.UPLOAD_TOKEN_SECRET) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
'UPLOAD_TOKEN_SECRET is not set. Generate one with `yarn cedar generate secret` and add it to .env.',
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return process.env.UPLOAD_TOKEN_SECRET
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const requestUploadToken = ({ profile }: { profile: string }) => {
|
|
27
|
+
return issueUploadToken({
|
|
28
|
+
profiles,
|
|
29
|
+
profile,
|
|
30
|
+
secret: secret(),
|
|
31
|
+
currentUser: context.currentUser,
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const createPresignedUploadUrl = ({
|
|
36
|
+
input,
|
|
37
|
+
}: {
|
|
38
|
+
input: { filename: string; contentType: string; size: bigint | number }
|
|
39
|
+
}) => {
|
|
40
|
+
return createPresignedUpload({
|
|
41
|
+
db,
|
|
42
|
+
targets,
|
|
43
|
+
tokenPayload: getUploadTokenPayload(context),
|
|
44
|
+
input,
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const confirmUpload = ({ uploadId }: { uploadId: string }) => {
|
|
49
|
+
return confirmUploadRecord({
|
|
50
|
+
db,
|
|
51
|
+
targets,
|
|
52
|
+
uploadId,
|
|
53
|
+
currentUser: context.currentUser,
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const uploadFile = async ({
|
|
58
|
+
profile: profileName,
|
|
59
|
+
input,
|
|
60
|
+
}: {
|
|
61
|
+
profile: string
|
|
62
|
+
input: { filename: string; mimeType: string; data: string }
|
|
63
|
+
}) => {
|
|
64
|
+
const profile = resolveProfile(profiles, profileName)
|
|
65
|
+
const target = resolveTarget(targets, profile.target)
|
|
66
|
+
|
|
67
|
+
if (target.providerType !== 'db') {
|
|
68
|
+
throw new UploadError(
|
|
69
|
+
'NOT_SUPPORTED',
|
|
70
|
+
`Upload profile '${profile.name}' does not store files in the database. Use an upload token instead.`,
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!isMimeTypeAllowed(profile.allowedMimeTypes, input.mimeType)) {
|
|
75
|
+
throw new UploadError(
|
|
76
|
+
'MIME_TYPE_NOT_ALLOWED',
|
|
77
|
+
`File type '${input.mimeType}' is not allowed for upload profile '${profile.name}'.`,
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return storeFile(target, {
|
|
82
|
+
db,
|
|
83
|
+
filename: input.filename,
|
|
84
|
+
mimeType: input.mimeType,
|
|
85
|
+
data: Buffer.from(input.data, 'base64'),
|
|
86
|
+
maxSize: profile.maxFileSize,
|
|
87
|
+
userId: context.currentUser ? String(context.currentUser.id) : undefined,
|
|
88
|
+
})
|
|
89
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createWithDataUriDirective } from '@cedarjs/uploads'
|
|
2
|
+
|
|
3
|
+
import { db } from 'src/lib/db'
|
|
4
|
+
import { targets } from 'src/lib/uploads'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolves a field holding an Upload id to a base64 data: URI of the file.
|
|
8
|
+
* Every resolved field embeds the whole file, so use it for small files only.
|
|
9
|
+
*/
|
|
10
|
+
const withDataUri = createWithDataUriDirective({ db, targets })
|
|
11
|
+
|
|
12
|
+
export const schema = withDataUri.schema
|
|
13
|
+
|
|
14
|
+
export default withDataUri
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createWithSignedUrlDirective } from '@cedarjs/uploads'
|
|
2
|
+
|
|
3
|
+
import { db } from 'src/lib/db'
|
|
4
|
+
import { targets } from 'src/lib/uploads'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolves a field holding an Upload id to a time-limited URL for the file,
|
|
8
|
+
* from whichever storage target holds it. Files download by default; pass
|
|
9
|
+
* `disposition: 'inline'` to render them in the browser instead, and only
|
|
10
|
+
* for MIME types you trust.
|
|
11
|
+
*/
|
|
12
|
+
const withSignedUrl = createWithSignedUrlDirective({ db, targets })
|
|
13
|
+
|
|
14
|
+
export const schema = withSignedUrl.schema
|
|
15
|
+
|
|
16
|
+
export default withSignedUrl
|