@cedarjs/cli 6.0.0-rc.260 → 6.0.0-rc.340
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/dev/devHandler.js +38 -1
- package/dist/commands/dev.js +3 -0
- package/dist/commands/execHandler.js +12 -0
- package/dist/commands/generate/package/filesTask.js +12 -0
- package/dist/commands/generate/package/packageHandler.js +11 -4
- package/dist/commands/generate/package/templates/test.ts.template +2 -2
- package/dist/commands/generate/package/templates/vitest.config.ts.template +9 -0
- package/dist/commands/generate/scaffold/scaffoldHandler.js +54 -13
- package/dist/commands/generate/script/templates/script.ts.template +9 -4
- package/dist/commands/serve.js +2 -2
- package/dist/commands/setup/deploy/providers/renderHandler.js +23 -1
- package/dist/commands/setup/deploy/templates/render.js +5 -2
- package/dist/commands/setup/neon/neon.js +13 -3
- package/dist/commands/setup/neon/neonHandler.js +31 -3
- package/dist/commands/setup/uploads/uploadsHandler.js +1 -1
- package/dist/commands/test/testHandlerEsm.js +1 -1
- package/dist/commands/upgrade/preUpgradeScripts.js +9 -9
- package/dist/commands/upgrade/upgradeHandler.js +42 -32
- package/dist/lib/background.js +20 -1
- package/package.json +21 -21
|
@@ -48,7 +48,8 @@ const handler = async ({
|
|
|
48
48
|
apiDebugPort,
|
|
49
49
|
debugBrk,
|
|
50
50
|
ud = false,
|
|
51
|
-
nodeArgs = ""
|
|
51
|
+
nodeArgs = "",
|
|
52
|
+
jobs: jobsOption
|
|
52
53
|
}) => {
|
|
53
54
|
recordTelemetryAttributes({
|
|
54
55
|
command: "dev",
|
|
@@ -206,6 +207,11 @@ const handler = async ({
|
|
|
206
207
|
` --apiPort ${apiAvailablePort}`,
|
|
207
208
|
getApiDebugFlag(apiDebugPort, apiAvailablePort),
|
|
208
209
|
debugBrk ? "--debug-brk" : "",
|
|
210
|
+
// `cedar-unified-dev` starts its own in-process jobs worker pool (see
|
|
211
|
+
// `jobsDevMiddleware.ts`) rather than relying on the nodemon-wrapped
|
|
212
|
+
// worker pushed below, so `--no-jobs` has to be forwarded explicitly -
|
|
213
|
+
// it isn't part of `forward` unless the user passed it after `--`.
|
|
214
|
+
jobsOption === false ? "--no-jobs" : "",
|
|
209
215
|
forward
|
|
210
216
|
].join(" ").replace(/\s+/g, " ").trim();
|
|
211
217
|
};
|
|
@@ -280,6 +286,37 @@ const handler = async ({
|
|
|
280
286
|
prefixColor: "green"
|
|
281
287
|
});
|
|
282
288
|
}
|
|
289
|
+
const jobsConfigured = jobsOption !== false && workspace.includes("api") && !!cedarPaths.api.jobsConfig && // `getPaths()` resolves `jobsConfig` once and caches it in-process, so
|
|
290
|
+
// if `api/src/lib/jobs.ts` is deleted mid-session the cached path would
|
|
291
|
+
// otherwise still look "configured". Guard against starting a worker
|
|
292
|
+
// that can't load a jobs config that no longer exists.
|
|
293
|
+
fs.existsSync(cedarPaths.api.jobsConfig) && fs.existsSync(cedarPaths.api.jobs) && // Job files always live in `api/src/jobs/<ComponentName>Job/`
|
|
294
|
+
// subdirectories (see `generate/job/jobHandler.ts`), so entries here are
|
|
295
|
+
// directories, not files — only the `.keep` placeholder (and any stray
|
|
296
|
+
// dotfiles, e.g. `.DS_Store`) should be excluded.
|
|
297
|
+
fs.readdirSync(cedarPaths.api.jobs).some((entry) => !entry.startsWith("."));
|
|
298
|
+
if (jobsConfigured && unifiedDevCommand) {
|
|
299
|
+
} else if (jobsConfigured) {
|
|
300
|
+
jobs.push({
|
|
301
|
+
name: "jobs",
|
|
302
|
+
// `cedar-jobs work` loads its config and job files from `api/dist`
|
|
303
|
+
// (compiled output), not `api/src`. That dist output is only written
|
|
304
|
+
// once the `api` watcher's initial build finishes, which happens
|
|
305
|
+
// asynchronously — so on a clean `cedar dev` start there's a window
|
|
306
|
+
// where `api/dist` doesn't exist yet and the worker would exit
|
|
307
|
+
// immediately. Wrapping it in nodemon (same tool the `api` job above
|
|
308
|
+
// uses) means it retries as soon as `api/dist` changes, instead of
|
|
309
|
+
// staying dead for the rest of the session. This also means the
|
|
310
|
+
// worker restarts automatically whenever job code is rebuilt, since
|
|
311
|
+
// Node's ESM cache would otherwise keep serving stale job code.
|
|
312
|
+
command: formatRunBinCommand("nodemon", [
|
|
313
|
+
"--quiet",
|
|
314
|
+
`--watch "${cedarPaths.api.dist}"`,
|
|
315
|
+
`--exec "${formatRunBinCommand("cedar-jobs", ["work"])}"`
|
|
316
|
+
]),
|
|
317
|
+
prefixColor: "magenta"
|
|
318
|
+
});
|
|
319
|
+
}
|
|
283
320
|
const packageWorkspaces = workspace.filter(
|
|
284
321
|
(w) => w !== "api" && w !== "web" && w !== "gen"
|
|
285
322
|
);
|
package/dist/commands/dev.js
CHANGED
|
@@ -31,6 +31,9 @@ const builder = (yargs) => {
|
|
|
31
31
|
}).option("nodeArgs", {
|
|
32
32
|
type: "string",
|
|
33
33
|
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
|
+
}).option("jobs", {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Start the background jobs worker alongside the other dev servers when jobs are configured (`cedar setup jobs` + at least one `cedar g job`). Pass `--no-jobs` to opt out and run `cedar jobs work` yourself instead."
|
|
34
37
|
}).middleware(() => {
|
|
35
38
|
const check = checkNodeVersion();
|
|
36
39
|
if (check.ok) {
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { context } from "@opentelemetry/api";
|
|
4
4
|
import { suppressTracing } from "@opentelemetry/core";
|
|
5
5
|
import { Listr } from "listr2";
|
|
6
|
+
import { Parser } from "yargs/helpers";
|
|
6
7
|
import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
|
|
7
8
|
import { findScripts } from "@cedarjs/internal/dist/files";
|
|
8
9
|
import { runScriptFunction } from "../lib/exec.js";
|
|
@@ -50,6 +51,17 @@ const handler = async (args) => {
|
|
|
50
51
|
delete scriptArgs.l;
|
|
51
52
|
delete scriptArgs.s;
|
|
52
53
|
delete scriptArgs.silent;
|
|
54
|
+
if (Array.isArray(scriptArgs._)) {
|
|
55
|
+
const dashBlockIndex = scriptArgs._.findIndex(
|
|
56
|
+
(arg) => typeof arg === "string" && arg.startsWith("-")
|
|
57
|
+
);
|
|
58
|
+
if (dashBlockIndex !== -1) {
|
|
59
|
+
const unparsedTail = scriptArgs._.splice(dashBlockIndex);
|
|
60
|
+
const { _: reparsedPositionals, ...reparsedFlags } = Parser(unparsedTail);
|
|
61
|
+
scriptArgs._.push(...reparsedPositionals);
|
|
62
|
+
Object.assign(scriptArgs, reparsedFlags);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
53
65
|
const scriptPath = resolveScriptPath(name);
|
|
54
66
|
if (!scriptPath) {
|
|
55
67
|
console.error(
|
|
@@ -8,6 +8,7 @@ const files = async ({
|
|
|
8
8
|
fileName,
|
|
9
9
|
typescript,
|
|
10
10
|
tests: generateTests = true,
|
|
11
|
+
esm = false,
|
|
11
12
|
...rest
|
|
12
13
|
}) => {
|
|
13
14
|
const extension = typescript ? ".ts" : ".js";
|
|
@@ -58,6 +59,17 @@ const files = async ({
|
|
|
58
59
|
outputPath: path.join(folderName, "src", `${fileName}.test${extension}`)
|
|
59
60
|
});
|
|
60
61
|
outputFiles.push(testFile);
|
|
62
|
+
if (esm) {
|
|
63
|
+
const vitestConfigFile = await templateForFile({
|
|
64
|
+
name,
|
|
65
|
+
side: "packages",
|
|
66
|
+
generator: "package",
|
|
67
|
+
templatePath: "vitest.config.ts.template",
|
|
68
|
+
templateVars: { folderName, ...rest },
|
|
69
|
+
outputPath: path.join(folderName, `vitest.config${extension}`)
|
|
70
|
+
});
|
|
71
|
+
outputFiles.push(vitestConfigFile);
|
|
72
|
+
}
|
|
61
73
|
}
|
|
62
74
|
return outputFiles.reduce(async (accP, [outputPath, content]) => {
|
|
63
75
|
const acc = await accP;
|
|
@@ -11,7 +11,7 @@ import { workspacePackageSpecifier } from "@cedarjs/cli-helpers/packageManager";
|
|
|
11
11
|
import { runScript, runBinSync } from "@cedarjs/cli-helpers/packageManager/exec";
|
|
12
12
|
import { installPackages } from "@cedarjs/cli-helpers/packageManager/packages";
|
|
13
13
|
import { addWorkspaceDir } from "@cedarjs/cli-helpers/packageManager/workspaces";
|
|
14
|
-
import { getConfig } from "@cedarjs/project-config";
|
|
14
|
+
import { getConfig, projectIsEsm } from "@cedarjs/project-config";
|
|
15
15
|
import { getPackageManager } from "@cedarjs/project-config/packageManager";
|
|
16
16
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
17
17
|
import { getPaths, writeFilesTask } from "../../../lib/index.js";
|
|
@@ -32,8 +32,10 @@ async function updateTsconfig(task) {
|
|
|
32
32
|
path: path.join(getPaths().api.base, "tsconfig.json"),
|
|
33
33
|
expectedModule: "node20",
|
|
34
34
|
// While Cedar doesn't officially endorse NodeNext, it will still work
|
|
35
|
-
// here, so we'll keep it
|
|
36
|
-
|
|
35
|
+
// here, so we'll keep it. ESNext is also acceptable: it's the current
|
|
36
|
+
// create-cedar-app default, paired with `moduleResolution: bundler` so
|
|
37
|
+
// extensionless scaffold/generator imports resolve correctly.
|
|
38
|
+
acceptable: ["node20", "nodenext", "esnext"]
|
|
37
39
|
},
|
|
38
40
|
{
|
|
39
41
|
name: "web",
|
|
@@ -338,7 +340,12 @@ const handler = async ({
|
|
|
338
340
|
{
|
|
339
341
|
title: "Generating package files...",
|
|
340
342
|
task: async (ctx) => {
|
|
341
|
-
packageFiles = await files({
|
|
343
|
+
packageFiles = await files({
|
|
344
|
+
...ctx.nameVariants,
|
|
345
|
+
// Only Vitest projects get a config generated for them
|
|
346
|
+
esm: projectIsEsm(),
|
|
347
|
+
...rest
|
|
348
|
+
});
|
|
342
349
|
return writeFilesTask(packageFiles, { overwriteExisting: force });
|
|
343
350
|
}
|
|
344
351
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ${camelName} } from './index.js'
|
|
2
2
|
|
|
3
3
|
describe('${camelName}', () => {
|
|
4
|
-
it('should not throw any errors',
|
|
5
|
-
expect(${camelName}()).not.toThrow()
|
|
4
|
+
it('should not throw any errors', () => {
|
|
5
|
+
expect(() => ${camelName}()).not.toThrow()
|
|
6
6
|
})
|
|
7
7
|
})
|
|
@@ -6,6 +6,7 @@ import humanize from "humanize-string";
|
|
|
6
6
|
import { Listr } from "listr2";
|
|
7
7
|
import pascalcase from "pascalcase";
|
|
8
8
|
import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
|
|
9
|
+
import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
|
|
9
10
|
import {
|
|
10
11
|
addWorkspacePackages,
|
|
11
12
|
removeWorkspacePackages
|
|
@@ -38,10 +39,14 @@ import {
|
|
|
38
39
|
import { builder as sdlBuilder } from "../sdl/sdl.js";
|
|
39
40
|
import {
|
|
40
41
|
files as sdlFiles,
|
|
42
|
+
stubFiles as sdlStubFiles,
|
|
41
43
|
printRedactedFieldsNote,
|
|
42
44
|
redactedSensitiveFields
|
|
43
45
|
} from "../sdl/sdlHandler.js";
|
|
44
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
missingRelatedModels,
|
|
48
|
+
writeFilesWithStubsTask
|
|
49
|
+
} from "../sdl/stubFiles.js";
|
|
45
50
|
import { builder as serviceBuilder } from "../service/service.js";
|
|
46
51
|
import { files as serviceFiles } from "../service/serviceHandler.js";
|
|
47
52
|
import { customOrDefaultTemplatePath } from "../yargsHandlerHelpers.js";
|
|
@@ -630,22 +635,26 @@ const tasks = ({
|
|
|
630
635
|
tests,
|
|
631
636
|
typescript,
|
|
632
637
|
javascript: _javascript,
|
|
633
|
-
tailwind
|
|
638
|
+
tailwind,
|
|
639
|
+
missingModels
|
|
634
640
|
}) => {
|
|
635
641
|
return new Listr(
|
|
636
642
|
[
|
|
637
643
|
{
|
|
638
644
|
title: "Generating scaffold files...",
|
|
639
645
|
task: async () => {
|
|
640
|
-
const f =
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
646
|
+
const f = {
|
|
647
|
+
...await files({
|
|
648
|
+
docs,
|
|
649
|
+
model,
|
|
650
|
+
path: path2,
|
|
651
|
+
tests,
|
|
652
|
+
typescript,
|
|
653
|
+
tailwind,
|
|
654
|
+
force
|
|
655
|
+
}),
|
|
656
|
+
...await sdlStubFiles(missingModels, model, { docs, typescript })
|
|
657
|
+
};
|
|
649
658
|
return writeFilesWithStubsTask(f, { overwriteExisting: force });
|
|
650
659
|
}
|
|
651
660
|
},
|
|
@@ -711,6 +720,7 @@ const handler = async ({
|
|
|
711
720
|
tailwind = shouldUseTailwindCSS(tailwind);
|
|
712
721
|
try {
|
|
713
722
|
const { name } = await verifyModelName({ name: model });
|
|
723
|
+
const missingModels = await missingRelatedModels(name);
|
|
714
724
|
const t = tasks({
|
|
715
725
|
docs,
|
|
716
726
|
model: name,
|
|
@@ -718,13 +728,44 @@ const handler = async ({
|
|
|
718
728
|
force,
|
|
719
729
|
tests,
|
|
720
730
|
typescript,
|
|
721
|
-
tailwind
|
|
731
|
+
tailwind,
|
|
732
|
+
missingModels
|
|
722
733
|
});
|
|
723
734
|
if (rollback && !force) {
|
|
724
735
|
prepareForRollback(t);
|
|
725
736
|
}
|
|
726
737
|
await t.run();
|
|
727
|
-
|
|
738
|
+
if (missingModels.length > 0) {
|
|
739
|
+
console.log();
|
|
740
|
+
console.log(
|
|
741
|
+
c.info(
|
|
742
|
+
`${name} has relations to models that don't have SDL files of their own yet: ${missingModels.join(", ")}`
|
|
743
|
+
)
|
|
744
|
+
);
|
|
745
|
+
console.log(
|
|
746
|
+
c.info(
|
|
747
|
+
"Read-only SDL stubs were generated for them, since GraphQL type generation fails otherwise."
|
|
748
|
+
)
|
|
749
|
+
);
|
|
750
|
+
console.log(
|
|
751
|
+
c.info("To replace a stub, run one of the following for each model:")
|
|
752
|
+
);
|
|
753
|
+
for (const stubModel of missingModels) {
|
|
754
|
+
console.log(
|
|
755
|
+
c.info(
|
|
756
|
+
` ${formatCedarCommand(["generate", "sdl", stubModel])} (SDL + service only)`
|
|
757
|
+
)
|
|
758
|
+
);
|
|
759
|
+
console.log(
|
|
760
|
+
c.info(
|
|
761
|
+
` ${formatCedarCommand(["generate", "scaffold", stubModel])} (adds pages, cells, and forms too)`
|
|
762
|
+
)
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
printRedactedFieldsNote(
|
|
767
|
+
await redactedSensitiveFields([name, ...missingModels])
|
|
768
|
+
);
|
|
728
769
|
} catch (e) {
|
|
729
770
|
const message = e instanceof Error ? e.message : String(e);
|
|
730
771
|
const exitCode = e instanceof Error && "exitCode" in e ? e.exitCode ?? 1 : 1;
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
// To access your database uncomment the line below
|
|
4
4
|
// import { db } from 'api/src/lib/db'
|
|
5
5
|
|
|
6
|
-
interface
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
interface ScriptArgs {
|
|
7
|
+
args: {
|
|
8
|
+
// positional args, e.g. `yarn cedar exec myScript foo 123` -> ['foo', 123]
|
|
9
|
+
// numeric-looking args are parsed as numbers, others as strings
|
|
10
|
+
_: Array<string | number>
|
|
11
|
+
// named flags, e.g. `--force` -> { force: true }
|
|
12
|
+
[flag: string]: unknown
|
|
13
|
+
}
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
export default async ({ args }:
|
|
16
|
+
export default async ({ args }: ScriptArgs) => {
|
|
12
17
|
// Your script here...
|
|
13
18
|
console.log(':: Executing script with args ::')
|
|
14
19
|
console.log(args)
|
package/dist/commands/serve.js
CHANGED
|
@@ -107,7 +107,7 @@ const builder = async (yargs) => {
|
|
|
107
107
|
const webHost = argv.webHost ?? getWebHost({ isPublicSide: true });
|
|
108
108
|
const apiRootPath = argv.apiRootPath ?? "/";
|
|
109
109
|
const apiTarget = `http://${apiHost.includes(":") ? `[${apiHost}]` : apiHost}:${apiPort}`;
|
|
110
|
-
const {
|
|
110
|
+
const { staticMiddleware } = await import("srvx/static");
|
|
111
111
|
const apiUrl = getConfig().web.apiUrl;
|
|
112
112
|
const webDist = getPaths().web.dist;
|
|
113
113
|
const prerenderIndexPath = path.join(webDist, "200.html");
|
|
@@ -117,7 +117,7 @@ const builder = async (yargs) => {
|
|
|
117
117
|
// Dummy fetch handler. All requests are handled by middleware
|
|
118
118
|
fetch: async () => new Response("Not Found", { status: 404 }),
|
|
119
119
|
middleware: [
|
|
120
|
-
|
|
120
|
+
staticMiddleware({ dir: webDist }),
|
|
121
121
|
async (req, next) => {
|
|
122
122
|
const url = new URL(req.url, "http://localhost");
|
|
123
123
|
if (!url.pathname.startsWith(apiUrl)) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import prismaInternals from "@prisma/internals";
|
|
3
3
|
import { Listr } from "listr2";
|
|
4
|
+
import prompts from "prompts";
|
|
4
5
|
import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
|
|
5
6
|
import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
|
|
6
7
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
7
8
|
import { writeFilesTask, printSetupNotes } from "../../../../lib/index.js";
|
|
8
9
|
import { POSTGRES_YAML, RENDER_YAML, SQLITE_YAML } from "../templates/render.js";
|
|
9
10
|
const { getConfig } = prismaInternals;
|
|
11
|
+
const SQLITE_API_PLAN = "starter";
|
|
10
12
|
const getRenderYamlContent = async (database) => {
|
|
11
13
|
if (database === "none") {
|
|
12
14
|
return {
|
|
@@ -27,7 +29,7 @@ const getRenderYamlContent = async (database) => {
|
|
|
27
29
|
case "sqlite":
|
|
28
30
|
return {
|
|
29
31
|
path: path.join(getPaths().base, "render.yaml"),
|
|
30
|
-
content: RENDER_YAML(SQLITE_YAML)
|
|
32
|
+
content: RENDER_YAML(SQLITE_YAML, SQLITE_API_PLAN)
|
|
31
33
|
};
|
|
32
34
|
default:
|
|
33
35
|
throw new Error(`
|
|
@@ -61,6 +63,26 @@ const handler = async ({
|
|
|
61
63
|
force,
|
|
62
64
|
database
|
|
63
65
|
});
|
|
66
|
+
if (database === "sqlite") {
|
|
67
|
+
console.warn(
|
|
68
|
+
c.warning(
|
|
69
|
+
`Render's free plan doesn't support persistent disks, which the \`sqlite\` deploy option requires for its database file. The generated render.yaml will set the api service's plan to "${SQLITE_API_PLAN}" (a paid plan) instead of "free" so the disk can actually attach.
|
|
70
|
+
|
|
71
|
+
If you want to stay on the free plan, rerun this command with \`--database postgresql\` (a managed database, not a disk) or \`--database none\`.`
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
console.log();
|
|
75
|
+
const { confirmed } = await prompts({
|
|
76
|
+
type: "confirm",
|
|
77
|
+
name: "confirmed",
|
|
78
|
+
message: `Generate render.yaml with the api service on the "${SQLITE_API_PLAN}" plan?`
|
|
79
|
+
});
|
|
80
|
+
if (!confirmed) {
|
|
81
|
+
console.log("Aborting render setup.");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
console.log();
|
|
85
|
+
}
|
|
64
86
|
const tasks = new Listr(
|
|
65
87
|
[
|
|
66
88
|
{
|
|
@@ -2,7 +2,7 @@ import path from "path";
|
|
|
2
2
|
import { getPaths } from "../../../../lib/index.js";
|
|
3
3
|
import { getUserApiUrl } from "../helpers/index.js";
|
|
4
4
|
const PROJECT_NAME = path.basename(getPaths().base);
|
|
5
|
-
const RENDER_YAML = (database) => {
|
|
5
|
+
const RENDER_YAML = (database, plan = "free") => {
|
|
6
6
|
const apiUrl = getUserApiUrl().replace(/\/$/, "");
|
|
7
7
|
return `# Quick links to the docs:
|
|
8
8
|
# - Deploying Cedar: https://cedarjs.com/docs/deploy/render
|
|
@@ -41,7 +41,7 @@ services:
|
|
|
41
41
|
|
|
42
42
|
- name: ${PROJECT_NAME}-api
|
|
43
43
|
type: web
|
|
44
|
-
plan:
|
|
44
|
+
plan: ${plan}
|
|
45
45
|
runtime: node
|
|
46
46
|
region: oregon
|
|
47
47
|
buildCommand: npm install --global corepack && yarn install && yarn cedar build api
|
|
@@ -69,9 +69,12 @@ const POSTGRES_YAML = ` - key: DATABASE_URL
|
|
|
69
69
|
|
|
70
70
|
databases:
|
|
71
71
|
- name: ${PROJECT_NAME}-db
|
|
72
|
+
plan: free
|
|
72
73
|
region: oregon`;
|
|
73
74
|
const SQLITE_YAML = ` - key: DATABASE_URL
|
|
74
75
|
value: file:./data/sqlite.db
|
|
76
|
+
# Persistent disks aren't available on Render's free plan, which is why
|
|
77
|
+
# the api service above is on a paid plan when SQLite is selected.
|
|
75
78
|
disk:
|
|
76
79
|
name: sqlite-data
|
|
77
80
|
mountPath: /opt/render/project/src/api/db/data
|
|
@@ -7,15 +7,25 @@ function builder(yargs) {
|
|
|
7
7
|
default: false,
|
|
8
8
|
description: "Overwrite existing DATABASE_URL in .env",
|
|
9
9
|
type: "boolean"
|
|
10
|
+
}).option("migrations", {
|
|
11
|
+
description: "Run Prisma migrations after setup. Omit to be prompted. Use --no-migrations to skip.",
|
|
12
|
+
type: "boolean"
|
|
13
|
+
}).option("verbose", {
|
|
14
|
+
alias: "v",
|
|
15
|
+
default: false,
|
|
16
|
+
description: "Show full output from migration commands (stderr visible in terminal)",
|
|
17
|
+
type: "boolean"
|
|
10
18
|
});
|
|
11
19
|
}
|
|
12
|
-
async function handler({ force }) {
|
|
20
|
+
async function handler({ force, migrations, verbose }) {
|
|
13
21
|
recordTelemetryAttributes({
|
|
14
22
|
command: "setup neon",
|
|
15
|
-
force
|
|
23
|
+
force,
|
|
24
|
+
migrations,
|
|
25
|
+
verbose
|
|
16
26
|
});
|
|
17
27
|
const { handler: handler2 } = await import("./neonHandler.js");
|
|
18
|
-
return handler2({ force });
|
|
28
|
+
return handler2({ force, migrations, verbose });
|
|
19
29
|
}
|
|
20
30
|
export {
|
|
21
31
|
builder,
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
|
+
import prompts from "prompts";
|
|
5
6
|
import { colors, getPaths, installPackages } from "@cedarjs/cli-helpers";
|
|
6
7
|
import { prettyPrintCedarCommand } from "@cedarjs/cli-helpers/packageManager";
|
|
7
8
|
import { errorTelemetry } from "@cedarjs/telemetry";
|
|
@@ -25,7 +26,7 @@ function isPostgresConnectionString(rawValue) {
|
|
|
25
26
|
return false;
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
|
-
async function handler({ force }) {
|
|
29
|
+
async function handler({ force, migrations, verbose }) {
|
|
29
30
|
const cedarPaths = getPaths();
|
|
30
31
|
const shape = checkProjectShape(cedarPaths);
|
|
31
32
|
if (!shape.ok) {
|
|
@@ -51,6 +52,29 @@ async function handler({ force }) {
|
|
|
51
52
|
)
|
|
52
53
|
);
|
|
53
54
|
}
|
|
55
|
+
let runMigrations = migrations;
|
|
56
|
+
if (!skipProvisioning && runMigrations === void 0) {
|
|
57
|
+
if (!process.stdin.isTTY) {
|
|
58
|
+
const error = new Error(
|
|
59
|
+
"Cannot prompt for confirmation in a non-interactive terminal. Please pass --migrations or --no-migrations explicitly."
|
|
60
|
+
);
|
|
61
|
+
errorTelemetry(process.argv, error.message);
|
|
62
|
+
console.error(colors.error(error.message));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const response = await prompts({
|
|
66
|
+
type: "toggle",
|
|
67
|
+
name: "runMigrations",
|
|
68
|
+
message: "Run Prisma migrations now?",
|
|
69
|
+
initial: true,
|
|
70
|
+
active: "Yes",
|
|
71
|
+
inactive: "No"
|
|
72
|
+
});
|
|
73
|
+
if (response.runMigrations === void 0) {
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
runMigrations = response.runMigrations;
|
|
77
|
+
}
|
|
54
78
|
const tasks = new Listr(
|
|
55
79
|
[
|
|
56
80
|
...getSqliteToPostgresTasks({ dbPath: shape.dbPath }),
|
|
@@ -124,6 +148,9 @@ async function handler({ force }) {
|
|
|
124
148
|
if (skipProvisioning) {
|
|
125
149
|
return true;
|
|
126
150
|
}
|
|
151
|
+
if (!runMigrations) {
|
|
152
|
+
return migrations === false ? "Skipped (--no-migrations)" : "Skipped";
|
|
153
|
+
}
|
|
127
154
|
if (ctx.directDatabaseUrlNotSet) {
|
|
128
155
|
return `Skipping migrations \u2014 could not confirm prisma.config is reading DIRECT_DATABASE_URL, so migrations could target the wrong database. Fix datasource.url, then run \`${prettyPrintCedarCommand(["prisma", "migrate", "dev"])}\` manually.`;
|
|
129
156
|
}
|
|
@@ -134,7 +161,7 @@ async function handler({ force }) {
|
|
|
134
161
|
"yarn cedar prisma migrate dev --name init-neon",
|
|
135
162
|
{
|
|
136
163
|
cwd: cedarPaths.base,
|
|
137
|
-
stdio: ["inherit", "inherit", "pipe"],
|
|
164
|
+
stdio: verbose ? "inherit" : ["inherit", "inherit", "pipe"],
|
|
138
165
|
reject: false,
|
|
139
166
|
env: {
|
|
140
167
|
...process.env,
|
|
@@ -144,7 +171,8 @@ async function handler({ force }) {
|
|
|
144
171
|
);
|
|
145
172
|
if (result.exitCode !== 0) {
|
|
146
173
|
throw new Error(
|
|
147
|
-
|
|
174
|
+
verbose ? `Prisma migration failed. You can try running it manually:
|
|
175
|
+
${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}` : "Prisma migration failed:\n\n" + result.stderr + `
|
|
148
176
|
|
|
149
177
|
You can try running it manually:
|
|
150
178
|
${prettyPrintCedarCommand(["prisma", "migrate", "dev", "--name", "init-neon"])}`
|
|
@@ -83,7 +83,7 @@ const handler = async ({ force }) => {
|
|
|
83
83
|
if (transformResult.error) {
|
|
84
84
|
if (transformResult.error === "RW_CODEMOD_ERR_OLD_FORMAT") {
|
|
85
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/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"
|
|
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
87
|
);
|
|
88
88
|
}
|
|
89
89
|
throw new Error(
|
|
@@ -59,10 +59,10 @@ const handler = async ({
|
|
|
59
59
|
vitestArgs.push("--run");
|
|
60
60
|
}
|
|
61
61
|
if (!others["config"]) {
|
|
62
|
+
sides.forEach((side) => vitestArgs.push("--project", side));
|
|
62
63
|
if (!sides.length) {
|
|
63
64
|
project.workspaces().forEach((side) => sides.push(side));
|
|
64
65
|
}
|
|
65
|
-
sides.forEach((side) => vitestArgs.push("--project", side));
|
|
66
66
|
}
|
|
67
67
|
try {
|
|
68
68
|
const cacheDirDb = `file:${ensurePosixPath(
|
|
@@ -4,6 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import execa from "execa";
|
|
6
6
|
import semver from "semver";
|
|
7
|
+
const MAIN_BRANCH_PRERELEASE_TAGS = ["canary"];
|
|
7
8
|
function isExecaError(e) {
|
|
8
9
|
return e instanceof Error && ("stdout" in e || "stderr" in e || "exitCode" in e);
|
|
9
10
|
}
|
|
@@ -33,8 +34,15 @@ async function runPreUpgradeScripts(ctx, task, { verbose, force }) {
|
|
|
33
34
|
if (!Array.isArray(manifest) || manifest.length === 0) {
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
37
|
+
const prereleaseTag = parsed?.prerelease[0];
|
|
38
|
+
const isMainBranchPrerelease = typeof prereleaseTag === "string" && MAIN_BRANCH_PRERELEASE_TAGS.includes(prereleaseTag);
|
|
36
39
|
const checkLevels = [];
|
|
37
|
-
if (parsed &&
|
|
40
|
+
if (parsed && isMainBranchPrerelease) {
|
|
41
|
+
checkLevels.push({
|
|
42
|
+
id: "tag",
|
|
43
|
+
candidates: [`${prereleaseTag}.ts`, `${prereleaseTag}/index.ts`]
|
|
44
|
+
});
|
|
45
|
+
} else if (parsed) {
|
|
38
46
|
checkLevels.push({
|
|
39
47
|
id: "exact",
|
|
40
48
|
candidates: [`${version}.ts`, `${version}/index.ts`]
|
|
@@ -50,14 +58,6 @@ async function runPreUpgradeScripts(ctx, task, { verbose, force }) {
|
|
|
50
58
|
id: "minor",
|
|
51
59
|
candidates: [`${parsed.major}.x.ts`, `${parsed.major}.x/index.ts`]
|
|
52
60
|
});
|
|
53
|
-
} else if (parsed && parsed.prerelease.length > 0) {
|
|
54
|
-
checkLevels.push({
|
|
55
|
-
id: "tag",
|
|
56
|
-
candidates: [
|
|
57
|
-
`${parsed.prerelease[0]}.ts`,
|
|
58
|
-
`${parsed.prerelease[0]}/index.ts`
|
|
59
|
-
]
|
|
60
|
-
});
|
|
61
61
|
}
|
|
62
62
|
const scriptsToRun = [];
|
|
63
63
|
for (const level of checkLevels) {
|
|
@@ -33,6 +33,7 @@ const handler = async (upgradeOptions) => {
|
|
|
33
33
|
});
|
|
34
34
|
let preUpgradeMessage = "";
|
|
35
35
|
let preUpgradeError = "";
|
|
36
|
+
const notBlockedByPreUpgradeChecks = (ctx) => force || !ctx.preUpgradeError;
|
|
36
37
|
const tasks = new Listr(
|
|
37
38
|
[
|
|
38
39
|
{
|
|
@@ -87,39 +88,46 @@ const handler = async (upgradeOptions) => {
|
|
|
87
88
|
{
|
|
88
89
|
title: "Updating your CedarJS version",
|
|
89
90
|
task: (ctx) => updateCedarJSDepsForAllSides(ctx, { dryRun, verbose }),
|
|
90
|
-
enabled: (ctx) => !!ctx.versionToUpgradeTo &&
|
|
91
|
+
enabled: (ctx) => !!ctx.versionToUpgradeTo && notBlockedByPreUpgradeChecks(ctx)
|
|
91
92
|
},
|
|
92
93
|
{
|
|
93
94
|
title: "Updating other packages in your package.json(s)",
|
|
94
95
|
task: (ctx) => updatePackageVersionsFromTemplate(ctx, { dryRun, verbose }),
|
|
95
|
-
|
|
96
|
+
// Canary only. This forces the template's dependency versions onto the
|
|
97
|
+
// project and adds back any the project is missing, which resurrects
|
|
98
|
+
// packages people have deliberately removed — a project that moved off
|
|
99
|
+
// SQLite gets better-sqlite3 back, for example. That's too blunt for
|
|
100
|
+
// regular upgrades, but people running canary are already signed up
|
|
101
|
+
// for rougher edges.
|
|
102
|
+
// https://github.com/redwoodjs/redwood/pull/8855
|
|
103
|
+
enabled: (ctx) => String(ctx.versionToUpgradeTo).includes("canary") && notBlockedByPreUpgradeChecks(ctx)
|
|
96
104
|
},
|
|
97
105
|
{
|
|
98
106
|
title: "Downloading yarn patches",
|
|
99
107
|
task: (ctx) => downloadYarnPatches(ctx, { dryRun, verbose }),
|
|
100
|
-
enabled: (ctx) => String(ctx.versionToUpgradeTo).includes("canary") &&
|
|
108
|
+
enabled: (ctx) => String(ctx.versionToUpgradeTo).includes("canary") && notBlockedByPreUpgradeChecks(ctx)
|
|
101
109
|
},
|
|
102
110
|
{
|
|
103
111
|
title: "Removing CLI cache",
|
|
104
112
|
task: () => removeCliCache({ dryRun, verbose }),
|
|
105
|
-
enabled: (ctx) =>
|
|
113
|
+
enabled: (ctx) => notBlockedByPreUpgradeChecks(ctx)
|
|
106
114
|
},
|
|
107
115
|
{
|
|
108
116
|
title: `Running ${getPackageManager()} ${install()}`,
|
|
109
117
|
task: () => packageManagerInstall({ verbose }),
|
|
110
|
-
enabled: (ctx) =>
|
|
118
|
+
enabled: (ctx) => notBlockedByPreUpgradeChecks(ctx),
|
|
111
119
|
skip: () => !!dryRun
|
|
112
120
|
},
|
|
113
121
|
{
|
|
114
122
|
title: "Refreshing the Prisma client",
|
|
115
123
|
task: (_ctx, task) => refreshPrismaClient(task, { verbose }),
|
|
116
|
-
enabled: (ctx) =>
|
|
124
|
+
enabled: (ctx) => notBlockedByPreUpgradeChecks(ctx),
|
|
117
125
|
skip: () => !!dryRun
|
|
118
126
|
},
|
|
119
127
|
{
|
|
120
128
|
title: "De-duplicating dependencies",
|
|
121
129
|
skip: () => !!dryRun || !dedupe2,
|
|
122
|
-
enabled: (ctx) => dedupeIsSupported() &&
|
|
130
|
+
enabled: (ctx) => dedupeIsSupported() && notBlockedByPreUpgradeChecks(ctx),
|
|
123
131
|
task: (_ctx, task) => dedupeDeps(task, { verbose })
|
|
124
132
|
},
|
|
125
133
|
{
|
|
@@ -303,6 +311,22 @@ function updateCedarJSDepsForAllSides(ctx, options) {
|
|
|
303
311
|
})
|
|
304
312
|
);
|
|
305
313
|
}
|
|
314
|
+
function mergeTemplateDependencies(field, templatePackageJson, localPackageJson, messages, { dryRun, verbose } = {}) {
|
|
315
|
+
const templateDeps = templatePackageJson[field];
|
|
316
|
+
if (!templateDeps) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
for (const [depName, depVersion] of Object.entries(templateDeps)) {
|
|
320
|
+
if (depName.startsWith("@cedarjs/")) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
const localDeps = localPackageJson[field] ??= {};
|
|
324
|
+
if (verbose || dryRun) {
|
|
325
|
+
messages.push(` - ${depName}: ${localDeps[depName]} => ${depVersion}`);
|
|
326
|
+
}
|
|
327
|
+
localDeps[depName] = depVersion;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
306
330
|
async function updatePackageVersionsFromTemplate(ctx, { dryRun, verbose }) {
|
|
307
331
|
if (!ctx.versionToUpgradeTo) {
|
|
308
332
|
throw new Error("Failed to upgrade");
|
|
@@ -338,30 +362,15 @@ async function updatePackageVersionsFromTemplate(ctx, { dryRun, verbose }) {
|
|
|
338
362
|
const localPackageJsonText = fs.readFileSync(pkgJsonPath, "utf-8");
|
|
339
363
|
const localPackageJson = JSON.parse(localPackageJsonText);
|
|
340
364
|
const messages = [];
|
|
341
|
-
|
|
342
|
-
(
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
);
|
|
353
|
-
Object.entries(templatePackageJson.devDependencies || {}).forEach(
|
|
354
|
-
([depName, depVersion]) => {
|
|
355
|
-
if (!depName.startsWith("@cedarjs/")) {
|
|
356
|
-
if (verbose || dryRun) {
|
|
357
|
-
messages.push(
|
|
358
|
-
` - ${depName}: ${localPackageJson.devDependencies[depName]} => ${depVersion}`
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
localPackageJson.devDependencies[depName] = depVersion;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
);
|
|
365
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
366
|
+
mergeTemplateDependencies(
|
|
367
|
+
field,
|
|
368
|
+
templatePackageJson,
|
|
369
|
+
localPackageJson,
|
|
370
|
+
messages,
|
|
371
|
+
{ dryRun, verbose }
|
|
372
|
+
);
|
|
373
|
+
}
|
|
365
374
|
if (messages.length > 0) {
|
|
366
375
|
task.title = task.title + "\n" + messages.join("\n");
|
|
367
376
|
}
|
|
@@ -469,5 +478,6 @@ async function dedupeDeps(_task, { verbose }) {
|
|
|
469
478
|
await packageManagerInstall({ verbose });
|
|
470
479
|
}
|
|
471
480
|
export {
|
|
472
|
-
handler
|
|
481
|
+
handler,
|
|
482
|
+
mergeTemplateDependencies
|
|
473
483
|
};
|
package/dist/lib/background.js
CHANGED
|
@@ -3,6 +3,23 @@ import fs from "node:fs";
|
|
|
3
3
|
import os from "os";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { getPaths } from "@cedarjs/project-config";
|
|
6
|
+
function quoteForWindowsShell(arg) {
|
|
7
|
+
let quoted = '"';
|
|
8
|
+
let backslashes = 0;
|
|
9
|
+
for (const char of arg) {
|
|
10
|
+
if (char === "\\") {
|
|
11
|
+
backslashes += 1;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (char === '"') {
|
|
15
|
+
quoted += "\\".repeat(backslashes * 2 + 1) + '"';
|
|
16
|
+
} else {
|
|
17
|
+
quoted += "\\".repeat(backslashes) + char;
|
|
18
|
+
}
|
|
19
|
+
backslashes = 0;
|
|
20
|
+
}
|
|
21
|
+
return quoted + "\\".repeat(backslashes * 2) + '"';
|
|
22
|
+
}
|
|
6
23
|
function spawnBackgroundProcess(name, cmd, args) {
|
|
7
24
|
const logDirectory = path.join(getPaths().generated.base, "logs");
|
|
8
25
|
fs.mkdirSync(logDirectory, { recursive: true });
|
|
@@ -37,7 +54,8 @@ function spawnBackgroundProcess(name, cmd, args) {
|
|
|
37
54
|
shell: true,
|
|
38
55
|
stdio: ["ignore", stdout, stderr]
|
|
39
56
|
};
|
|
40
|
-
const
|
|
57
|
+
const command = [cmd, ...args].map(quoteForWindowsShell).join(" ");
|
|
58
|
+
const child = spawn(command, spawnOptions);
|
|
41
59
|
child.unref();
|
|
42
60
|
} else {
|
|
43
61
|
const spawnOptions = {
|
|
@@ -51,5 +69,6 @@ function spawnBackgroundProcess(name, cmd, args) {
|
|
|
51
69
|
fs.closeSync(stderr);
|
|
52
70
|
}
|
|
53
71
|
export {
|
|
72
|
+
quoteForWindowsShell,
|
|
54
73
|
spawnBackgroundProcess
|
|
55
74
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli",
|
|
3
|
-
"version": "6.0.0-rc.
|
|
3
|
+
"version": "6.0.0-rc.340",
|
|
4
4
|
"description": "The CedarJS Command Line",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,21 +32,21 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@babel/core": "^7.26.10",
|
|
35
|
-
"@babel/parser": "7.29.
|
|
35
|
+
"@babel/parser": "7.29.8",
|
|
36
36
|
"@babel/preset-typescript": "7.29.7",
|
|
37
|
-
"@babel/traverse": "7.29.
|
|
38
|
-
"@babel/types": "7.29.
|
|
39
|
-
"@cedarjs/api-server": "6.0.0-rc.
|
|
40
|
-
"@cedarjs/babel-config": "6.0.0-rc.
|
|
41
|
-
"@cedarjs/cli-helpers": "6.0.0-rc.
|
|
42
|
-
"@cedarjs/internal": "6.0.0-rc.
|
|
43
|
-
"@cedarjs/prerender": "6.0.0-rc.
|
|
44
|
-
"@cedarjs/project-config": "6.0.0-rc.
|
|
45
|
-
"@cedarjs/structure": "6.0.0-rc.
|
|
46
|
-
"@cedarjs/telemetry": "6.0.0-rc.
|
|
47
|
-
"@cedarjs/utils": "6.0.0-rc.
|
|
48
|
-
"@cedarjs/vite": "6.0.0-rc.
|
|
49
|
-
"@cedarjs/web-server": "6.0.0-rc.
|
|
37
|
+
"@babel/traverse": "7.29.8",
|
|
38
|
+
"@babel/types": "7.29.8",
|
|
39
|
+
"@cedarjs/api-server": "6.0.0-rc.340",
|
|
40
|
+
"@cedarjs/babel-config": "6.0.0-rc.340",
|
|
41
|
+
"@cedarjs/cli-helpers": "6.0.0-rc.340",
|
|
42
|
+
"@cedarjs/internal": "6.0.0-rc.340",
|
|
43
|
+
"@cedarjs/prerender": "6.0.0-rc.340",
|
|
44
|
+
"@cedarjs/project-config": "6.0.0-rc.340",
|
|
45
|
+
"@cedarjs/structure": "6.0.0-rc.340",
|
|
46
|
+
"@cedarjs/telemetry": "6.0.0-rc.340",
|
|
47
|
+
"@cedarjs/utils": "6.0.0-rc.340",
|
|
48
|
+
"@cedarjs/vite": "6.0.0-rc.340",
|
|
49
|
+
"@cedarjs/web-server": "6.0.0-rc.340",
|
|
50
50
|
"@listr2/prompt-adapter-enquirer": "4.3.0",
|
|
51
51
|
"@opentelemetry/api": "1.9.1",
|
|
52
52
|
"@opentelemetry/core": "1.30.1",
|
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
"prettier": "3.8.4",
|
|
83
83
|
"prisma": "7.8.0",
|
|
84
84
|
"prompts": "2.4.2",
|
|
85
|
-
"semver": "7.
|
|
86
|
-
"smol-toml": "1.
|
|
87
|
-
"srvx": "0.
|
|
85
|
+
"semver": "7.8.5",
|
|
86
|
+
"smol-toml": "1.8.0",
|
|
87
|
+
"srvx": "0.12.5",
|
|
88
88
|
"string-env-interpolation": "1.0.1",
|
|
89
|
-
"systeminformation": "5.
|
|
89
|
+
"systeminformation": "5.33.1",
|
|
90
90
|
"termi-link": "1.1.0",
|
|
91
91
|
"title-case": "3.0.3",
|
|
92
92
|
"unionfs": "4.6.0",
|
|
@@ -94,10 +94,10 @@
|
|
|
94
94
|
"yargs": "17.7.3"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@cedarjs/framework-tools": "6.0.0-rc.
|
|
97
|
+
"@cedarjs/framework-tools": "6.0.0-rc.340",
|
|
98
98
|
"@prisma/dmmf": "7.8.0",
|
|
99
99
|
"@types/archiver": "^7.0.0",
|
|
100
|
-
"memfs": "4.
|
|
100
|
+
"memfs": "4.68.1",
|
|
101
101
|
"node-ssh": "13.2.1",
|
|
102
102
|
"ts-dedent": "2.3.0",
|
|
103
103
|
"typescript": "5.9.3",
|