create-prisma 0.9.2 → 0.9.3-pr.64.236.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-BAj76dgk.mjs} +138 -25
- 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.64.236.1",
|
|
53
45
|
"node-version": process.version,
|
|
54
46
|
platform: process.platform,
|
|
55
47
|
arch: process.arch
|
|
@@ -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";
|
|
@@ -1166,7 +1266,9 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
1166
1266
|
const projectName = options.projectName ?? path.basename(projectDir);
|
|
1167
1267
|
const template = options.template ?? "minimal";
|
|
1168
1268
|
const progress = context.verbose ? void 0 : options.progressSpinner ?? spinner();
|
|
1169
|
-
|
|
1269
|
+
const ownsProgress = progress !== void 0 && !options.progressSpinner;
|
|
1270
|
+
let gitInitialization;
|
|
1271
|
+
if (ownsProgress) progress.start("Creating Prisma 8 project...");
|
|
1170
1272
|
try {
|
|
1171
1273
|
progress?.message("Preparing Prisma 8 project files...");
|
|
1172
1274
|
await runPrismaInit(context, projectDir);
|
|
@@ -1181,13 +1283,23 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
1181
1283
|
await writePrismaDependencies(context.databaseProvider, context.packageManager, context.authoring, projectDir);
|
|
1182
1284
|
await ensureComposerTypeScriptOptions(projectDir);
|
|
1183
1285
|
if (context.databaseProvider === "mongo") await ensureMongoEnvironment(projectDir);
|
|
1286
|
+
if (context.packageManager !== "deno") {
|
|
1287
|
+
await ensureGitignoreEntry(projectDir, "/.alchemy");
|
|
1288
|
+
await ensureGitignoreEntry(projectDir, "/.prisma-composer");
|
|
1289
|
+
}
|
|
1184
1290
|
progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`);
|
|
1185
1291
|
await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
|
|
1186
1292
|
progress?.message("Installing Prisma agent skills...");
|
|
1187
1293
|
await initializeAgentSkills(context, projectDir);
|
|
1188
1294
|
progress?.message("Generating Prisma 8 contract artifacts...");
|
|
1189
1295
|
await emitContract(context, projectDir);
|
|
1296
|
+
if (options.initializeGit) {
|
|
1297
|
+
progress?.message("Initializing Git repository...");
|
|
1298
|
+
gitInitialization = await initializeGitRepository(projectDir);
|
|
1299
|
+
}
|
|
1190
1300
|
progress?.stop("Prisma 8 project ready.");
|
|
1301
|
+
if (gitInitialization?.status === "initialized" && context.verbose) log.success("Initialized Git repository with an initial commit.");
|
|
1302
|
+
else if (gitInitialization?.status === "skipped") log.warn(`Could not initialize Git repository: ${gitInitialization.reason}`);
|
|
1191
1303
|
} catch (error) {
|
|
1192
1304
|
progress?.error("Could not create Prisma 8 project.");
|
|
1193
1305
|
cancel(getCommandErrorMessage(error));
|
|
@@ -1195,7 +1307,7 @@ async function executePrismaSetupContext(context, options = {}) {
|
|
|
1195
1307
|
}
|
|
1196
1308
|
let deployment;
|
|
1197
1309
|
if (context.shouldDeploy) {
|
|
1198
|
-
deployment = await
|
|
1310
|
+
deployment = await deployNewProjectWithComposer({
|
|
1199
1311
|
appName: projectName,
|
|
1200
1312
|
packageManager: context.packageManager,
|
|
1201
1313
|
projectDir,
|
|
@@ -1490,6 +1602,7 @@ async function executeCreateContext(context) {
|
|
|
1490
1602
|
template: context.template,
|
|
1491
1603
|
createdProjectPath: context.targetDirectory,
|
|
1492
1604
|
includeDevNextStep: true,
|
|
1605
|
+
initializeGit: !context.targetPathState.exists || context.targetPathState.isEmptyDirectory,
|
|
1493
1606
|
progressSpinner: createSpinner
|
|
1494
1607
|
})) return {
|
|
1495
1608
|
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-BAj76dgk.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.64.236.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.64.236.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",
|