create-prisma 0.9.2 → 0.9.3-pr.65.238.1
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/cli.mjs +1 -1
- package/dist/{create-DPrHKEg5.mjs → create-D_2SzXVU.mjs} +157 -28
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { cancel, confirm, intro, isCancel, log, note, outro, select, spinner, text } from "@clack/prompts";
|
|
3
|
+
import { cancel, confirm, intro, isCancel, log, note, outro, select, spinner, taskLog, text } from "@clack/prompts";
|
|
4
4
|
import fs from "fs-extra";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
@@ -10,24 +10,16 @@ import Handlebars from "handlebars";
|
|
|
10
10
|
import { existsSync } from "node:fs";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { execa } from "execa";
|
|
13
|
+
import { createInterface } from "node:readline";
|
|
13
14
|
import { styleText } from "node:util";
|
|
14
15
|
|
|
15
16
|
//#region src/telemetry/client.ts
|
|
16
|
-
const TELEMETRY_API_KEY = "
|
|
17
|
+
const TELEMETRY_API_KEY = "";
|
|
17
18
|
const TELEMETRY_HOST = "https://us.i.posthog.com";
|
|
18
19
|
const TELEMETRY_CONFIG_FILE = "telemetry.json";
|
|
19
20
|
const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
20
|
-
function isTruthyEnvValue(value) {
|
|
21
|
-
return [
|
|
22
|
-
"1",
|
|
23
|
-
"true",
|
|
24
|
-
"yes",
|
|
25
|
-
"on"
|
|
26
|
-
].includes(String(value ?? "").trim().toLowerCase());
|
|
27
|
-
}
|
|
28
21
|
function shouldDisableTelemetry() {
|
|
29
|
-
|
|
30
|
-
return process.env.CREATE_PRISMA_DISABLE_TELEMETRY !== void 0 || process.env.CREATE_PRISMA_TELEMETRY_DISABLED !== void 0 || process.env.DO_NOT_TRACK !== void 0;
|
|
22
|
+
return true;
|
|
31
23
|
}
|
|
32
24
|
function getTelemetryConfigDir() {
|
|
33
25
|
if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Application Support", "create-prisma");
|
|
@@ -49,7 +41,7 @@ async function getAnonymousId() {
|
|
|
49
41
|
}
|
|
50
42
|
function getCommonProperties() {
|
|
51
43
|
return {
|
|
52
|
-
"cli-version": "0.9.
|
|
44
|
+
"cli-version": "0.9.3-pr.65.238.1",
|
|
53
45
|
"node-version": process.version,
|
|
54
46
|
platform: process.platform,
|
|
55
47
|
arch: process.arch
|
|
@@ -479,9 +471,9 @@ async function scaffoldCreateFrameworkTemplate(opts) {
|
|
|
479
471
|
const dependencyVersionMap = {
|
|
480
472
|
"@astrojs/node": "^10.0.2",
|
|
481
473
|
"@elysiajs/node": "^1.4.5",
|
|
482
|
-
"@prisma/composer": "0.
|
|
483
|
-
"@prisma/composer-prisma-cloud": "0.
|
|
484
|
-
"@prisma/orm-mongo": "8.0.0-rc.
|
|
474
|
+
"@prisma/composer": "0.14.0",
|
|
475
|
+
"@prisma/composer-prisma-cloud": "0.14.0",
|
|
476
|
+
"@prisma/orm-mongo": "8.0.0-rc.6",
|
|
485
477
|
"@prisma/orm-postgres": "8.0.0-rc.4",
|
|
486
478
|
"@sveltejs/adapter-node": "^5.3.2",
|
|
487
479
|
"@types/node": "^25.6.2",
|
|
@@ -668,7 +660,7 @@ async function installProjectDependencies(packageManager, projectDir = process.c
|
|
|
668
660
|
//#endregion
|
|
669
661
|
//#region src/tasks/deploy-with-composer.ts
|
|
670
662
|
function redactSecrets(message) {
|
|
671
|
-
return message.replace(/\b((?:prisma\+)?postgres(?:ql)
|
|
663
|
+
return message.replace(/\b((?:(?:prisma\+)?postgres(?:ql)?|mongodb(?:\+srv)?):\/\/)[^\s'"]+/gi, "$1<redacted>").replace(/\b([A-Z0-9_]*(?:MONGODB_(?:URL|URI)|DATABASE_URL|TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY)[A-Z0-9_]*\s*=\s*)(?:"[^"]*"|'[^']*'|[^\s]+)/gi, "$1<redacted>").replace(/(\bAuthorization\s*:\s*Bearer\s+)[^\s'"]+/gi, "$1<redacted>");
|
|
672
664
|
}
|
|
673
665
|
function getErrorMessage(error) {
|
|
674
666
|
if (error instanceof Error) return redactSecrets(error.message);
|
|
@@ -703,12 +695,16 @@ async function runPrismaJsonCommand(options) {
|
|
|
703
695
|
"--json",
|
|
704
696
|
"--no-interactive"
|
|
705
697
|
]);
|
|
706
|
-
const
|
|
698
|
+
const subprocess = execa(invocation.command, invocation.args, {
|
|
707
699
|
cwd: options.projectDir,
|
|
708
700
|
env: process.env,
|
|
709
701
|
reject: false
|
|
710
702
|
});
|
|
711
|
-
|
|
703
|
+
const stderrLines = options.onStderrLine && subprocess.stderr ? (async () => {
|
|
704
|
+
const lines = createInterface({ input: subprocess.stderr });
|
|
705
|
+
for await (const line of lines) if (line.trim()) options.onStderrLine?.(line);
|
|
706
|
+
})() : Promise.resolve();
|
|
707
|
+
const [result] = await Promise.all([subprocess, stderrLines]);
|
|
712
708
|
let envelope;
|
|
713
709
|
try {
|
|
714
710
|
envelope = parsePrismaCliEnvelope(result.stdout);
|
|
@@ -722,6 +718,19 @@ async function runPrismaJsonCommand(options) {
|
|
|
722
718
|
}
|
|
723
719
|
return envelope.result;
|
|
724
720
|
}
|
|
721
|
+
function findProjectNameCollisions(projects, appName) {
|
|
722
|
+
return projects.filter((project) => project.name === appName);
|
|
723
|
+
}
|
|
724
|
+
async function ensureProjectNameAvailable(options) {
|
|
725
|
+
const collisions = findProjectNameCollisions((await runPrismaJsonCommand({
|
|
726
|
+
packageManager: options.packageManager,
|
|
727
|
+
projectDir: options.projectDir,
|
|
728
|
+
args: ["project", "list"]
|
|
729
|
+
})).items, options.appName);
|
|
730
|
+
if (collisions.length === 0) return;
|
|
731
|
+
const projectIds = collisions.map((project) => project.id).join(", ");
|
|
732
|
+
throw new Error(`A Prisma project named "${options.appName}" already exists in workspace ${workspaceLabel(options.workspace)} (${options.workspace.id}). Choose a different project name or delete the existing project (${projectIds}) in Prisma Console, then retry.`);
|
|
733
|
+
}
|
|
725
734
|
async function ensureAuthentication(packageManager, projectDir, beforeInteractiveLogin) {
|
|
726
735
|
const whoami = () => runPrismaJsonCommand({
|
|
727
736
|
packageManager,
|
|
@@ -843,8 +852,13 @@ async function getProjectDetails(options) {
|
|
|
843
852
|
return;
|
|
844
853
|
}
|
|
845
854
|
}
|
|
846
|
-
|
|
855
|
+
/**
|
|
856
|
+
* Performs the optional one-shot deployment at the end of a create-prisma scaffold.
|
|
857
|
+
* Generated projects use their own `deploy` script for every subsequent deployment.
|
|
858
|
+
*/
|
|
859
|
+
async function deployNewProjectWithComposer(options) {
|
|
847
860
|
const progress = options.verbose ? void 0 : spinner();
|
|
861
|
+
let deploymentLog;
|
|
848
862
|
let progressRunning = false;
|
|
849
863
|
const showProgress = (message) => {
|
|
850
864
|
if (!progress) return;
|
|
@@ -875,6 +889,14 @@ async function deployWithComposer(options) {
|
|
|
875
889
|
...options.workspace ? { workspace: options.workspace } : {}
|
|
876
890
|
});
|
|
877
891
|
if (!selectedWorkspace) return;
|
|
892
|
+
showProgress("Checking Prisma project name...");
|
|
893
|
+
if (options.verbose) log.step("Checking Prisma project name.");
|
|
894
|
+
await ensureProjectNameAvailable({
|
|
895
|
+
appName: options.appName,
|
|
896
|
+
packageManager: options.packageManager,
|
|
897
|
+
projectDir: options.projectDir,
|
|
898
|
+
workspace: selectedWorkspace
|
|
899
|
+
});
|
|
878
900
|
showProgress("Building for deployment...");
|
|
879
901
|
if (options.verbose) log.step("Building for deployment.");
|
|
880
902
|
const build = getRunScriptArgs(options.packageManager, "build");
|
|
@@ -883,22 +905,40 @@ async function deployWithComposer(options) {
|
|
|
883
905
|
env: process.env,
|
|
884
906
|
stdio: options.verbose ? "inherit" : "pipe"
|
|
885
907
|
});
|
|
886
|
-
|
|
887
|
-
|
|
908
|
+
clearProgress();
|
|
909
|
+
const deployCommand = getPackageExecutionCommand(options.packageManager, [
|
|
910
|
+
PRISMA_PLATFORM_CLI_PACKAGE,
|
|
911
|
+
"deploy",
|
|
912
|
+
"module.ts"
|
|
913
|
+
]);
|
|
914
|
+
if (options.verbose) log.step(`Deploying to Prisma with ${deployCommand}.`);
|
|
915
|
+
else {
|
|
916
|
+
deploymentLog = taskLog({
|
|
917
|
+
title: "Deploying to Prisma...",
|
|
918
|
+
limit: 10
|
|
919
|
+
});
|
|
920
|
+
deploymentLog.message(`$ ${deployCommand}`);
|
|
921
|
+
}
|
|
888
922
|
const deployment = parseComposerDeployResult(await runPrismaJsonCommand({
|
|
889
923
|
packageManager: options.packageManager,
|
|
890
924
|
projectDir: options.projectDir,
|
|
891
925
|
args: ["deploy", "module.ts"],
|
|
892
|
-
|
|
926
|
+
onStderrLine: (line) => {
|
|
927
|
+
const redactedLine = redactSecrets(line);
|
|
928
|
+
if (options.verbose) process.stderr.write(`${redactedLine}\n`);
|
|
929
|
+
else deploymentLog?.message(redactedLine);
|
|
930
|
+
}
|
|
893
931
|
}));
|
|
894
932
|
const appName = deployment?.appName ?? options.appName;
|
|
895
|
-
|
|
933
|
+
if (options.verbose) log.step("Loading deployment details.");
|
|
934
|
+
else deploymentLog?.message("Loading deployment details...");
|
|
896
935
|
const details = await getProjectDetails({
|
|
897
936
|
packageManager: options.packageManager,
|
|
898
937
|
projectDir: options.projectDir,
|
|
899
938
|
appName
|
|
900
939
|
});
|
|
901
|
-
|
|
940
|
+
deploymentLog?.success("Deployed to Prisma.");
|
|
941
|
+
deploymentLog = void 0;
|
|
902
942
|
progressRunning = false;
|
|
903
943
|
if (options.verbose) log.success("Deployed to Prisma.");
|
|
904
944
|
const workspace = details?.workspace ?? selectedWorkspace;
|
|
@@ -909,13 +949,73 @@ async function deployWithComposer(options) {
|
|
|
909
949
|
project: details?.project ?? { name: appName }
|
|
910
950
|
};
|
|
911
951
|
} catch (error) {
|
|
912
|
-
|
|
952
|
+
if (deploymentLog) {
|
|
953
|
+
deploymentLog.error("Deployment failed.");
|
|
954
|
+
deploymentLog = void 0;
|
|
955
|
+
} else progress?.error("Deployment failed.");
|
|
913
956
|
progressRunning = false;
|
|
914
957
|
log.error(`Deploy failed: ${getErrorMessage(error)}`);
|
|
915
958
|
return;
|
|
916
959
|
}
|
|
917
960
|
}
|
|
918
961
|
|
|
962
|
+
//#endregion
|
|
963
|
+
//#region src/tasks/initialize-git.ts
|
|
964
|
+
function errorMessage(error) {
|
|
965
|
+
if (error instanceof Error && "stderr" in error) {
|
|
966
|
+
const stderr = String(error.stderr ?? "").trim();
|
|
967
|
+
if (stderr) return stderr;
|
|
968
|
+
}
|
|
969
|
+
return error instanceof Error ? error.message : String(error);
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Initializes a standalone scaffold as a Git repository and records its generated files.
|
|
973
|
+
* Projects created inside an existing repository remain part of that repository.
|
|
974
|
+
*/
|
|
975
|
+
async function initializeGitRepository(projectDir, env = process.env) {
|
|
976
|
+
try {
|
|
977
|
+
const existing = await execa("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
978
|
+
cwd: projectDir,
|
|
979
|
+
env,
|
|
980
|
+
reject: false
|
|
981
|
+
});
|
|
982
|
+
if (existing.exitCode === 0 && existing.stdout.trim() === "true") return { status: "already-in-repository" };
|
|
983
|
+
} catch (error) {
|
|
984
|
+
return {
|
|
985
|
+
status: "skipped",
|
|
986
|
+
reason: errorMessage(error)
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
let initialized = false;
|
|
990
|
+
try {
|
|
991
|
+
await execa("git", ["init"], {
|
|
992
|
+
cwd: projectDir,
|
|
993
|
+
env
|
|
994
|
+
});
|
|
995
|
+
initialized = true;
|
|
996
|
+
await execa("git", ["add", "--all"], {
|
|
997
|
+
cwd: projectDir,
|
|
998
|
+
env
|
|
999
|
+
});
|
|
1000
|
+
await execa("git", [
|
|
1001
|
+
"commit",
|
|
1002
|
+
"--no-verify",
|
|
1003
|
+
"-m",
|
|
1004
|
+
"Initial commit from create-prisma"
|
|
1005
|
+
], {
|
|
1006
|
+
cwd: projectDir,
|
|
1007
|
+
env
|
|
1008
|
+
});
|
|
1009
|
+
return { status: "initialized" };
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
if (initialized) await fs.remove(path.join(projectDir, ".git"));
|
|
1012
|
+
return {
|
|
1013
|
+
status: "skipped",
|
|
1014
|
+
reason: errorMessage(error)
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
|
|
919
1019
|
//#endregion
|
|
920
1020
|
//#region src/tasks/setup-prisma.ts
|
|
921
1021
|
const DEFAULT_DATABASE_PROVIDER = "postgres";
|
|
@@ -1127,6 +1227,20 @@ async function emitContract(context, projectDir) {
|
|
|
1127
1227
|
stdio: context.verbose ? "inherit" : "pipe"
|
|
1128
1228
|
});
|
|
1129
1229
|
}
|
|
1230
|
+
async function planBaselineMigration(context, projectDir) {
|
|
1231
|
+
if (context.databaseProvider !== "postgres") return;
|
|
1232
|
+
const invocation = getPrismaCliInvocation(context.packageManager, [
|
|
1233
|
+
"migration",
|
|
1234
|
+
"plan",
|
|
1235
|
+
"--name",
|
|
1236
|
+
"init"
|
|
1237
|
+
]);
|
|
1238
|
+
if (context.verbose) log.step([invocation.command, ...invocation.args].join(" "));
|
|
1239
|
+
await execa(invocation.command, invocation.args, {
|
|
1240
|
+
cwd: projectDir,
|
|
1241
|
+
stdio: context.verbose ? "inherit" : "pipe"
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1130
1244
|
function formatNextSteps(steps) {
|
|
1131
1245
|
return steps.map((step) => `${step.command}\n ${step.description}`).join("\n\n");
|
|
1132
1246
|
}
|
|
@@ -1166,7 +1280,9 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
1166
1280
|
const projectName = options.projectName ?? path.basename(projectDir);
|
|
1167
1281
|
const template = options.template ?? "minimal";
|
|
1168
1282
|
const progress = context.verbose ? void 0 : options.progressSpinner ?? spinner();
|
|
1169
|
-
|
|
1283
|
+
const ownsProgress = progress !== void 0 && !options.progressSpinner;
|
|
1284
|
+
let gitInitialization;
|
|
1285
|
+
if (ownsProgress) progress.start("Creating Prisma 8 project...");
|
|
1170
1286
|
try {
|
|
1171
1287
|
progress?.message("Preparing Prisma 8 project files...");
|
|
1172
1288
|
await runPrismaInit(context, projectDir);
|
|
@@ -1181,13 +1297,25 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
1181
1297
|
await writePrismaDependencies(context.databaseProvider, context.packageManager, context.authoring, projectDir);
|
|
1182
1298
|
await ensureComposerTypeScriptOptions(projectDir);
|
|
1183
1299
|
if (context.databaseProvider === "mongo") await ensureMongoEnvironment(projectDir);
|
|
1300
|
+
if (context.packageManager !== "deno") {
|
|
1301
|
+
await ensureGitignoreEntry(projectDir, "/.alchemy");
|
|
1302
|
+
await ensureGitignoreEntry(projectDir, "/.prisma-composer");
|
|
1303
|
+
}
|
|
1184
1304
|
progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`);
|
|
1185
1305
|
await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
|
|
1186
1306
|
progress?.message("Installing Prisma agent skills...");
|
|
1187
1307
|
await initializeAgentSkills(context, projectDir);
|
|
1188
1308
|
progress?.message("Generating Prisma 8 contract artifacts...");
|
|
1189
1309
|
await emitContract(context, projectDir);
|
|
1310
|
+
progress?.message("Authoring the baseline migration...");
|
|
1311
|
+
await planBaselineMigration(context, projectDir);
|
|
1312
|
+
if (options.initializeGit) {
|
|
1313
|
+
progress?.message("Initializing Git repository...");
|
|
1314
|
+
gitInitialization = await initializeGitRepository(projectDir);
|
|
1315
|
+
}
|
|
1190
1316
|
progress?.stop("Prisma 8 project ready.");
|
|
1317
|
+
if (gitInitialization?.status === "initialized" && context.verbose) log.success("Initialized Git repository with an initial commit.");
|
|
1318
|
+
else if (gitInitialization?.status === "skipped") log.warn(`Could not initialize Git repository: ${gitInitialization.reason}`);
|
|
1191
1319
|
} catch (error) {
|
|
1192
1320
|
progress?.error("Could not create Prisma 8 project.");
|
|
1193
1321
|
cancel(getCommandErrorMessage(error));
|
|
@@ -1195,7 +1323,7 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
1195
1323
|
}
|
|
1196
1324
|
let deployment;
|
|
1197
1325
|
if (context.shouldDeploy) {
|
|
1198
|
-
deployment = await
|
|
1326
|
+
deployment = await deployNewProjectWithComposer({
|
|
1199
1327
|
appName: projectName,
|
|
1200
1328
|
packageManager: context.packageManager,
|
|
1201
1329
|
projectDir,
|
|
@@ -1490,6 +1618,7 @@ async function executeCreateContext(context) {
|
|
|
1490
1618
|
template: context.template,
|
|
1491
1619
|
createdProjectPath: context.targetDirectory,
|
|
1492
1620
|
includeDevNextStep: true,
|
|
1621
|
+
initializeGit: !context.targetPathState.exists || context.targetPathState.isEmptyDirectory,
|
|
1493
1622
|
progressSpinner: createSpinner
|
|
1494
1623
|
})) return {
|
|
1495
1624
|
ok: false,
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as DatabaseProviderSchema, i as CreateTemplateSchema, n as AuthoringStyleSchema, o as PackageManagerSchema, r as CreateCommandInputSchema, t as runCreateCommand } from "./create-
|
|
2
|
+
import { a as DatabaseProviderSchema, i as CreateTemplateSchema, n as AuthoringStyleSchema, o as PackageManagerSchema, r as CreateCommandInputSchema, t as runCreateCommand } from "./create-D_2SzXVU.mjs";
|
|
3
3
|
import { os } from "@orpc/server";
|
|
4
4
|
import { createCli } from "trpc-cli";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
|
|
7
7
|
//#region src/index.ts
|
|
8
|
-
const CLI_VERSION = "0.9.
|
|
8
|
+
const CLI_VERSION = "0.9.3-pr.65.238.1";
|
|
9
9
|
const CreateCliInputSchema = z.tuple([z.string().trim().min(1, "Please enter a valid project name").optional().describe("Project name / directory"), CreateCommandInputSchema]);
|
|
10
10
|
function normalizeCreateCliInput(input) {
|
|
11
11
|
const [projectName, options] = input;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-prisma",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3-pr.65.238.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Create Prisma 8 projects with first-party templates and great DX.",
|
|
6
6
|
"homepage": "https://github.com/prisma/create-prisma",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dev": "tsdown --watch",
|
|
38
38
|
"start": "bun run ./dist/cli.mjs",
|
|
39
39
|
"test": "bun run test:unit && bun run test:e2e",
|
|
40
|
-
"test:unit": "bun test ./tests/dependencies.test.ts ./tests/deploy-with-composer.test.ts ./tests/install.test.ts ./tests/node-version.test.ts ./tests/setup-prisma.test.ts ./tests/telemetry.test.ts",
|
|
40
|
+
"test:unit": "bun test ./tests/dependencies.test.ts ./tests/deploy-with-composer.test.ts ./tests/initialize-git.test.ts ./tests/install.test.ts ./tests/node-version.test.ts ./tests/setup-prisma.test.ts ./tests/telemetry.test.ts",
|
|
41
41
|
"test:e2e": "bun test --timeout 180000 ./tests/e2e/create-prisma.e2e.test.ts",
|
|
42
42
|
"check": "bun run format:check && bun run lint",
|
|
43
43
|
"lint": "oxlint . --deny-warnings",
|