@cedarjs/cli 5.0.6 → 5.0.7-next.219
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 +3 -1
- package/dist/commands/build/buildHandler.js +14 -6
- package/dist/commands/console.js +5 -3
- package/dist/commands/dev/devHandler.js +34 -4
- package/dist/commands/dev.js +3 -0
- package/dist/commands/experimental/setupOpentelemetryHandler.js +1 -1
- package/dist/commands/generate/job/jobHandler.js +5 -7
- package/dist/commands/generate/package/packageHandler.js +3 -6
- package/dist/commands/generate/scaffold/scaffoldHandler.js +73 -4
- package/dist/commands/generate/sdl/sdlHandler.js +9 -33
- package/dist/commands/generate/yargsHandlerHelpers.js +0 -6
- package/dist/commands/lint.js +1 -61
- package/dist/commands/prismaHandler.js +3 -6
- package/dist/commands/serve.js +21 -22
- package/dist/commands/serveBothHandler.js +4 -4
- package/dist/commands/setup/auth/auth.js +1 -1
- 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 +194 -0
- package/dist/commands/setup/deploy/helpers/index.js +9 -39
- package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +17 -5
- package/dist/commands/setup/deploy/providers/renderHandler.js +4 -20
- package/dist/commands/setup/deploy/templates/render.js +24 -14
- package/dist/commands/setup/docker/templates/Dockerfile.yarn +2 -5
- package/dist/commands/setup/docker/templates/docker-compose.dev.yml +1 -1
- package/dist/commands/setup/docker/templates/docker-compose.prod.yml +2 -5
- package/dist/commands/setup/graphql/features/fragments/appGqlConfigTransform.js +6 -3
- package/dist/commands/setup/neon/neonHandler.js +96 -254
- package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +0 -1
- package/dist/commands/setup.js +2 -1
- package/dist/lib/exec.js +5 -8
- package/dist/lib/index.js +22 -6
- package/dist/lib/updateCheck.js +34 -6
- package/dist/telemetry/resource.js +3 -8
- package/package.json +20 -21
- package/dist/commands/consoleHandler.js +0 -75
- /package/dist/commands/setup/{neon → database}/templates/db.ts.template +0 -0
package/README.md
CHANGED
|
@@ -238,12 +238,9 @@ export const builder = (yargs) => {
|
|
|
238
238
|
|
|
239
239
|
...
|
|
240
240
|
|
|
241
|
-
.option('
|
|
242
|
-
default:
|
|
243
|
-
description:
|
|
244
|
-
'Webpack Bundle Analyzer',
|
|
245
|
-
'https://github.com/webpack-contrib/webpack-bundle-analyzer'
|
|
246
|
-
)}`,
|
|
241
|
+
.option('prerender', {
|
|
242
|
+
default: true,
|
|
243
|
+
description: 'Prerender after building web',
|
|
247
244
|
type: 'boolean',
|
|
248
245
|
})
|
|
249
246
|
.option('verbose', {
|
|
@@ -258,11 +255,11 @@ export const builder = (yargs) => {
|
|
|
258
255
|
}
|
|
259
256
|
```
|
|
260
257
|
|
|
261
|
-
These two calls to `options` configure this command to have options `--
|
|
258
|
+
These two calls to `options` configure this command to have options `--prerender` and `--verbose`:
|
|
262
259
|
|
|
263
260
|
```terminal
|
|
264
|
-
yarn
|
|
265
|
-
yarn
|
|
261
|
+
yarn cedar build --no-prerender
|
|
262
|
+
yarn cedar build --verbose
|
|
266
263
|
```
|
|
267
264
|
|
|
268
265
|
For the full list of what properties you can use to compose the options object, see [options(key, [opt])](https://yargs.js.org/docs/#api-optionskey-opt).
|
|
@@ -280,8 +277,8 @@ While `build`'s `handler` is too long to reproduce here in full, to get the poin
|
|
|
280
277
|
|
|
281
278
|
export const handler = async ({
|
|
282
279
|
side = ['api', 'web'],
|
|
280
|
+
prerender = true,
|
|
283
281
|
verbose = false,
|
|
284
|
-
stats = false,
|
|
285
282
|
}) => {
|
|
286
283
|
|
|
287
284
|
...
|
package/dist/cfw.js
CHANGED
|
@@ -40,6 +40,8 @@ try {
|
|
|
40
40
|
// CEDAR_DISABLE_TELEMETRY
|
|
41
41
|
env: { CEDAR_CWD: projectPath }
|
|
42
42
|
});
|
|
43
|
-
} catch {
|
|
43
|
+
} catch (e) {
|
|
44
44
|
console.log();
|
|
45
|
+
const exitCode = e && typeof e === "object" && "exitCode" in e && typeof e.exitCode === "number" ? e.exitCode : 1;
|
|
46
|
+
process.exit(exitCode);
|
|
45
47
|
}
|
|
@@ -181,10 +181,14 @@ Run ` + c.info(formatCedarCommand(["build"])) + " (without specifying a workspac
|
|
|
181
181
|
"@cedarjs/vite/bins/cedar-vite-build.mjs"
|
|
182
182
|
);
|
|
183
183
|
await execa(
|
|
184
|
-
|
|
184
|
+
"node",
|
|
185
|
+
[
|
|
186
|
+
buildBinPath,
|
|
187
|
+
`--webDir=${cedarPaths.web.base}`,
|
|
188
|
+
`--verbose=${verbose}`
|
|
189
|
+
],
|
|
185
190
|
{
|
|
186
191
|
stdio: verbose ? "inherit" : "pipe",
|
|
187
|
-
shell: true,
|
|
188
192
|
cwd: cedarPaths.web.base
|
|
189
193
|
}
|
|
190
194
|
);
|
|
@@ -223,12 +227,16 @@ Run ` + c.info(formatCedarCommand(["build"])) + " (without specifying a workspac
|
|
|
223
227
|
"@cedarjs/vite/bins/cedar-vite-build.mjs"
|
|
224
228
|
);
|
|
225
229
|
await execa(
|
|
226
|
-
|
|
230
|
+
"node",
|
|
231
|
+
[
|
|
232
|
+
buildBinPath,
|
|
233
|
+
`--webDir=${cedarPaths.web.base}`,
|
|
234
|
+
`--verbose=${verbose}`
|
|
235
|
+
],
|
|
227
236
|
{
|
|
228
237
|
stdio: verbose ? "inherit" : "pipe",
|
|
229
|
-
|
|
230
|
-
//
|
|
231
|
-
// cedar-vite-build binary
|
|
238
|
+
// `cwd` makes postcss/tailwind config resolution work (see the
|
|
239
|
+
// @NOTE above)
|
|
232
240
|
// It won't change process.cwd for anything else here, in this
|
|
233
241
|
// process
|
|
234
242
|
cwd: cedarPaths.web.base
|
package/dist/commands/console.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const command = "console";
|
|
2
2
|
const aliases = ["c"];
|
|
3
|
-
const description = "Launch an interactive
|
|
3
|
+
const description = "Launch an interactive Cedar shell";
|
|
4
4
|
const handler = async () => {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
console.log(
|
|
6
|
+
"`cedar console` has been removed from the Cedar CLI.\nRun it as a standalone tool instead:\n\n yarn dlx @cedarjs/console\n npx @cedarjs/console\n pnpm dlx @cedarjs/console\n"
|
|
7
|
+
);
|
|
8
|
+
process.exit(1);
|
|
7
9
|
};
|
|
8
10
|
export {
|
|
9
11
|
aliases,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { Writable } from "node:stream";
|
|
4
5
|
import concurrently from "concurrently";
|
|
@@ -7,6 +8,7 @@ import { formatRunBinCommand } from "@cedarjs/cli-helpers/packageManager/display
|
|
|
7
8
|
import { shutdownPort } from "@cedarjs/internal/dist/dev";
|
|
8
9
|
import { generateGqlormArtifacts } from "@cedarjs/internal/dist/generate/gqlormSchema";
|
|
9
10
|
import { getConfig, getConfigPath } from "@cedarjs/project-config";
|
|
11
|
+
import { getPackageManager } from "@cedarjs/project-config/packageManager";
|
|
10
12
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
11
13
|
import { exitWithError } from "../../lib/exit.js";
|
|
12
14
|
import { generatePrismaClient } from "../../lib/generatePrismaClient.js";
|
|
@@ -15,13 +17,38 @@ import { getFreePort } from "../../lib/ports.js";
|
|
|
15
17
|
import { serverFileExists } from "../../lib/project.js";
|
|
16
18
|
import { getApiDebugFlag } from "./apiDebugFlag.js";
|
|
17
19
|
import { getPackageWatchCommands } from "./packageWatchCommands.js";
|
|
20
|
+
const createdRequire = createRequire(import.meta.url);
|
|
21
|
+
function formatViteDevBinCommand(binName, extraNodeArgs = "") {
|
|
22
|
+
let vitePackageJsonPath;
|
|
23
|
+
let vitePackageJson;
|
|
24
|
+
try {
|
|
25
|
+
vitePackageJsonPath = createdRequire.resolve("@cedarjs/vite/package.json");
|
|
26
|
+
vitePackageJson = createdRequire("@cedarjs/vite/package.json");
|
|
27
|
+
} catch (e) {
|
|
28
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Could not resolve @cedarjs/vite, which the dev server needs to run. Is it installed? (${message})`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const binRelativePath = vitePackageJson.bin?.[binName];
|
|
34
|
+
if (!binRelativePath) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`@cedarjs/vite does not declare a "${binName}" bin. This is a bug in CedarJS.`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const binPath = path.join(path.dirname(vitePackageJsonPath), binRelativePath);
|
|
40
|
+
const nodeLauncher = getPackageManager() === "yarn" ? "yarn node" : "node";
|
|
41
|
+
const flags = extraNodeArgs ? `${extraNodeArgs} ` : "";
|
|
42
|
+
return `${nodeLauncher} ${flags}"${binPath}"`;
|
|
43
|
+
}
|
|
18
44
|
const handler = async ({
|
|
19
45
|
workspace = ["api", "web", "packages/*"],
|
|
20
46
|
forward = "",
|
|
21
47
|
generate = true,
|
|
22
48
|
apiDebugPort,
|
|
23
49
|
debugBrk,
|
|
24
|
-
ud = false
|
|
50
|
+
ud = false,
|
|
51
|
+
nodeArgs = ""
|
|
25
52
|
}) => {
|
|
26
53
|
recordTelemetryAttributes({
|
|
27
54
|
command: "dev",
|
|
@@ -174,7 +201,7 @@ const handler = async ({
|
|
|
174
201
|
return null;
|
|
175
202
|
}
|
|
176
203
|
return [
|
|
177
|
-
|
|
204
|
+
formatViteDevBinCommand("cedar-unified-dev", nodeArgs),
|
|
178
205
|
` --port ${webAvailablePort}`,
|
|
179
206
|
` --apiPort ${apiAvailablePort}`,
|
|
180
207
|
getApiDebugFlag(apiDebugPort, apiAvailablePort),
|
|
@@ -230,13 +257,16 @@ const handler = async ({
|
|
|
230
257
|
});
|
|
231
258
|
}
|
|
232
259
|
if (workspace.includes("web")) {
|
|
233
|
-
let webCommand = `${
|
|
260
|
+
let webCommand = `${formatViteDevBinCommand("cedar-vite-dev", nodeArgs)} ${forward}`;
|
|
234
261
|
if (streamingSsrEnabled) {
|
|
235
|
-
webCommand = `${
|
|
262
|
+
webCommand = `${formatViteDevBinCommand("cedar-dev-fe", nodeArgs)} ${forward}`;
|
|
236
263
|
}
|
|
237
264
|
jobs.push({
|
|
238
265
|
name: "web",
|
|
239
266
|
command: webCommand,
|
|
267
|
+
env: {
|
|
268
|
+
NODE_ENV: "development"
|
|
269
|
+
},
|
|
240
270
|
prefixColor: "blue",
|
|
241
271
|
cwd: cedarPaths.web.base,
|
|
242
272
|
runWhen: () => fs.existsSync(cedarPaths.web.src)
|
package/dist/commands/dev.js
CHANGED
|
@@ -31,6 +31,9 @@ const builder = (yargs) => {
|
|
|
31
31
|
type: "boolean",
|
|
32
32
|
default: false,
|
|
33
33
|
description: "Use the unified Vite dev server that handles both web and API in a single process (experimental)."
|
|
34
|
+
}).option("nodeArgs", {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: 'CLI args to pass to the node process running the web dev server, for example: `--node-args="--inspect --max-old-space-size=8192"`.'
|
|
34
37
|
}).middleware(() => {
|
|
35
38
|
const check = checkNodeVersion();
|
|
36
39
|
if (check.ok) {
|
|
@@ -114,7 +114,7 @@ const handler = async ({
|
|
|
114
114
|
},
|
|
115
115
|
task: (_ctx, task) => {
|
|
116
116
|
task.output = [
|
|
117
|
-
"Please add the following to your '
|
|
117
|
+
"Please add the following to your 'cedarFastifyGraphQLServer' plugin options to enable OTel for your graphql",
|
|
118
118
|
"openTelemetryOptions: {",
|
|
119
119
|
" resolvers: true,",
|
|
120
120
|
" result: true,",
|
|
@@ -97,13 +97,11 @@ const handler = async ({
|
|
|
97
97
|
{
|
|
98
98
|
title: "Cleaning up...",
|
|
99
99
|
task: () => {
|
|
100
|
-
runBinSync(
|
|
101
|
-
"
|
|
102
|
-
"--
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
...Object.keys(jobFiles)
|
|
106
|
-
]);
|
|
100
|
+
runBinSync(
|
|
101
|
+
"eslint",
|
|
102
|
+
["--fix", `${getPaths().api.jobsConfig}`, ...Object.keys(jobFiles)],
|
|
103
|
+
{ cwd: getPaths().base }
|
|
104
|
+
);
|
|
107
105
|
}
|
|
108
106
|
}
|
|
109
107
|
],
|
|
@@ -407,12 +407,9 @@ const handler = async ({
|
|
|
407
407
|
{
|
|
408
408
|
title: "Cleaning up...",
|
|
409
409
|
task: () => {
|
|
410
|
-
runBinSync("eslint", [
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
`${getPaths().base}/node_modules/@cedarjs/eslint-config/index.js`,
|
|
414
|
-
...Object.keys(packageFiles)
|
|
415
|
-
]);
|
|
410
|
+
runBinSync("eslint", ["--fix", ...Object.keys(packageFiles)], {
|
|
411
|
+
cwd: getPaths().base
|
|
412
|
+
});
|
|
416
413
|
}
|
|
417
414
|
}
|
|
418
415
|
],
|
|
@@ -42,6 +42,7 @@ import { files as serviceFiles } from "../service/serviceHandler.js";
|
|
|
42
42
|
import { customOrDefaultTemplatePath } from "../yargsHandlerHelpers.js";
|
|
43
43
|
const SKIPPABLE_ASSETS = ["scaffold.css"];
|
|
44
44
|
const PACKAGE_SET = "Set";
|
|
45
|
+
const PACKAGE_PRIVATE_SET = "PrivateSet";
|
|
45
46
|
const getIdType = (model) => {
|
|
46
47
|
return model.fields.find((field) => field.isId)?.type;
|
|
47
48
|
};
|
|
@@ -512,6 +513,65 @@ const addHelperPackages = async (task) => {
|
|
|
512
513
|
await removeWorkspacePackages("web", ["humanize-string"]);
|
|
513
514
|
});
|
|
514
515
|
};
|
|
516
|
+
const isAuthSetup = () => {
|
|
517
|
+
const extensions = ["ts", "js", "tsx", "jsx"];
|
|
518
|
+
return extensions.some(
|
|
519
|
+
(ext) => fs.existsSync(path.join(getPaths().web.src, "auth." + ext))
|
|
520
|
+
);
|
|
521
|
+
};
|
|
522
|
+
const ROUTE_TAG_RE = /<Route\s+([^>]*?)\/?>/g;
|
|
523
|
+
const extractRouteAttr = (tagAttrs, attrName) => tagAttrs.match(new RegExp(`\\b${attrName}=["']([^"']+)["']`))?.[1];
|
|
524
|
+
const getRoutesFileContent = () => {
|
|
525
|
+
const routesPath = getPaths().web.routes;
|
|
526
|
+
if (!fs.existsSync(routesPath)) {
|
|
527
|
+
return void 0;
|
|
528
|
+
}
|
|
529
|
+
return readFile(routesPath).toString();
|
|
530
|
+
};
|
|
531
|
+
const hasLoginRoute = () => {
|
|
532
|
+
const content = getRoutesFileContent();
|
|
533
|
+
if (!content) {
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
return Array.from(content.matchAll(ROUTE_TAG_RE)).some(
|
|
537
|
+
([, attrs]) => extractRouteAttr(attrs, "name") === "login"
|
|
538
|
+
);
|
|
539
|
+
};
|
|
540
|
+
const findUnprotectedLandingPageRouteName = () => {
|
|
541
|
+
const content = getRoutesFileContent();
|
|
542
|
+
if (!content) {
|
|
543
|
+
return void 0;
|
|
544
|
+
}
|
|
545
|
+
const privateSetRanges = Array.from(
|
|
546
|
+
content.matchAll(/<PrivateSet\b[^>]*>([\s\S]*?)<\/PrivateSet>/g)
|
|
547
|
+
).map((match) => ({
|
|
548
|
+
start: match.index ?? 0,
|
|
549
|
+
end: (match.index ?? 0) + match[0].length
|
|
550
|
+
}));
|
|
551
|
+
for (const match of content.matchAll(ROUTE_TAG_RE)) {
|
|
552
|
+
const [, attrs] = match;
|
|
553
|
+
if (extractRouteAttr(attrs, "path") !== "/") {
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
const tagStart = match.index ?? 0;
|
|
557
|
+
const isProtected = privateSetRanges.some(
|
|
558
|
+
(range) => tagStart >= range.start && tagStart < range.end
|
|
559
|
+
);
|
|
560
|
+
if (!isProtected) {
|
|
561
|
+
return extractRouteAttr(attrs, "name");
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return void 0;
|
|
565
|
+
};
|
|
566
|
+
const getUnauthenticatedRedirectRoute = () => {
|
|
567
|
+
if (!isAuthSetup()) {
|
|
568
|
+
return void 0;
|
|
569
|
+
}
|
|
570
|
+
if (hasLoginRoute()) {
|
|
571
|
+
return "login";
|
|
572
|
+
}
|
|
573
|
+
return findUnprotectedLandingPageRouteName();
|
|
574
|
+
};
|
|
515
575
|
const addSetImport = (task) => {
|
|
516
576
|
const routesPath = getPaths().web.routes;
|
|
517
577
|
const routesContent = readFile(routesPath).toString();
|
|
@@ -525,15 +585,19 @@ const addSetImport = (task) => {
|
|
|
525
585
|
return void 0;
|
|
526
586
|
}
|
|
527
587
|
const routerImports = importContent.replace(/\s/g, "").split(",");
|
|
528
|
-
|
|
588
|
+
const namesToImport = [
|
|
589
|
+
PACKAGE_SET,
|
|
590
|
+
...getUnauthenticatedRedirectRoute() ? [PACKAGE_PRIVATE_SET] : []
|
|
591
|
+
].filter((name) => !routerImports.includes(name));
|
|
592
|
+
if (!namesToImport.length) {
|
|
529
593
|
return "Skipping Set import";
|
|
530
594
|
}
|
|
531
595
|
const newRoutesContent = routesContent.replace(
|
|
532
596
|
cedarRouterImport,
|
|
533
|
-
importStart + spacing +
|
|
597
|
+
importStart + spacing + namesToImport.join("," + spacing) + `,` + spacing + importContent + importEnd
|
|
534
598
|
);
|
|
535
599
|
writeFile(routesPath, newRoutesContent, { overwriteExisting: true });
|
|
536
|
-
return
|
|
600
|
+
return `Added ${namesToImport.join(", ")} import to Routes.{jsx,tsx}`;
|
|
537
601
|
};
|
|
538
602
|
const addScaffoldSetToRouter = async (model, scaffoldPath) => {
|
|
539
603
|
const templateNames = getTemplateStrings(model, scaffoldPath);
|
|
@@ -542,10 +606,12 @@ const addScaffoldSetToRouter = async (model, scaffoldPath) => {
|
|
|
542
606
|
const titleTo = templateNames.pluralRouteName;
|
|
543
607
|
const buttonLabel = `New ${nameVars.singularPascalName}`;
|
|
544
608
|
const buttonTo = templateNames.newRouteName;
|
|
609
|
+
const unauthenticatedRoute = getUnauthenticatedRedirectRoute();
|
|
545
610
|
return addRoutesToRouterTask(
|
|
546
611
|
await routes({ model, path: scaffoldPath }),
|
|
547
612
|
"ScaffoldLayout",
|
|
548
|
-
{ title, titleTo, buttonLabel, buttonTo }
|
|
613
|
+
{ title, titleTo, buttonLabel, buttonTo },
|
|
614
|
+
unauthenticatedRoute ? { unauthenticated: unauthenticatedRoute } : void 0
|
|
549
615
|
);
|
|
550
616
|
};
|
|
551
617
|
const tasks = ({
|
|
@@ -664,7 +730,10 @@ const splitPathAndModel = (pathSlashModel) => {
|
|
|
664
730
|
};
|
|
665
731
|
export {
|
|
666
732
|
files,
|
|
733
|
+
getUnauthenticatedRedirectRoute,
|
|
667
734
|
handler,
|
|
735
|
+
hasLoginRoute,
|
|
736
|
+
isAuthSetup,
|
|
668
737
|
routes,
|
|
669
738
|
shouldUseTailwindCSS,
|
|
670
739
|
splitPathAndModel,
|
|
@@ -46,15 +46,8 @@ const addFieldGraphQLComment = (field, str) => {
|
|
|
46
46
|
const modelFieldToSDL = ({
|
|
47
47
|
field,
|
|
48
48
|
required = true,
|
|
49
|
-
types = {},
|
|
50
49
|
docs = false
|
|
51
50
|
}) => {
|
|
52
|
-
if (Object.entries(types).length && field.kind === "object") {
|
|
53
|
-
const resolvedType = idType(types[field.type]);
|
|
54
|
-
if (typeof resolvedType === "string") {
|
|
55
|
-
field.type = resolvedType;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
51
|
const prismaTypeToGraphqlType = {
|
|
59
52
|
Json: "JSON",
|
|
60
53
|
Decimal: "Float",
|
|
@@ -73,7 +66,7 @@ const modelFieldToSDL = ({
|
|
|
73
66
|
const querySDL = (model, docs = false) => {
|
|
74
67
|
return model.fields.map((field) => modelFieldToSDL({ field, docs }));
|
|
75
68
|
};
|
|
76
|
-
const inputSDL = (model, required,
|
|
69
|
+
const inputSDL = (model, required, docs = false) => {
|
|
77
70
|
const ignoredFields = DEFAULT_IGNORE_FIELDS_FOR_INPUT;
|
|
78
71
|
return model.fields.filter((field) => {
|
|
79
72
|
const idField = model.fields.find((field2) => field2.isId);
|
|
@@ -81,21 +74,19 @@ const inputSDL = (model, required, types = {}, docs = false) => {
|
|
|
81
74
|
ignoredFields.push(idField.name);
|
|
82
75
|
}
|
|
83
76
|
return !ignoredFields.includes(field.name) && field.kind !== "object";
|
|
84
|
-
}).map((field) => modelFieldToSDL({ field, required,
|
|
77
|
+
}).map((field) => modelFieldToSDL({ field, required, docs }));
|
|
85
78
|
};
|
|
86
79
|
function idInputSDL(idType2, docs) {
|
|
87
80
|
if (!Array.isArray(idType2)) {
|
|
88
81
|
return [];
|
|
89
82
|
}
|
|
90
|
-
return idType2.map(
|
|
91
|
-
(field) => modelFieldToSDL({ field, required: true, types: {}, docs })
|
|
92
|
-
);
|
|
83
|
+
return idType2.map((field) => modelFieldToSDL({ field, required: true, docs }));
|
|
93
84
|
}
|
|
94
|
-
const createInputSDL = (model,
|
|
95
|
-
return inputSDL(model, true,
|
|
85
|
+
const createInputSDL = (model, docs = false) => {
|
|
86
|
+
return inputSDL(model, true, docs);
|
|
96
87
|
};
|
|
97
|
-
const updateInputSDL = (model,
|
|
98
|
-
return inputSDL(model, false,
|
|
88
|
+
const updateInputSDL = (model, docs = false) => {
|
|
89
|
+
return inputSDL(model, false, docs);
|
|
99
90
|
};
|
|
100
91
|
function idType(model, crud) {
|
|
101
92
|
if (!crud || !model) {
|
|
@@ -131,21 +122,6 @@ const sdlFromSchemaModel = async (name, crud, docs = false) => {
|
|
|
131
122
|
);
|
|
132
123
|
}
|
|
133
124
|
const model = schemaResult;
|
|
134
|
-
const resolvedTypes = await Promise.all(
|
|
135
|
-
model.fields.filter((field) => field.kind === "object").map(async (field) => {
|
|
136
|
-
const fieldModel = await getSchema(field.type);
|
|
137
|
-
return fieldModel && "fields" in fieldModel ? fieldModel : void 0;
|
|
138
|
-
})
|
|
139
|
-
);
|
|
140
|
-
const types = resolvedTypes.reduce(
|
|
141
|
-
(acc, cur) => {
|
|
142
|
-
if (!cur) {
|
|
143
|
-
return acc;
|
|
144
|
-
}
|
|
145
|
-
return { ...acc, [cur.name]: cur };
|
|
146
|
-
},
|
|
147
|
-
{}
|
|
148
|
-
);
|
|
149
125
|
const enums = (await Promise.all(
|
|
150
126
|
model.fields.filter((field) => field.kind === "enum").map(async (field) => {
|
|
151
127
|
const enumDef = await getEnum(field.type);
|
|
@@ -159,8 +135,8 @@ const sdlFromSchemaModel = async (name, crud, docs = false) => {
|
|
|
159
135
|
modelName,
|
|
160
136
|
modelDescription,
|
|
161
137
|
query: querySDL(model, docs).join("\n "),
|
|
162
|
-
createInput: createInputSDL(model,
|
|
163
|
-
updateInput: updateInputSDL(model,
|
|
138
|
+
createInput: createInputSDL(model, docs).join("\n "),
|
|
139
|
+
updateInput: updateInputSDL(model, docs).join("\n "),
|
|
164
140
|
idInput: idInputSDL(idTypeRes, docs).join("\n "),
|
|
165
141
|
idType: idType(model, crud),
|
|
166
142
|
idName: idName(model, crud),
|
|
@@ -30,14 +30,8 @@ const customOrDefaultTemplatePath = ({
|
|
|
30
30
|
generator,
|
|
31
31
|
templatePath
|
|
32
32
|
);
|
|
33
|
-
const deprecatedCustomPath = getPaths()[side].generators ? path.join(getPaths()[side].generators, generator, templatePath) : void 0;
|
|
34
33
|
if (fs.existsSync(customPath)) {
|
|
35
34
|
return customPath;
|
|
36
|
-
} else if (deprecatedCustomPath && fs.existsSync(deprecatedCustomPath)) {
|
|
37
|
-
console.log(
|
|
38
|
-
`Having generator templates in ${getPaths()[side].generators} has been deprecated. Please move them to ${getPaths().generatorTemplates}.`
|
|
39
|
-
);
|
|
40
|
-
return deprecatedCustomPath;
|
|
41
35
|
} else {
|
|
42
36
|
return defaultPath;
|
|
43
37
|
}
|
package/dist/commands/lint.js
CHANGED
|
@@ -1,63 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
2
|
import { terminalLink } from "termi-link";
|
|
4
3
|
import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
|
|
5
4
|
import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
|
|
6
|
-
import { getPaths
|
|
7
|
-
function detectLegacyEslintConfig() {
|
|
8
|
-
const projectRoot = getPaths().base;
|
|
9
|
-
const legacyConfigFiles = [
|
|
10
|
-
".eslintrc.js",
|
|
11
|
-
".eslintrc.cjs",
|
|
12
|
-
".eslintrc.json",
|
|
13
|
-
".eslintrc.yaml",
|
|
14
|
-
".eslintrc.yml"
|
|
15
|
-
];
|
|
16
|
-
const foundLegacyFiles = [];
|
|
17
|
-
for (const configFile of legacyConfigFiles) {
|
|
18
|
-
if (fs.existsSync(path.join(projectRoot, configFile))) {
|
|
19
|
-
foundLegacyFiles.push(configFile);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
23
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
24
|
-
try {
|
|
25
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
26
|
-
if (packageJson.eslintConfig) {
|
|
27
|
-
foundLegacyFiles.push("package.json (eslintConfig field)");
|
|
28
|
-
}
|
|
29
|
-
if (packageJson.eslint) {
|
|
30
|
-
foundLegacyFiles.push("package.json (eslint field)");
|
|
31
|
-
}
|
|
32
|
-
} catch {
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return foundLegacyFiles;
|
|
36
|
-
}
|
|
37
|
-
function showLegacyEslintDeprecationWarning(legacyFiles) {
|
|
38
|
-
console.warn("");
|
|
39
|
-
console.warn("\u26A0\uFE0F DEPRECATION WARNING: Legacy ESLint Configuration Detected");
|
|
40
|
-
console.warn("");
|
|
41
|
-
console.warn(" The following legacy ESLint configuration files were found:");
|
|
42
|
-
legacyFiles.forEach((file) => {
|
|
43
|
-
console.warn(` - ${file}`);
|
|
44
|
-
});
|
|
45
|
-
console.warn("");
|
|
46
|
-
console.warn(
|
|
47
|
-
" Cedar has migrated to ESLint flat config format. Legacy configurations"
|
|
48
|
-
);
|
|
49
|
-
console.warn(
|
|
50
|
-
" still work but are deprecated and will be removed in a future version."
|
|
51
|
-
);
|
|
52
|
-
console.warn("");
|
|
53
|
-
console.warn(" To migrate to the new format:");
|
|
54
|
-
console.warn(" 1. Remove the legacy config file(s) listed above");
|
|
55
|
-
console.warn(" 2. Create an eslint.config.mjs");
|
|
56
|
-
console.warn(" 3. Use the flat config format with @cedarjs/eslint-config");
|
|
57
|
-
console.warn("");
|
|
58
|
-
console.warn(" See more here: https://github.com/cedarjs/cedar/pull/629");
|
|
59
|
-
console.warn("");
|
|
60
|
-
}
|
|
5
|
+
import { getPaths } from "@cedarjs/project-config";
|
|
61
6
|
const command = "lint [paths..]";
|
|
62
7
|
const description = "Lint your files";
|
|
63
8
|
const builder = (yargs) => {
|
|
@@ -86,11 +31,6 @@ const handler = async ({
|
|
|
86
31
|
format = "stylish"
|
|
87
32
|
}) => {
|
|
88
33
|
recordTelemetryAttributes({ command: "lint", fix, format });
|
|
89
|
-
const config = getConfig();
|
|
90
|
-
const legacyConfigFiles = detectLegacyEslintConfig();
|
|
91
|
-
if (legacyConfigFiles.length > 0 && config instanceof Object && "eslintLegacyConfigWarning" in config && config.eslintLegacyConfigWarning) {
|
|
92
|
-
showLegacyEslintDeprecationWarning(legacyConfigFiles);
|
|
93
|
-
}
|
|
94
34
|
try {
|
|
95
35
|
const sbPath = getPaths().web.storybook;
|
|
96
36
|
const eslintArgs = [
|
|
@@ -49,18 +49,15 @@ const handler = async ({
|
|
|
49
49
|
for (const [name, value] of Object.entries(options)) {
|
|
50
50
|
args.push(name.length > 1 ? `--${name}` : `-${name}`);
|
|
51
51
|
if (typeof value === "string") {
|
|
52
|
-
|
|
53
|
-
args.push(`"${value}"`);
|
|
54
|
-
} else {
|
|
55
|
-
args.push(value);
|
|
56
|
-
}
|
|
52
|
+
args.push(value);
|
|
57
53
|
} else if (typeof value === "number") {
|
|
58
54
|
args.push(String(value));
|
|
59
55
|
}
|
|
60
56
|
}
|
|
57
|
+
const displayCommand = args.map((arg) => arg.includes(" ") ? `"${arg}"` : arg).join(" ");
|
|
61
58
|
console.log();
|
|
62
59
|
console.log(c.note("Running Prisma CLI..."));
|
|
63
|
-
console.log(c.underline(`$ <pm exec> prisma ${
|
|
60
|
+
console.log(c.underline(`$ <pm exec> prisma ${displayCommand}`));
|
|
64
61
|
console.log();
|
|
65
62
|
try {
|
|
66
63
|
runTransitiveBinSync("prisma", args, {
|
package/dist/commands/serve.js
CHANGED
|
@@ -6,11 +6,18 @@ import { terminalLink } from "termi-link";
|
|
|
6
6
|
import * as apiServerCLIConfig from "@cedarjs/api-server/apiCliConfig";
|
|
7
7
|
import * as bothServerCLIConfig from "@cedarjs/api-server/bothCliConfig";
|
|
8
8
|
import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
|
|
9
|
-
import { projectIsEsm } from "@cedarjs/project-config";
|
|
10
9
|
import * as webServerCLIConfig from "@cedarjs/web-server";
|
|
11
10
|
import { getPaths, getConfig } from "../lib/index.js";
|
|
12
11
|
import { serverFileExists } from "../lib/project.js";
|
|
13
12
|
import { webSsrServerHandler } from "./serveWebHandler.js";
|
|
13
|
+
function refuseServerFileUnderUD() {
|
|
14
|
+
console.error(
|
|
15
|
+
c.error(
|
|
16
|
+
"\n api/src/server.ts was detected, but a custom server file is not supported with --ud. It is a Fastify concept \u2014 anything registered there (Realtime, custom plugins, custom middleware) would silently be skipped if serving continued.\n"
|
|
17
|
+
)
|
|
18
|
+
);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
14
21
|
function resolveUDEntryPath() {
|
|
15
22
|
const base = path.join(getPaths().api.dist, "ud", "index");
|
|
16
23
|
for (const ext of [".mjs", ".js"]) {
|
|
@@ -91,17 +98,13 @@ const builder = async (yargs) => {
|
|
|
91
98
|
process.exit(1);
|
|
92
99
|
}
|
|
93
100
|
if (serverFileExists()) {
|
|
94
|
-
|
|
95
|
-
c.warning(
|
|
96
|
-
"\n Note: api/src/server.ts was detected. This file is a Fastify concept and will be ignored when using --ud. You are testing the experimental UD support, so the behavior will not match your production Fastify setup.\n"
|
|
97
|
-
)
|
|
98
|
-
);
|
|
101
|
+
refuseServerFileUnderUD();
|
|
99
102
|
}
|
|
100
103
|
const { getAPIHost, getAPIPort, getWebHost, getWebPort } = await import("@cedarjs/api-server/cliHelpers");
|
|
101
104
|
const apiPort = argv.apiPort ?? getAPIPort();
|
|
102
105
|
const apiHost = argv.apiHost ?? getAPIHost();
|
|
103
|
-
const webPort = argv.webPort ?? getWebPort();
|
|
104
|
-
const webHost = argv.webHost ?? getWebHost();
|
|
106
|
+
const webPort = argv.webPort ?? getWebPort({ isPublicSide: true });
|
|
107
|
+
const webHost = argv.webHost ?? getWebHost({ isPublicSide: true });
|
|
105
108
|
const apiRootPath = argv.apiRootPath ?? "/";
|
|
106
109
|
const apiTarget = `http://${apiHost.includes(":") ? `[${apiHost}]` : apiHost}:${apiPort}`;
|
|
107
110
|
const { serveStatic } = await import("srvx/static");
|
|
@@ -162,12 +165,7 @@ const builder = async (yargs) => {
|
|
|
162
165
|
const serveBothHandlers = await import("./serveBothHandler.js");
|
|
163
166
|
await serveBothHandlers.bothSsrRscServerHandler(argv, rscEnabled);
|
|
164
167
|
} else {
|
|
165
|
-
|
|
166
|
-
const { handler } = await import("@cedarjs/api-server/cjs/bothCliConfigHandler");
|
|
167
|
-
await handler(argv);
|
|
168
|
-
} else {
|
|
169
|
-
await bothServerCLIConfig.handler(argv);
|
|
170
|
-
}
|
|
168
|
+
await bothServerCLIConfig.handler(argv);
|
|
171
169
|
}
|
|
172
170
|
}
|
|
173
171
|
}).command({
|
|
@@ -193,7 +191,15 @@ const builder = async (yargs) => {
|
|
|
193
191
|
socket: argv.socket,
|
|
194
192
|
apiRootPath: argv.apiRootPath
|
|
195
193
|
});
|
|
194
|
+
const { getAPIHost, getAPIPort } = await import("@cedarjs/api-server/cliHelpers");
|
|
195
|
+
const apiPort = argv.port ?? getAPIPort({ isPublicSide: true });
|
|
196
|
+
const apiHost = argv.host ?? getAPIHost({ isPublicSide: true });
|
|
197
|
+
argv.port = apiPort;
|
|
198
|
+
argv.host = apiHost;
|
|
196
199
|
if (argv.ud) {
|
|
200
|
+
if (serverFileExists()) {
|
|
201
|
+
refuseServerFileUnderUD();
|
|
202
|
+
}
|
|
197
203
|
const udEntryPath = resolveUDEntryPath();
|
|
198
204
|
if (!udEntryPath) {
|
|
199
205
|
console.error(
|
|
@@ -203,8 +209,6 @@ const builder = async (yargs) => {
|
|
|
203
209
|
);
|
|
204
210
|
process.exit(1);
|
|
205
211
|
}
|
|
206
|
-
const apiPort = argv.port ?? parseInt(process.env.PORT ?? "8911", 10);
|
|
207
|
-
const apiHost = argv.host ?? process.env.HOST ?? "localhost";
|
|
208
212
|
process.stdout.write(
|
|
209
213
|
`API server starting at http://${apiHost}:${apiPort}...`
|
|
210
214
|
);
|
|
@@ -219,12 +223,7 @@ const builder = async (yargs) => {
|
|
|
219
223
|
const { apiServerFileHandler } = await import("./serveApiHandler.js");
|
|
220
224
|
await apiServerFileHandler(argv);
|
|
221
225
|
} else {
|
|
222
|
-
|
|
223
|
-
const { handler } = await import("@cedarjs/api-server/cjs/apiCliConfigHandler");
|
|
224
|
-
await handler(argv);
|
|
225
|
-
} else {
|
|
226
|
-
await apiServerCLIConfig.handler(argv);
|
|
227
|
-
}
|
|
226
|
+
await apiServerCLIConfig.handler(argv);
|
|
228
227
|
}
|
|
229
228
|
}
|
|
230
229
|
}).command({
|