@cedarjs/cli 7.0.1-next.467 → 7.1.0-rc.32
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/dist/commands/build/buildHandler.js +1 -2
- package/dist/commands/build.js +1 -1
- package/dist/commands/check.js +1 -2
- package/dist/commands/deploy/baremetal/baremetalHandler.js +73 -364
- package/dist/commands/deploy/baremetal.js +1 -7
- package/dist/commands/deploy/flightcontrolHandler.js +1 -1
- package/dist/commands/deploy/helpers/deployHandler.js +1 -1
- package/dist/commands/deploy/netlify.js +1 -1
- package/dist/commands/deploy/renderHandler.js +1 -1
- package/dist/commands/deploy/serverlessHandler.js +1 -2
- package/dist/commands/deploy/vercel.js +1 -1
- package/dist/commands/destroy/handlerHelpers.js +1 -1
- package/dist/commands/destroy/page/pageHandler.js +1 -2
- package/dist/commands/destroy/scaffold/scaffoldHandler.js +26 -65
- package/dist/commands/destroy/sdl/sdlHandler.js +1 -2
- package/dist/commands/dev/devHandler.js +4 -3
- package/dist/commands/dev/packageWatchCommands.js +3 -8
- package/dist/commands/dev.js +1 -1
- package/dist/commands/execHandler.js +1 -2
- package/dist/commands/experimental/live-queries/liveQueries.js +1 -1
- package/dist/commands/experimental/live-queries/liveQueriesHandler.js +3 -3
- package/dist/commands/experimental/setupInngest.js +1 -1
- package/dist/commands/experimental/setupInngestHandler.js +1 -1
- package/dist/commands/experimental/setupOpentelemetry.js +1 -1
- package/dist/commands/experimental/setupOpentelemetryHandler.js +1 -2
- package/dist/commands/experimental/setupReactCompiler.js +1 -1
- package/dist/commands/experimental/setupReactCompilerHandler.js +4 -4
- package/dist/commands/experimental/setupRsc.js +1 -1
- package/dist/commands/experimental/setupRscHandler.js +1 -2
- package/dist/commands/experimental/setupStreamingSsr.js +1 -1
- package/dist/commands/experimental/setupStreamingSsrHandler.js +2 -3
- package/dist/commands/generate/cell/cell.js +0 -20
- package/dist/commands/generate/cell/cellHandler.js +20 -68
- package/dist/commands/generate/cell/templates/cell.tsx.template +2 -21
- package/dist/commands/generate/cell/templates/cellList.tsx.template +2 -21
- package/dist/commands/generate/cell/templates/test.js.template +1 -1
- package/dist/commands/generate/dataMigration/dataMigration.js +1 -2
- package/dist/commands/generate/dbAuth/dbAuth.js +2 -6
- package/dist/commands/generate/dbAuth/dbAuthHandler.js +17 -80
- package/dist/commands/generate/dbAuth/templates/login.webAuthn.tsx.template +12 -20
- package/dist/commands/generate/directive/directiveHandler.js +1 -2
- package/dist/commands/generate/function/functionHandler.js +1 -2
- package/dist/commands/generate/helpers.js +0 -26
- package/dist/commands/generate/job/jobHandler.js +1 -2
- package/dist/commands/generate/model/modelHandler.js +1 -2
- package/dist/commands/generate/ogImage/ogImageHandler.js +1 -2
- package/dist/commands/generate/ogImage/templates/ogImage.og.tsx.template +1 -1
- package/dist/commands/generate/package/filesTask.js +12 -9
- package/dist/commands/generate/package/packageHandler.js +4 -3
- package/dist/commands/generate/package/templates/tsconfig.json.template +0 -1
- package/dist/commands/generate/page/pageHandler.js +1 -2
- package/dist/commands/generate/realtime/realtime.js +1 -1
- package/dist/commands/generate/realtime/realtimeHandler.js +9 -2
- package/dist/commands/generate/realtime/templates/liveQueries/blank/blank.service.ts.template +4 -12
- package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.service.ts.template +2 -2
- package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +4 -4
- package/dist/commands/generate/scaffold/scaffold.js +1 -1
- package/dist/commands/generate/scaffold/scaffoldHandler.js +49 -93
- package/dist/commands/generate/scaffold/templates/assets/scaffold.tailwind.css.template +7 -12
- package/dist/commands/generate/scaffold/templates/components/EditNameCell.tsx.template +7 -5
- package/dist/commands/generate/scaffold/templates/components/NameForm.tsx.template +9 -10
- package/dist/commands/generate/scaffold/templates/lib/formatters.test.tsx.template +0 -11
- package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +4 -16
- package/dist/commands/generate/script/scriptHandler.js +1 -2
- package/dist/commands/generate/script/templates/tsconfig.json.template +0 -1
- package/dist/commands/generate/sdl/sdlHandler.js +4 -10
- package/dist/commands/generate/secret/secret.js +1 -1
- package/dist/commands/generate/service/serviceHandler.js +49 -79
- package/dist/commands/generate/service/templates/service.ts.template +13 -40
- package/dist/commands/generate/service/templates/test.ts.template +6 -8
- package/dist/commands/generate/yargsCommandHelpers.js +1 -1
- package/dist/commands/generate/yargsHandlerHelpers.js +1 -2
- package/dist/commands/generate.js +1 -1
- package/dist/commands/info.js +1 -1
- package/dist/commands/jobsHandler.js +3 -5
- package/dist/commands/lint.js +1 -1
- package/dist/commands/prerenderHandler.js +4 -11
- package/dist/commands/prismaHandler.js +2 -7
- package/dist/commands/record/init.js +1 -1
- package/dist/commands/serve.js +1 -2
- package/dist/commands/setup/auth/auth.js +4 -2
- package/dist/commands/setup/cache/cache.js +1 -1
- package/dist/commands/setup/cache/cacheHandler.js +1 -2
- package/dist/commands/setup/cache/templates/memcached.ts.template +17 -14
- package/dist/commands/setup/cache/templates/redis.ts.template +20 -12
- package/dist/commands/setup/database/postgres.js +1 -1
- package/dist/commands/setup/database/postgresHandler.js +1 -3
- package/dist/commands/setup/deploy/providers/baremetal.js +0 -7
- package/dist/commands/setup/deploy/providers/baremetalHandler.js +21 -130
- package/dist/commands/setup/deploy/providers/coherence.js +1 -1
- package/dist/commands/setup/deploy/providers/coherenceHandler.js +6 -7
- package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +1 -2
- package/dist/commands/setup/deploy/providers/netlifyHandler.js +1 -2
- package/dist/commands/setup/deploy/providers/renderHandler.js +1 -2
- package/dist/commands/setup/deploy/providers/serverlessHandler.js +1 -2
- package/dist/commands/setup/deploy/providers/universalDeployHandler.js +6 -4
- package/dist/commands/setup/deploy/providers/vercelHandler.js +1 -2
- package/dist/commands/setup/deploy/templates/baremetal.js +9 -119
- package/dist/commands/setup/deploy/templates/netlifyUD.js +0 -3
- package/dist/commands/setup/docker/docker.js +1 -1
- package/dist/commands/setup/docker/dockerHandler.js +1 -2
- package/dist/commands/setup/generator/generator.js +1 -1
- package/dist/commands/setup/generator/generatorHandler.js +1 -1
- package/dist/commands/setup/graphql/features/fragments/fragments.js +1 -1
- package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +5 -3
- package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +1 -1
- package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +1 -2
- package/dist/commands/setup/i18n/i18n.js +1 -1
- package/dist/commands/setup/i18n/i18nHandler.js +1 -1
- package/dist/commands/setup/jobs/jobs.js +1 -1
- package/dist/commands/setup/jobs/jobsHandler.js +1 -4
- package/dist/commands/setup/mailer/mailer.js +1 -1
- package/dist/commands/setup/mailer/mailerHandler.js +1 -2
- package/dist/commands/setup/middleware/ogImage/ogImage.js +1 -1
- package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +1 -2
- package/dist/commands/setup/monitoring/sentry/sentry.js +1 -1
- package/dist/commands/setup/monitoring/sentry/sentryHandler.js +9 -13
- package/dist/commands/setup/monitoring/sentry/templates/sentryApi.ts.template +4 -1
- package/dist/commands/setup/monitoring/sentry/templates/sentryWeb.ts.template +4 -7
- package/dist/commands/setup/neon/neon.js +1 -1
- package/dist/commands/setup/neon/neonHandler.js +9 -5
- package/dist/commands/setup/package/package.js +1 -1
- package/dist/commands/setup/package/packageHandler.js +4 -4
- 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 +16 -4
- package/dist/commands/setup/realtime/templates/defer/fastAndSlowFields/fastAndSlowFields.ts.template +1 -4
- package/dist/commands/setup/realtime/templates/liveQueries/auctions/auctions.ts.template +4 -12
- package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +1 -1
- package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +2 -2
- package/dist/commands/setup/server-file/serverFile.js +1 -1
- package/dist/commands/setup/server-file/serverFileHandler.js +1 -2
- package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +1 -2
- package/dist/commands/setup/ui/libraries/mantineHandler.js +1 -2
- package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +82 -63
- package/dist/commands/setup/ui/templates/postcss.config.cjs.template +9 -0
- package/dist/commands/setup/uploads/dbCodemod.js +28 -0
- package/dist/commands/setup/uploads/templates/signedUrl.ts.template +21 -0
- package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +24 -23
- package/dist/commands/setup/uploads/uploads.js +7 -49
- package/dist/commands/setup/uploads/uploadsHandler.js +69 -277
- package/dist/commands/setup.js +1 -2
- package/dist/commands/studio.js +1 -1
- package/dist/commands/test/testHandler.js +71 -25
- package/dist/commands/test/testHandlerEsm.js +109 -0
- package/dist/commands/test.js +18 -10
- package/dist/commands/testEsm.js +41 -0
- package/dist/commands/type-checkHandler.js +1 -1
- package/dist/commands/upgrade/preUpgradeScripts.js +3 -3
- package/dist/commands/upgrade/upgrade.js +1 -1
- package/dist/commands/upgrade/upgradeHandler.js +1 -2
- package/dist/index.js +8 -5
- package/dist/lib/exit.js +1 -1
- package/dist/lib/index.js +31 -16
- package/dist/lib/loadEnvFiles.js +1 -1
- package/dist/lib/plugin.js +1 -1
- package/dist/lib/test.js +1 -1
- package/dist/lib/updateCheck.js +4 -4
- package/dist/middleware/checkNodeVersion.js +4 -4
- package/package.json +27 -27
- package/dist/commands/deploy/baremetal/monitors.js +0 -66
- package/dist/commands/generate/cell/templates/cellFragment.tsx.template +0 -43
- package/dist/commands/generate/cell/templates/storiesFragment.tsx.template +0 -23
- package/dist/commands/generate/cell/templates/testFragment.js.template +0 -30
- package/dist/commands/generate/dbAuth/templates/changePassword.tsx.template +0 -131
- package/dist/commands/generate/dbAuth/templates/login.oauth.tsx.template +0 -164
- package/dist/commands/generate/dbAuth/templates/signup.oauth.tsx.template +0 -147
- package/dist/commands/generate/scaffold/templates/layouts/NamesScaffoldLayout.tsx.template +0 -18
- package/dist/commands/setup/tenancy/authCodemod.js +0 -66
- package/dist/commands/setup/tenancy/dbCodemod.js +0 -64
- package/dist/commands/setup/tenancy/graphqlCodemod.js +0 -88
- package/dist/commands/setup/tenancy/preflight.js +0 -49
- package/dist/commands/setup/tenancy/schemaPrisma.js +0 -81
- package/dist/commands/setup/tenancy/signupCodemod.js +0 -154
- package/dist/commands/setup/tenancy/templates/InvitePage.tsx.template +0 -72
- package/dist/commands/setup/tenancy/templates/OrgScope.tsx.template +0 -40
- package/dist/commands/setup/tenancy/templates/ensureDefaultOrganizations.dataMigration.ts.template +0 -39
- package/dist/commands/setup/tenancy/templates/organizations.scenarios.ts.template +0 -57
- package/dist/commands/setup/tenancy/templates/organizations.sdl.ts.template +0 -89
- package/dist/commands/setup/tenancy/templates/organizations.test.ts.template +0 -381
- package/dist/commands/setup/tenancy/templates/organizations.ts.template +0 -394
- package/dist/commands/setup/tenancy/templates/requireMembership.test.ts.template +0 -35
- package/dist/commands/setup/tenancy/templates/requireMembership.ts.template +0 -25
- package/dist/commands/setup/tenancy/tenancy.js +0 -30
- package/dist/commands/setup/tenancy/tenancyHandler.js +0 -425
- package/dist/commands/setup/uploads/gitignore.js +0 -17
- package/dist/commands/setup/uploads/schemaPrisma.js +0 -41
- package/dist/commands/setup/uploads/serverFile.js +0 -217
- package/dist/commands/setup/uploads/templates/requireUploadToken.ts.template +0 -15
- package/dist/commands/setup/uploads/templates/uploads.sdl.ts.template +0 -79
- package/dist/commands/setup/uploads/templates/uploads.ts.template +0 -98
- package/dist/commands/setup/uploads/templates/withDataUri.ts.template +0 -14
- package/dist/commands/setup/uploads/templates/withSignedUrl.ts.template +0 -16
- package/dist/commands/test/viteVersionCheck.js +0 -75
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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__})
|
|
1
|
+
import { createUploadsConfig, setupStorage } from '@cedarjs/storage'
|
|
2
|
+
import { FileSystemStorage } from '@cedarjs/storage/FileSystemStorage'
|
|
3
|
+
import { UrlSigner } from '@cedarjs/storage/UrlSigner'
|
|
17
4
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export const
|
|
24
|
-
|
|
5
|
+
const uploadsConfig = createUploadsConfig({
|
|
6
|
+
// Configure your fields here
|
|
7
|
+
// e.g. modelName: { fields: ['fieldWithUpload']}
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export const fsStorage = new FileSystemStorage({
|
|
11
|
+
baseDir: './uploads',
|
|
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 }
|
|
@@ -1,68 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
|
|
3
|
-
import { requireTTYOrExit } from "@cedarjs/cli-helpers/tty";
|
|
1
|
+
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
4
2
|
const command = "uploads";
|
|
5
|
-
const description = "
|
|
6
|
-
const TARGET_CHOICES = ["fs", "db", "s3"];
|
|
7
|
-
const TARGET_DESCRIPTIONS = {
|
|
8
|
-
fs: "Local filesystem, uploaded through the api server (development, single-server deploys)",
|
|
9
|
-
db: "Inline in the database, for small files like avatars and thumbnails",
|
|
10
|
-
s3: "S3 or S3-compatible storage, uploaded straight from the browser with presigned URLs"
|
|
11
|
-
};
|
|
3
|
+
const description = "Setup uploads and storage. This will install the required packages and add the required initial configuration to your redwood app.";
|
|
12
4
|
const builder = (yargs) => {
|
|
13
|
-
|
|
14
|
-
choices: TARGET_CHOICES,
|
|
15
|
-
description: "Storage targets to configure: fs (local filesystem), db (inline in the database), s3 (direct-to-S3 presigned uploads). Prompts when omitted.",
|
|
16
|
-
type: "array"
|
|
17
|
-
}).option("force", {
|
|
5
|
+
yargs.option("force", {
|
|
18
6
|
alias: "f",
|
|
19
7
|
default: false,
|
|
20
8
|
description: "Overwrite existing configuration",
|
|
21
9
|
type: "boolean"
|
|
22
10
|
});
|
|
23
11
|
};
|
|
24
|
-
function toTargetChoices(values) {
|
|
25
|
-
const choices = TARGET_CHOICES;
|
|
26
|
-
return [...new Set(values)].filter(
|
|
27
|
-
(t) => choices.includes(t)
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
async function promptForTargets() {
|
|
31
|
-
requireTTYOrExit("--targets");
|
|
32
|
-
const response = await prompts({
|
|
33
|
-
type: "multiselect",
|
|
34
|
-
name: "targets",
|
|
35
|
-
message: "Which storage targets do you want to configure?",
|
|
36
|
-
instructions: false,
|
|
37
|
-
hint: "Space to toggle, enter to confirm",
|
|
38
|
-
min: 1,
|
|
39
|
-
choices: TARGET_CHOICES.map((value) => ({
|
|
40
|
-
title: value,
|
|
41
|
-
description: TARGET_DESCRIPTIONS[value],
|
|
42
|
-
value,
|
|
43
|
-
selected: value !== "s3"
|
|
44
|
-
}))
|
|
45
|
-
});
|
|
46
|
-
if (response.targets === void 0) {
|
|
47
|
-
process.exit(0);
|
|
48
|
-
}
|
|
49
|
-
return toTargetChoices(response.targets);
|
|
50
|
-
}
|
|
51
12
|
const handler = async (options) => {
|
|
52
|
-
const targets = options.targets?.length ? toTargetChoices(options.targets) : await promptForTargets();
|
|
53
13
|
recordTelemetryAttributes({
|
|
54
14
|
command: "setup uploads",
|
|
55
|
-
|
|
56
|
-
|
|
15
|
+
force: options.force,
|
|
16
|
+
skipExamples: options.skipExamples
|
|
57
17
|
});
|
|
58
18
|
const { handler: handler2 } = await import("./uploadsHandler.js");
|
|
59
|
-
return handler2(
|
|
19
|
+
return handler2(options);
|
|
60
20
|
};
|
|
61
21
|
export {
|
|
62
|
-
TARGET_CHOICES,
|
|
63
22
|
builder,
|
|
64
23
|
command,
|
|
65
24
|
description,
|
|
66
|
-
handler
|
|
67
|
-
toTargetChoices
|
|
25
|
+
handler
|
|
68
26
|
};
|
|
@@ -1,298 +1,105 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { pathToFileURL } from "node:url";
|
|
4
3
|
import { Listr } from "listr2";
|
|
5
4
|
import { format } from "prettier";
|
|
6
5
|
import { terminalLink } from "termi-link";
|
|
7
|
-
import { colors as c } from "@cedarjs/cli-helpers/colors";
|
|
8
|
-
import { getPrettierOptions } from "@cedarjs/cli-helpers/fileHelpers";
|
|
9
6
|
import {
|
|
10
7
|
addApiPackages,
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
getPrettierOptions,
|
|
9
|
+
colors as c
|
|
10
|
+
} from "@cedarjs/cli-helpers";
|
|
13
11
|
import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
|
|
14
|
-
import { addEnvVar } from "@cedarjs/cli-helpers/project";
|
|
15
|
-
import { getSchemaPath } from "@cedarjs/project-config";
|
|
16
12
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
17
13
|
import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
|
|
18
14
|
import { isTypeScriptProject } from "../../../lib/project.js";
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
import { transformGitignore } from "./gitignore.js";
|
|
22
|
-
import { addUploadModel } from "./schemaPrisma.js";
|
|
23
|
-
import {
|
|
24
|
-
addUploadsPlugin,
|
|
25
|
-
detectServerAuth,
|
|
26
|
-
hasUploadsPlugin
|
|
27
|
-
} from "./serverFile.js";
|
|
28
|
-
const UPPY_VERSION = "^6.0.0";
|
|
29
|
-
const S3_IMPORTS = `import { S3Client } from '@aws-sdk/client-s3'
|
|
30
|
-
|
|
31
|
-
import { createS3Provider } from '@cedarjs/uploads/s3'
|
|
32
|
-
`;
|
|
33
|
-
const S3_CLIENT = `
|
|
34
|
-
// Your own S3 client. It stays available for S3-specific work (lifecycle
|
|
35
|
-
// rules, CORS, and so on) alongside the storage target below. Credentials
|
|
36
|
-
// come from the SDK's default chain: AWS_ACCESS_KEY_ID and
|
|
37
|
-
// AWS_SECRET_ACCESS_KEY in .env, or an IAM role, SSO, or container
|
|
38
|
-
// credentials in production. For an S3-compatible service, add \`endpoint\`
|
|
39
|
-
// and \`forcePathStyle: true\`.
|
|
40
|
-
export const s3Client = new S3Client({
|
|
41
|
-
region: process.env.AWS_REGION,
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
const s3Bucket = process.env.S3_BUCKET_UPLOADS
|
|
45
|
-
|
|
46
|
-
if (!s3Bucket) {
|
|
47
|
-
throw new Error('Set S3_BUCKET_UPLOADS in .env to use the S3 storage target')
|
|
48
|
-
}
|
|
49
|
-
`;
|
|
50
|
-
const TARGET_BLOCKS = {
|
|
51
|
-
fs: ` // Files uploaded through the api server and stored on local disk. Good for
|
|
52
|
-
// development and single-server deploys.
|
|
53
|
-
local: createFsProvider({
|
|
54
|
-
uploadDir: path.join(getPaths().api.base, '.uploads'),
|
|
55
|
-
serveBaseUrl: process.env.UPLOAD_SERVE_BASE_URL,
|
|
56
|
-
signSecret: process.env.UPLOAD_TOKEN_SECRET,
|
|
57
|
-
}),
|
|
58
|
-
`,
|
|
59
|
-
db: ` // Small files stored inline in the Upload row (avatars, thumbnails).
|
|
60
|
-
thumbnails: createDbProvider(),
|
|
61
|
-
`,
|
|
62
|
-
s3: ` // Files uploaded straight from the browser to S3 with presigned URLs.
|
|
63
|
-
files: createS3Provider({
|
|
64
|
-
client: s3Client,
|
|
65
|
-
bucket: s3Bucket,
|
|
66
|
-
region: process.env.AWS_REGION,
|
|
67
|
-
keyPrefix: 'uploads/',
|
|
68
|
-
}),
|
|
69
|
-
`
|
|
70
|
-
};
|
|
71
|
-
const PROFILE_BLOCKS = {
|
|
72
|
-
fs: ` attachment: {
|
|
73
|
-
target: 'local',
|
|
74
|
-
allowedMimeTypes: ['application/pdf', 'image/png', 'image/jpeg'],
|
|
75
|
-
maxFileSize: 25 * 1024 * 1024,
|
|
76
|
-
maxFiles: 10,
|
|
77
|
-
},
|
|
78
|
-
`,
|
|
79
|
-
db: ` avatar: {
|
|
80
|
-
target: 'thumbnails',
|
|
81
|
-
allowedMimeTypes: ['image/png', 'image/jpeg'],
|
|
82
|
-
maxFileSize: DB_MAX_FILE_SIZE,
|
|
83
|
-
maxFiles: 1,
|
|
84
|
-
},
|
|
85
|
-
`,
|
|
86
|
-
s3: ` document: {
|
|
87
|
-
target: 'files',
|
|
88
|
-
allowedMimeTypes: ['application/pdf', 'image/*'],
|
|
89
|
-
maxFileSize: 100 * 1024 * 1024,
|
|
90
|
-
maxFiles: 5,
|
|
91
|
-
},
|
|
92
|
-
`
|
|
93
|
-
};
|
|
94
|
-
const handler = async ({ targets, force }) => {
|
|
95
|
-
const paths = getPaths();
|
|
15
|
+
import { runTransform } from "../../../lib/runTransform.js";
|
|
16
|
+
const handler = async ({ force }) => {
|
|
96
17
|
const projectIsTypescript = isTypeScriptProject();
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const wantsS3 = targets.includes("s3");
|
|
101
|
-
const wantsUppy = wantsFs || wantsS3;
|
|
102
|
-
const packageJson = await import(pathToFileURL(path.join(paths.base, "package.json")).href, { with: { type: "json" } });
|
|
18
|
+
const packageJson = await import(path.join(getPaths().base, "package.json"), {
|
|
19
|
+
with: { type: "json" }
|
|
20
|
+
});
|
|
103
21
|
const cedarVersion = packageJson.default.devDependencies["@cedarjs/core"] ?? "latest";
|
|
104
|
-
const serverFilePath = path.join(paths.api.src, `server.${ext}`);
|
|
105
|
-
const writeTemplateFile = async (templateFile, outputPath, replacements = {}) => {
|
|
106
|
-
const templatePath = path.resolve(
|
|
107
|
-
import.meta.dirname,
|
|
108
|
-
"templates",
|
|
109
|
-
templateFile
|
|
110
|
-
);
|
|
111
|
-
let templateContent = fs.readFileSync(templatePath, "utf-8");
|
|
112
|
-
for (const [token, value] of Object.entries(replacements)) {
|
|
113
|
-
templateContent = templateContent.replaceAll(token, value);
|
|
114
|
-
}
|
|
115
|
-
const content = projectIsTypescript ? templateContent : await transformTSToJS(outputPath, templateContent);
|
|
116
|
-
return writeFile(outputPath, content, { overwriteExisting: force });
|
|
117
|
-
};
|
|
118
|
-
const apiPackages = [`@cedarjs/uploads@${cedarVersion}`];
|
|
119
|
-
const webPackages = [`@cedarjs/uploads@${cedarVersion}`];
|
|
120
|
-
if (wantsS3) {
|
|
121
|
-
apiPackages.push("@aws-sdk/client-s3", "@aws-sdk/s3-request-presigner");
|
|
122
|
-
}
|
|
123
|
-
if (wantsUppy) {
|
|
124
|
-
webPackages.push(
|
|
125
|
-
`@uppy/core@${UPPY_VERSION}`,
|
|
126
|
-
`@uppy/react@${UPPY_VERSION}`,
|
|
127
|
-
`@uppy/dashboard@${UPPY_VERSION}`
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
if (wantsFs) {
|
|
131
|
-
webPackages.push(`@uppy/xhr-upload@${UPPY_VERSION}`);
|
|
132
|
-
}
|
|
133
|
-
if (wantsS3) {
|
|
134
|
-
webPackages.push(`@uppy/aws-s3@${UPPY_VERSION}`);
|
|
135
|
-
}
|
|
136
22
|
const tasks = new Listr(
|
|
137
23
|
[
|
|
138
24
|
{
|
|
139
|
-
|
|
140
|
-
title: "Adding @cedarjs/uploads to your api side..."
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
...addWebPackages(webPackages),
|
|
144
|
-
title: "Adding @cedarjs/uploads to your web side..."
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
title: "Adding the Upload model to schema.prisma...",
|
|
25
|
+
title: `Adding api/src/lib/uploads.${projectIsTypescript ? "ts" : "js"}...`,
|
|
148
26
|
task: async () => {
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
{
|
|
161
|
-
__S3_IMPORTS__: wantsS3 ? S3_IMPORTS : "",
|
|
162
|
-
__S3_CLIENT__: wantsS3 ? S3_CLIENT : "",
|
|
163
|
-
__FS_IMPORT__: wantsFs ? "createFsProvider," : "",
|
|
164
|
-
__DB_IMPORT__: wantsDb ? "createDbProvider," : "",
|
|
165
|
-
__DB_MAX_IMPORT__: wantsDb ? "DB_MAX_FILE_SIZE," : "",
|
|
166
|
-
__PATH_IMPORT__: wantsFs ? "import path from 'node:path'\n\n" : "",
|
|
167
|
-
__GET_PATHS_IMPORT__: wantsFs ? "import { getPaths } from '@cedarjs/project-config'\n" : "",
|
|
168
|
-
__TARGETS__: targets.map((t) => TARGET_BLOCKS[t]).join("\n"),
|
|
169
|
-
__PROFILES__: targets.map((t) => PROFILE_BLOCKS[t]).join("\n")
|
|
170
|
-
}
|
|
27
|
+
const templatePath = path.resolve(
|
|
28
|
+
import.meta.dirname,
|
|
29
|
+
"templates",
|
|
30
|
+
"srcLibUploads.ts.template"
|
|
31
|
+
);
|
|
32
|
+
const templateContent = fs.readFileSync(templatePath, {
|
|
33
|
+
encoding: "utf8",
|
|
34
|
+
flag: "r"
|
|
35
|
+
});
|
|
36
|
+
const uploadsPath = path.join(
|
|
37
|
+
getPaths().api.lib,
|
|
38
|
+
`uploads.${projectIsTypescript ? "ts" : "js"}`
|
|
171
39
|
);
|
|
40
|
+
const uploadsContent = projectIsTypescript ? templateContent : await transformTSToJS(uploadsPath, templateContent);
|
|
41
|
+
return writeFile(uploadsPath, uploadsContent, {
|
|
42
|
+
overwriteExisting: force
|
|
43
|
+
});
|
|
172
44
|
}
|
|
173
45
|
},
|
|
174
46
|
{
|
|
175
|
-
title:
|
|
47
|
+
title: `Adding signedUrl function...`,
|
|
176
48
|
task: async () => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
49
|
+
const templatePath = path.resolve(
|
|
50
|
+
import.meta.dirname,
|
|
51
|
+
"templates",
|
|
52
|
+
"signedUrl.ts.template"
|
|
180
53
|
);
|
|
181
|
-
|
|
182
|
-
"
|
|
183
|
-
|
|
54
|
+
const templateContent = fs.readFileSync(templatePath, {
|
|
55
|
+
encoding: "utf8",
|
|
56
|
+
flag: "r"
|
|
57
|
+
});
|
|
58
|
+
const uploadsPath = path.join(
|
|
59
|
+
getPaths().api.functions,
|
|
60
|
+
`signedUrl.${projectIsTypescript ? "ts" : "js"}`
|
|
184
61
|
);
|
|
62
|
+
const uploadsContent = projectIsTypescript ? templateContent : await transformTSToJS(uploadsPath, templateContent);
|
|
63
|
+
return writeFile(uploadsPath, uploadsContent, {
|
|
64
|
+
overwriteExisting: force
|
|
65
|
+
});
|
|
185
66
|
}
|
|
186
67
|
},
|
|
187
68
|
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const directives = ["requireUploadToken", "withSignedUrl"];
|
|
191
|
-
if (wantsDb) {
|
|
192
|
-
directives.push("withDataUri");
|
|
193
|
-
}
|
|
194
|
-
for (const name of directives) {
|
|
195
|
-
await writeTemplateFile(
|
|
196
|
-
`${name}.ts.template`,
|
|
197
|
-
path.join(paths.api.directives, name, `${name}.${ext}`)
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
title: "Adding the server file...",
|
|
204
|
-
task: (_ctx, task) => task.newListr(setupServerFileTasks({ force: false })),
|
|
205
|
-
skip: () => fs.existsSync(serverFilePath) ? "api/src/server already exists; skipping." : false
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
title: "Registering the upload plugin in api/src/server...",
|
|
209
|
-
task: async (_ctx, task) => {
|
|
210
|
-
const source = fs.readFileSync(serverFilePath, "utf-8");
|
|
211
|
-
if (hasUploadsPlugin(source)) {
|
|
212
|
-
task.skip("The upload plugin is already registered; skipping.");
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const graphqlPath = path.join(paths.api.functions, `graphql.${ext}`);
|
|
216
|
-
const authPath = path.join(paths.api.lib, `auth.${ext}`);
|
|
217
|
-
const auth = fs.existsSync(graphqlPath) && fs.existsSync(authPath) && fs.readFileSync(authPath, "utf-8").includes("getCurrentUser") ? detectServerAuth(fs.readFileSync(graphqlPath, "utf-8")) : null;
|
|
218
|
-
let updated;
|
|
219
|
-
try {
|
|
220
|
-
updated = addUploadsPlugin(source, { auth });
|
|
221
|
-
} catch {
|
|
222
|
-
throw new Error(
|
|
223
|
-
`Could not find \`await server.start()\` in ${path.relative(
|
|
224
|
-
paths.base,
|
|
225
|
-
serverFilePath
|
|
226
|
-
)}. Register the plugin by hand before the server starts:
|
|
227
|
-
|
|
228
|
-
import { cedarUploadsPlugin } from '@cedarjs/uploads'
|
|
229
|
-
import { db } from 'src/lib/db'
|
|
230
|
-
import { targets } from 'src/lib/uploads'
|
|
231
|
-
|
|
232
|
-
await server.register(cedarUploadsPlugin, {
|
|
233
|
-
tokenSecret: process.env.UPLOAD_TOKEN_SECRET,
|
|
234
|
-
targets,
|
|
235
|
-
db,
|
|
236
|
-
})
|
|
237
|
-
`
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
fs.writeFileSync(serverFilePath, updated);
|
|
241
|
-
}
|
|
69
|
+
...addApiPackages([`@cedarjs/storage@${cedarVersion}`]),
|
|
70
|
+
title: "Adding dependencies to your api side..."
|
|
242
71
|
},
|
|
243
72
|
{
|
|
244
|
-
title: "
|
|
245
|
-
task: () => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
"Signs upload tokens and file-serving URLs. Keep it secret and use a different value per environment."
|
|
73
|
+
title: "Modifying api/src/lib/db to add uploads prisma extension..",
|
|
74
|
+
task: async () => {
|
|
75
|
+
const dbPath = path.join(
|
|
76
|
+
getPaths().api.lib,
|
|
77
|
+
`db.${projectIsTypescript ? "ts" : "js"}`
|
|
250
78
|
);
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
"
|
|
263
|
-
);
|
|
264
|
-
addEnvVar("AWS_ACCESS_KEY_ID", "replace-me", "");
|
|
265
|
-
addEnvVar("AWS_SECRET_ACCESS_KEY", "replace-me", "");
|
|
266
|
-
addEnvVar(
|
|
267
|
-
"S3_BUCKET_UPLOADS",
|
|
268
|
-
"replace-me",
|
|
269
|
-
"Bucket direct uploads land in."
|
|
79
|
+
const transformResult = await runTransform({
|
|
80
|
+
transformPath: path.join(import.meta.dirname, "dbCodemod.js"),
|
|
81
|
+
targetPaths: [dbPath]
|
|
82
|
+
});
|
|
83
|
+
if (transformResult.error) {
|
|
84
|
+
if (transformResult.error === "RW_CODEMOD_ERR_OLD_FORMAT") {
|
|
85
|
+
throw new Error(
|
|
86
|
+
"It looks like your src/lib/db file is using the old format. Please update it as per the v8 upgrade guide: https://cedarjs.com/docs/8.x/upgrade-guides/v8#database-file-structure-change. And run again. \n\nYou can also manually modify your api/src/lib/db to include the prisma extension: https://cedarjs.com/docs/uploads/#attaching-the-prisma-extension"
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
throw new Error(
|
|
90
|
+
"Could not add the prisma extension. \n Please modify your api/src/lib/db to include the prisma extension: https://cedarjs.com/docs/uploads/#attaching-the-prisma-extension"
|
|
270
91
|
);
|
|
271
92
|
}
|
|
272
93
|
}
|
|
273
94
|
},
|
|
274
|
-
{
|
|
275
|
-
title: "Adding the fs upload directory to .gitignore...",
|
|
276
|
-
skip: () => wantsFs ? false : "No fs target selected; skipping.",
|
|
277
|
-
task: (_ctx, task) => {
|
|
278
|
-
const gitignorePath = path.join(paths.base, ".gitignore");
|
|
279
|
-
const source = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, "utf-8") : "";
|
|
280
|
-
const updated = transformGitignore(source);
|
|
281
|
-
if (updated === source) {
|
|
282
|
-
task.skip(".gitignore already up to date");
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
fs.writeFileSync(gitignorePath, updated, "utf-8");
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
95
|
{
|
|
289
96
|
title: "Prettifying changed files",
|
|
290
97
|
task: async (_ctx, task) => {
|
|
291
98
|
const prettifyPaths = [
|
|
292
|
-
|
|
293
|
-
path.join(
|
|
294
|
-
path.join(
|
|
295
|
-
path.join(
|
|
99
|
+
path.join(getPaths().api.lib, "db.js"),
|
|
100
|
+
path.join(getPaths().api.lib, "db.ts"),
|
|
101
|
+
path.join(getPaths().api.lib, "uploads.js"),
|
|
102
|
+
path.join(getPaths().api.lib, "uploads.ts")
|
|
296
103
|
];
|
|
297
104
|
for (const prettifyPath of prettifyPaths) {
|
|
298
105
|
try {
|
|
@@ -301,11 +108,11 @@ const handler = async ({ targets, force }) => {
|
|
|
301
108
|
}
|
|
302
109
|
const source = fs.readFileSync(prettifyPath, "utf-8");
|
|
303
110
|
const prettierOptions = await getPrettierOptions();
|
|
304
|
-
const
|
|
111
|
+
const prettifiedApp = await format(source, {
|
|
305
112
|
...prettierOptions,
|
|
306
113
|
parser: "babel-ts"
|
|
307
114
|
});
|
|
308
|
-
fs.writeFileSync(prettifyPath,
|
|
115
|
+
fs.writeFileSync(prettifyPath, prettifiedApp, "utf-8");
|
|
309
116
|
} catch {
|
|
310
117
|
task.output = "Couldn't prettify the changes. Please reformat the files manually if needed.";
|
|
311
118
|
}
|
|
@@ -315,30 +122,15 @@ const handler = async ({ targets, force }) => {
|
|
|
315
122
|
{
|
|
316
123
|
title: "One more thing...",
|
|
317
124
|
task: (_ctx, task) => {
|
|
318
|
-
const migrate = c.highlight(
|
|
319
|
-
formatCedarCommand(["prisma", "migrate", "dev"])
|
|
320
|
-
);
|
|
321
|
-
const types = c.highlight(formatCedarCommand(["generate", "types"]));
|
|
322
125
|
task.title = `One more thing...
|
|
323
126
|
|
|
324
|
-
${c.success("
|
|
325
|
-
|
|
326
|
-
Next steps:
|
|
127
|
+
${c.success("\nUploads and storage configured!\n")}
|
|
327
128
|
|
|
328
|
-
|
|
329
|
-
2. Regenerate types: ${types}
|
|
330
|
-
3. Review the storage targets and upload profiles in api/src/lib/uploads.${ext}${wantsS3 ? "\n 4. Fill in the AWS_* and S3_BUCKET_UPLOADS values in .env" : ""}
|
|
331
|
-
|
|
332
|
-
Upload tokens are bound to the logged-in user when the app has auth.
|
|
333
|
-
If you add auth later, pass
|
|
334
|
-
\`authenticate: createUploadAuthenticator({ authDecoder, getCurrentUser })\`
|
|
335
|
-
to the plugin in api/src/server.${ext}.
|
|
336
|
-
|
|
337
|
-
Schedule cleanupStaleUploads() from a recurring job to sweep uploads
|
|
338
|
-
that never completed.
|
|
129
|
+
Remember to add UPLOADS_SECRET to your .env file. You can generate one with ${c.highlight(formatCedarCommand(["generate", "secret"]))}
|
|
339
130
|
|
|
340
131
|
Check out the docs for more info:
|
|
341
132
|
${terminalLink("", "https://cedarjs.com/docs/uploads")}
|
|
133
|
+
|
|
342
134
|
`;
|
|
343
135
|
}
|
|
344
136
|
}
|
package/dist/commands/setup.js
CHANGED
|
@@ -16,12 +16,11 @@ import * as setupNeon from "./setup/neon/neon.js";
|
|
|
16
16
|
import * as setupPackage from "./setup/package/package.js";
|
|
17
17
|
import * as setupRealtime from "./setup/realtime/realtime.js";
|
|
18
18
|
import * as setupServerFile from "./setup/server-file/serverFile.js";
|
|
19
|
-
import * as setupTenancy from "./setup/tenancy/tenancy.js";
|
|
20
19
|
import * as setupUi from "./setup/ui/ui.js";
|
|
21
20
|
import * as setupUploads from "./setup/uploads/uploads.js";
|
|
22
21
|
const command = "setup <command>";
|
|
23
22
|
const description = "Initialize project config and install packages";
|
|
24
|
-
const builder = (yargs) => yargs.command(setupAuth).command(setupCache).command(setupDatabase).command(setupDeploy).command(setupDocker).command(setupGenerator).command(setupGraphql).command(setupI18n).command(setupJobs).command(setupMailer).command(setupMiddleware).command(setupMonitoring).command(setupNeon).command(setupPackage).command(setupRealtime).command(setupServerFile).command(
|
|
23
|
+
const builder = (yargs) => yargs.command(setupAuth).command(setupCache).command(setupDatabase).command(setupDeploy).command(setupDocker).command(setupGenerator).command(setupGraphql).command(setupI18n).command(setupJobs).command(setupMailer).command(setupMiddleware).command(setupMonitoring).command(setupNeon).command(setupPackage).command(setupRealtime).command(setupServerFile).command(setupUi).command(setupUploads).demandCommand().middleware(detectCedarVersion).epilogue(
|
|
25
24
|
`Also see the ${terminalLink(
|
|
26
25
|
"CedarJS CLI Reference",
|
|
27
26
|
"https://cedarjs.com/docs/cli-commands#setup"
|
package/dist/commands/studio.js
CHANGED