@cedarjs/cli 7.0.1-next.467 → 7.1.0-rc.34
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,217 +0,0 @@
|
|
|
1
|
-
import { isBuiltin } from "node:module";
|
|
2
|
-
const START_LINE = /^([ \t]*)await server\.start\(\)/m;
|
|
3
|
-
const FACTORY_IMPORT = /import\s*\{[^}]*\bcreateAuthDecoder\b[^}]*\}\s*from\s*['"](@cedarjs\/auth-[a-z0-9-]+-api)['"]/;
|
|
4
|
-
const DECODER_IMPORT = /import\s*\{[^}]*\bauthDecoder\b[^}]*\}\s*from\s*['"](@cedarjs\/auth-[a-z0-9-]+-api)['"]/;
|
|
5
|
-
function detectServerAuth(graphqlSource) {
|
|
6
|
-
const factory = FACTORY_IMPORT.exec(graphqlSource);
|
|
7
|
-
if (factory) {
|
|
8
|
-
return { decoderPackage: factory[1], usesFactory: true };
|
|
9
|
-
}
|
|
10
|
-
const decoder = DECODER_IMPORT.exec(graphqlSource);
|
|
11
|
-
if (decoder) {
|
|
12
|
-
return { decoderPackage: decoder[1], usesFactory: false };
|
|
13
|
-
}
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
function importedBindings(source) {
|
|
17
|
-
const names = /* @__PURE__ */ new Set();
|
|
18
|
-
const statements = source.matchAll(
|
|
19
|
-
/^import\s+(type\s+)?([^;]*?)\s+from\s+['"][^'"]+['"]/gm
|
|
20
|
-
);
|
|
21
|
-
for (const [, typeOnly, clause] of statements) {
|
|
22
|
-
if (typeOnly) {
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
const braces = /\{([^}]*)\}/.exec(clause);
|
|
26
|
-
const defaultOrNamespace = clause.replace(/\{[^}]*\}/, "");
|
|
27
|
-
for (const part of defaultOrNamespace.split(",")) {
|
|
28
|
-
const local = part.replace(/^\s*\*\s+as\s+/, "").trim();
|
|
29
|
-
if (local) {
|
|
30
|
-
names.add(local);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
for (const specifier of braces?.[1].split(",") ?? []) {
|
|
34
|
-
const trimmed = specifier.trim();
|
|
35
|
-
if (!trimmed || trimmed.startsWith("type ")) {
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
const alias = / as (\w+)$/.exec(trimmed);
|
|
39
|
-
names.add(alias ? alias[1] : trimmed);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return names;
|
|
43
|
-
}
|
|
44
|
-
function hasBinding(source, name) {
|
|
45
|
-
const declared = new RegExp(
|
|
46
|
-
`^(?:export\\s+)?(?:const|let|var|function)\\s+${name}\\b`,
|
|
47
|
-
"m"
|
|
48
|
-
);
|
|
49
|
-
return importedBindings(source).has(name) || declared.test(source);
|
|
50
|
-
}
|
|
51
|
-
function uploadsServerImports(source, auth) {
|
|
52
|
-
const specs = [];
|
|
53
|
-
if (auth) {
|
|
54
|
-
if (auth.usesFactory) {
|
|
55
|
-
if (!hasBinding(source, "authDecoder")) {
|
|
56
|
-
specs.push({
|
|
57
|
-
names: ["createAuthDecoder"],
|
|
58
|
-
from: auth.decoderPackage
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
specs.push({ names: ["authDecoder"], from: auth.decoderPackage });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
specs.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
|
-
specs.push({ names: authNames, from: "src/lib/auth" });
|
|
75
|
-
}
|
|
76
|
-
specs.push({ names: ["db"], from: "src/lib/db" });
|
|
77
|
-
specs.push({ names: ["targets"], from: "src/lib/uploads" });
|
|
78
|
-
return specs.map((spec) => ({
|
|
79
|
-
...spec,
|
|
80
|
-
names: spec.names.filter((name) => !hasBinding(source, name))
|
|
81
|
-
})).filter((spec) => spec.names.length > 0).map((spec) => ({
|
|
82
|
-
line: `import { ${spec.names.join(", ")} } from '${spec.from}'`,
|
|
83
|
-
from: spec.from
|
|
84
|
-
}));
|
|
85
|
-
}
|
|
86
|
-
function findImports(lines) {
|
|
87
|
-
const imports = [];
|
|
88
|
-
for (let start = 0; start < lines.length; start++) {
|
|
89
|
-
if (!/^import\b/.test(lines[start])) {
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
const sideEffect = /^import\s*['"]([^'"]+)['"]/.exec(lines[start]);
|
|
93
|
-
if (sideEffect) {
|
|
94
|
-
imports.push({ start, end: start, from: sideEffect[1] });
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
for (let end = start; end < lines.length; end++) {
|
|
98
|
-
const from = /\bfrom\s*['"]([^'"]+)['"]/.exec(lines[end]);
|
|
99
|
-
if (from) {
|
|
100
|
-
imports.push({ start, end, from: from[1] });
|
|
101
|
-
start = end;
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return imports;
|
|
107
|
-
}
|
|
108
|
-
function importGroup(from) {
|
|
109
|
-
if (isBuiltin(from)) {
|
|
110
|
-
return 0;
|
|
111
|
-
}
|
|
112
|
-
if (from === "react") {
|
|
113
|
-
return 1;
|
|
114
|
-
}
|
|
115
|
-
if (from.startsWith("@cedarjs/")) {
|
|
116
|
-
return 3;
|
|
117
|
-
}
|
|
118
|
-
if (from.startsWith("src/")) {
|
|
119
|
-
return /^src\/[^/]+\/.+\.(?:sdl\.)?(?:js|ts)$/.test(from) ? 4 : 5;
|
|
120
|
-
}
|
|
121
|
-
if (from === ".." || from.startsWith("../")) {
|
|
122
|
-
return 6;
|
|
123
|
-
}
|
|
124
|
-
if (/^\.\/?(?:index(?:\.[jt]sx?)?)?$/.test(from)) {
|
|
125
|
-
return 8;
|
|
126
|
-
}
|
|
127
|
-
if (from.startsWith("./")) {
|
|
128
|
-
return 7;
|
|
129
|
-
}
|
|
130
|
-
return 2;
|
|
131
|
-
}
|
|
132
|
-
function compareSpecifiers(a, b) {
|
|
133
|
-
const segmentsA = a.toLowerCase().split("/");
|
|
134
|
-
const segmentsB = b.toLowerCase().split("/");
|
|
135
|
-
for (let i = 0; i < Math.min(segmentsA.length, segmentsB.length); i++) {
|
|
136
|
-
if (segmentsA[i] !== segmentsB[i]) {
|
|
137
|
-
return segmentsA[i] < segmentsB[i] ? -1 : 1;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return segmentsA.length - segmentsB.length;
|
|
141
|
-
}
|
|
142
|
-
function insertImport(lines, serverImport) {
|
|
143
|
-
const imports = findImports(lines);
|
|
144
|
-
const group = importGroup(serverImport.from);
|
|
145
|
-
const sameGroup = imports.filter((i) => importGroup(i.from) === group);
|
|
146
|
-
if (sameGroup.length > 0) {
|
|
147
|
-
const next = sameGroup.find(
|
|
148
|
-
(i) => compareSpecifiers(i.from, serverImport.from) > 0
|
|
149
|
-
);
|
|
150
|
-
const at2 = next ? next.start : sameGroup[sameGroup.length - 1].end + 1;
|
|
151
|
-
return [...lines.slice(0, at2), serverImport.line, ...lines.slice(at2)];
|
|
152
|
-
}
|
|
153
|
-
const earlier = imports.filter((i) => importGroup(i.from) < group);
|
|
154
|
-
if (earlier.length > 0) {
|
|
155
|
-
const at2 = Math.max(...earlier.map((i) => i.end)) + 1;
|
|
156
|
-
const inserted = ["", serverImport.line];
|
|
157
|
-
if (at2 < lines.length && lines[at2].trim() !== "") {
|
|
158
|
-
inserted.push("");
|
|
159
|
-
}
|
|
160
|
-
return [...lines.slice(0, at2), ...inserted, ...lines.slice(at2)];
|
|
161
|
-
}
|
|
162
|
-
const later = imports.find((i) => importGroup(i.from) > group);
|
|
163
|
-
const at = later ? later.start : 0;
|
|
164
|
-
return [...lines.slice(0, at), serverImport.line, "", ...lines.slice(at)];
|
|
165
|
-
}
|
|
166
|
-
function uploadsServerRegistration(source, auth) {
|
|
167
|
-
if (!auth) {
|
|
168
|
-
return ` await server.register(cedarUploadsPlugin, {
|
|
169
|
-
tokenSecret: process.env.UPLOAD_TOKEN_SECRET,
|
|
170
|
-
targets,
|
|
171
|
-
db,
|
|
172
|
-
// Once the app has auth, bind upload tokens to the logged-in user:
|
|
173
|
-
//
|
|
174
|
-
// authenticate: createUploadAuthenticator({ authDecoder, getCurrentUser }),
|
|
175
|
-
})
|
|
176
|
-
`;
|
|
177
|
-
}
|
|
178
|
-
const decoder = auth.usesFactory && !hasBinding(source, "authDecoder") ? " const authDecoder = createAuthDecoder(cookieName)\n\n" : "";
|
|
179
|
-
return `${decoder} await server.register(cedarUploadsPlugin, {
|
|
180
|
-
tokenSecret: process.env.UPLOAD_TOKEN_SECRET,
|
|
181
|
-
targets,
|
|
182
|
-
db,
|
|
183
|
-
// Binds upload tokens to the logged-in user through the same auth
|
|
184
|
-
// pipeline the GraphQL server uses
|
|
185
|
-
authenticate: createUploadAuthenticator({ authDecoder, getCurrentUser }),
|
|
186
|
-
})
|
|
187
|
-
`;
|
|
188
|
-
}
|
|
189
|
-
function hasUploadsPlugin(source) {
|
|
190
|
-
return /^[ \t]*(?:(?:await|void)\s+|(?:const|let|var)\s+\w+\s*=\s*)?[\w.]+\.register\(\s*cedarUploadsPlugin\b/m.test(
|
|
191
|
-
source
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
function addUploadsPlugin(source, { auth = null } = {}) {
|
|
195
|
-
if (hasUploadsPlugin(source)) {
|
|
196
|
-
return source;
|
|
197
|
-
}
|
|
198
|
-
const start = START_LINE.exec(source);
|
|
199
|
-
if (!start) {
|
|
200
|
-
throw new Error("CEDAR_UPLOADS_ERR_NO_START");
|
|
201
|
-
}
|
|
202
|
-
const withImports = uploadsServerImports(source, auth).reduce(insertImport, source.split("\n")).join("\n");
|
|
203
|
-
return withImports.replace(
|
|
204
|
-
START_LINE,
|
|
205
|
-
(line) => `${uploadsServerRegistration(source, auth)}
|
|
206
|
-
${line}`
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
export {
|
|
210
|
-
addUploadsPlugin,
|
|
211
|
-
detectServerAuth,
|
|
212
|
-
hasBinding,
|
|
213
|
-
hasUploadsPlugin,
|
|
214
|
-
importedBindings,
|
|
215
|
-
uploadsServerImports,
|
|
216
|
-
uploadsServerRegistration
|
|
217
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
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,79 +0,0 @@
|
|
|
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
|
-
`
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
acceptedContentType,
|
|
3
|
-
confirmUpload as confirmUploadRecord,
|
|
4
|
-
createPresignedUpload,
|
|
5
|
-
getUploadTokenPayload,
|
|
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
|
-
// Checked by what the bytes are, not the type the client claimed, and
|
|
75
|
-
// stored under the type returned
|
|
76
|
-
const data = Buffer.from(input.data, 'base64')
|
|
77
|
-
const mimeType = acceptedContentType(
|
|
78
|
-
data,
|
|
79
|
-
profile.allowedMimeTypes,
|
|
80
|
-
input.mimeType,
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
if (!mimeType) {
|
|
84
|
-
throw new UploadError(
|
|
85
|
-
'MIME_TYPE_NOT_ALLOWED',
|
|
86
|
-
`That file is not a type allowed for upload profile '${profile.name}'.`,
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return storeFile(target, {
|
|
91
|
-
db,
|
|
92
|
-
filename: input.filename,
|
|
93
|
-
mimeType,
|
|
94
|
-
data,
|
|
95
|
-
maxSize: profile.maxFileSize,
|
|
96
|
-
userId: context.currentUser ? String(context.currentUser.id) : undefined,
|
|
97
|
-
})
|
|
98
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
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
|
|
@@ -1,16 +0,0 @@
|
|
|
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
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { getPaths } from "@cedarjs/project-config";
|
|
5
|
-
function resolvePackage(fromFile, packageName) {
|
|
6
|
-
try {
|
|
7
|
-
const require2 = createRequire(fromFile);
|
|
8
|
-
const packageJsonPath = require2.resolve(`${packageName}/package.json`);
|
|
9
|
-
const packageJson = JSON.parse(
|
|
10
|
-
fs.readFileSync(packageJsonPath, "utf-8")
|
|
11
|
-
);
|
|
12
|
-
if (typeof packageJson !== "object" || packageJson === null || !("version" in packageJson) || typeof packageJson.version !== "string") {
|
|
13
|
-
return void 0;
|
|
14
|
-
}
|
|
15
|
-
return {
|
|
16
|
-
version: packageJson.version,
|
|
17
|
-
dir: path.dirname(packageJsonPath)
|
|
18
|
-
};
|
|
19
|
-
} catch {
|
|
20
|
-
return void 0;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function resolveViteVersions({
|
|
24
|
-
projectBase,
|
|
25
|
-
webBase
|
|
26
|
-
}) {
|
|
27
|
-
const vitest = resolvePackage(
|
|
28
|
-
path.join(projectBase, "package.json"),
|
|
29
|
-
"vitest"
|
|
30
|
-
);
|
|
31
|
-
const vitestVite = vitest ? resolvePackage(path.join(vitest.dir, "package.json"), "vite") : void 0;
|
|
32
|
-
const cedarVite = resolvePackage(
|
|
33
|
-
path.join(webBase, "package.json"),
|
|
34
|
-
"@cedarjs/vite"
|
|
35
|
-
);
|
|
36
|
-
const frameworkVite = cedarVite ? resolvePackage(path.join(cedarVite.dir, "package.json"), "vite") : void 0;
|
|
37
|
-
return { vitestVite, frameworkVite };
|
|
38
|
-
}
|
|
39
|
-
function getViteVersionMismatchMessage({
|
|
40
|
-
vitestVite,
|
|
41
|
-
frameworkVite
|
|
42
|
-
}) {
|
|
43
|
-
if (!vitestVite || !frameworkVite) {
|
|
44
|
-
return void 0;
|
|
45
|
-
}
|
|
46
|
-
if (vitestVite.version === frameworkVite.version) {
|
|
47
|
-
return void 0;
|
|
48
|
-
}
|
|
49
|
-
return `Vitest is using Vite ${vitestVite.version} from
|
|
50
|
-
${vitestVite.dir}
|
|
51
|
-
but CedarJS is built against Vite ${frameworkVite.version} from
|
|
52
|
-
${frameworkVite.dir}
|
|
53
|
-
|
|
54
|
-
The CedarJS Vite plugins only work with the Vite version they're built against, so web tests can't run while Vitest uses a different copy. This happens when the project doesn't pin \`vite\`, because Vitest accepts a wide range of Vite versions and installs the newest one.
|
|
55
|
-
|
|
56
|
-
Please add an override/resolution that pins vite to ${frameworkVite.version}, then reinstall your dependencies.`;
|
|
57
|
-
}
|
|
58
|
-
function assertSingleViteVersion() {
|
|
59
|
-
const cedarPaths = getPaths();
|
|
60
|
-
const message = getViteVersionMismatchMessage(
|
|
61
|
-
resolveViteVersions({
|
|
62
|
-
projectBase: cedarPaths.base,
|
|
63
|
-
webBase: cedarPaths.web.base
|
|
64
|
-
})
|
|
65
|
-
);
|
|
66
|
-
if (message) {
|
|
67
|
-
console.error(message);
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export {
|
|
72
|
-
assertSingleViteVersion,
|
|
73
|
-
getViteVersionMismatchMessage,
|
|
74
|
-
resolveViteVersions
|
|
75
|
-
};
|