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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import "./create-DPrHKEg5.mjs";
2
+ import "./create-BAj76dgk.mjs";
3
3
  import { createCreatePrismaCli } from "./index.mjs";
4
4
 
5
5
  //#region src/cli.ts
@@ -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 = "phc_cmc85avbWyuJ2JyKdGPdv7dxXli8xLdWDBPbvIXWJfs";
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
- if (isTruthyEnvValue(process.env.CI) || isTruthyEnvValue(process.env.GITHUB_ACTIONS)) return true;
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.2",
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)?:\/\/)[^\s'"]+/gi, "$1<redacted>").replace(/\b([A-Z0-9_]*(?:DATABASE_URL|TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY)[A-Z0-9_]*=)[^\s]+/g, "$1<redacted>");
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 result = await execa(invocation.command, invocation.args, {
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
- if (options.forwardStderr && result.stderr) process.stderr.write(result.stderr.endsWith("\n") ? result.stderr : `${result.stderr}\n`);
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
- async function deployWithComposer(options) {
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
- showProgress("Deploying to Prisma...");
887
- if (options.verbose) log.step("Deploying to Prisma.");
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
- forwardStderr: options.verbose
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
- showProgress("Loading deployment details...");
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
- progress?.stop("Deployed to Prisma.");
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
- progress?.error("Deployment failed.");
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
- if (progress !== void 0 && !options.progressSpinner) progress.start("Creating Prisma 8 project...");
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 deployWithComposer({
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-DPrHKEg5.mjs";
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.2";
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.2",
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",