@prisma/cli 2.20.1 → 3.0.0-alpha.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.
Files changed (217) hide show
  1. package/LICENSE +158 -0
  2. package/README.md +29 -28
  3. package/dist/adapters/config.js +74 -0
  4. package/dist/adapters/local-state.js +98 -0
  5. package/dist/adapters/mock-api.js +57 -0
  6. package/dist/adapters/token-storage.js +43 -0
  7. package/dist/cli.js +9 -0
  8. package/dist/cli2.js +59 -0
  9. package/dist/commands/app/index.js +216 -0
  10. package/dist/commands/auth/index.js +42 -0
  11. package/dist/commands/branch/index.js +51 -0
  12. package/dist/commands/project/index.js +45 -0
  13. package/dist/controllers/app.js +834 -0
  14. package/dist/controllers/auth.js +107 -0
  15. package/dist/controllers/branch.js +73 -0
  16. package/dist/controllers/project.js +214 -0
  17. package/dist/controllers/select-prompt-port.js +12 -0
  18. package/dist/lib/app/bun-project.js +39 -0
  19. package/dist/lib/app/env-vars.js +24 -0
  20. package/dist/lib/app/local-dev.js +150 -0
  21. package/dist/lib/app/preview-build.js +142 -0
  22. package/dist/lib/app/preview-interaction.js +38 -0
  23. package/dist/lib/app/preview-progress.js +139 -0
  24. package/dist/lib/app/preview-provider.js +232 -0
  25. package/dist/lib/auth/auth-ops.js +57 -0
  26. package/dist/lib/auth/client.js +22 -0
  27. package/dist/lib/auth/guard.js +34 -0
  28. package/dist/lib/auth/login.js +117 -0
  29. package/dist/output/patterns.js +93 -0
  30. package/dist/presenters/app.js +405 -0
  31. package/dist/presenters/auth.js +73 -0
  32. package/dist/presenters/branch.js +111 -0
  33. package/dist/presenters/project.js +84 -0
  34. package/dist/shell/command-meta.js +329 -0
  35. package/dist/shell/command-runner.js +33 -0
  36. package/dist/shell/errors.js +66 -0
  37. package/dist/shell/global-flags.js +25 -0
  38. package/dist/shell/help.js +78 -0
  39. package/dist/shell/output.js +54 -0
  40. package/dist/shell/prompt.js +31 -0
  41. package/dist/shell/runtime.js +51 -0
  42. package/dist/shell/ui.js +59 -0
  43. package/dist/use-cases/auth.js +70 -0
  44. package/dist/use-cases/branch.js +95 -0
  45. package/dist/use-cases/create-cli-gateways.js +93 -0
  46. package/dist/use-cases/project.js +75 -0
  47. package/package.json +49 -137
  48. package/build/child.js +0 -4110
  49. package/build/index.js +0 -104447
  50. package/build/public/.DS_Store +0 -0
  51. package/build/public/assets/alert.60ea9f84.svg +0 -5
  52. package/build/public/assets/array.1a36c222.svg +0 -4
  53. package/build/public/assets/boolean.9188b434.svg +0 -4
  54. package/build/public/assets/browser.21a575be.js +0 -1
  55. package/build/public/assets/browser.38b7fdb1.js +0 -1
  56. package/build/public/assets/browser.cdd2249a.js +0 -1
  57. package/build/public/assets/chevron-down.24f76e3c.svg +0 -3
  58. package/build/public/assets/cross.c2610cf5.svg +0 -11
  59. package/build/public/assets/datetime.a3bf710a.svg +0 -4
  60. package/build/public/assets/download.8d34b65a.svg +0 -4
  61. package/build/public/assets/ellipsis.a8c5a34a.svg +0 -10
  62. package/build/public/assets/enum.7ec0b64c.svg +0 -6
  63. package/build/public/assets/folder.d77b8eaf.svg +0 -6
  64. package/build/public/assets/hamburger.5fdadeac.svg +0 -4
  65. package/build/public/assets/logotype.a960b169.svg +0 -4
  66. package/build/public/assets/number.85ddf96b.svg +0 -7
  67. package/build/public/assets/object.0ba944a6.svg +0 -5
  68. package/build/public/assets/play.8811691e.svg +0 -6
  69. package/build/public/assets/plus.8fbf7ad3.svg +0 -4
  70. package/build/public/assets/read.79154521.svg +0 -1
  71. package/build/public/assets/refresh.d5448ccc.svg +0 -4
  72. package/build/public/assets/search.2ed766ce.svg +0 -7
  73. package/build/public/assets/settings.5ad25af2.svg +0 -8
  74. package/build/public/assets/string.ea615a24.svg +0 -4
  75. package/build/public/assets/tick-indeterminate.aec8a44d.svg +0 -3
  76. package/build/public/assets/tick.8cbb6a93.svg +0 -4
  77. package/build/public/assets/vendor.c4d0f081.js +0 -354
  78. package/build/public/demo.html +0 -17
  79. package/build/public/demoChunk.js +0 -2
  80. package/build/public/electron-darwin.html +0 -19
  81. package/build/public/electron-linux.html +0 -18
  82. package/build/public/electron-mac.html +0 -18
  83. package/build/public/electron-win.html +0 -17
  84. package/build/public/electron-win32.html +0 -18
  85. package/build/public/electron.html +0 -17
  86. package/build/public/electronBus.js +0 -2
  87. package/build/public/electronChunk.js +0 -2
  88. package/build/public/favicon/apple-touch-icon.png +0 -0
  89. package/build/public/favicon/favicon-16x16.png +0 -0
  90. package/build/public/favicon/favicon-32x32.png +0 -0
  91. package/build/public/favicon/prisma.png +0 -0
  92. package/build/public/favicon.svg +0 -5
  93. package/build/public/fonts/.DS_Store +0 -0
  94. package/build/public/fonts/Inter.ttf +0 -0
  95. package/build/public/fonts/RobotoMono.ttf +0 -0
  96. package/build/public/icons/.DS_Store +0 -0
  97. package/build/public/icons/alert.svg +0 -5
  98. package/build/public/icons/array.svg +0 -4
  99. package/build/public/icons/bin.svg +0 -37
  100. package/build/public/icons/boolean.svg +0 -4
  101. package/build/public/icons/check.svg +0 -3
  102. package/build/public/icons/chevron-down.svg +0 -3
  103. package/build/public/icons/code.svg +0 -4
  104. package/build/public/icons/cross.svg +0 -11
  105. package/build/public/icons/data-tool.svg +0 -5
  106. package/build/public/icons/database.svg +0 -4
  107. package/build/public/icons/datetime.svg +0 -4
  108. package/build/public/icons/double-arrow-right.svg +0 -4
  109. package/build/public/icons/download.svg +0 -4
  110. package/build/public/icons/ellipsis.svg +0 -10
  111. package/build/public/icons/enum.svg +0 -6
  112. package/build/public/icons/expand.svg +0 -4
  113. package/build/public/icons/eye.svg +0 -20
  114. package/build/public/icons/filters.svg +0 -5
  115. package/build/public/icons/folder.svg +0 -6
  116. package/build/public/icons/hamburger.svg +0 -4
  117. package/build/public/icons/icon.svg +0 -199
  118. package/build/public/icons/logo.svg +0 -199
  119. package/build/public/icons/logotype.svg +0 -4
  120. package/build/public/icons/number.svg +0 -7
  121. package/build/public/icons/object.svg +0 -5
  122. package/build/public/icons/play.svg +0 -6
  123. package/build/public/icons/plus.svg +0 -4
  124. package/build/public/icons/refresh.svg +0 -4
  125. package/build/public/icons/search.svg +0 -7
  126. package/build/public/icons/settings.svg +0 -8
  127. package/build/public/icons/string.svg +0 -4
  128. package/build/public/icons/tick-indeterminate.svg +0 -3
  129. package/build/public/icons/tick.svg +0 -4
  130. package/build/public/illustrations/.DS_Store +0 -0
  131. package/build/public/illustrations/empty.svg +0 -1
  132. package/build/public/illustrations/read.svg +0 -1
  133. package/build/public/illustrations/searching.svg +0 -1
  134. package/build/public/images/.DS_Store +0 -0
  135. package/build/public/images/icon-1024.png +0 -0
  136. package/build/public/index.css +0 -1
  137. package/build/public/index.html +0 -49
  138. package/build/public/index.js +0 -1
  139. package/build/public/main.31f688a6254e294d9128.css +0 -118
  140. package/build/public/main.31f688a6254e294d9128.css.map +0 -1
  141. package/build/public/main.364c712f32662ff0e43d.css +0 -116
  142. package/build/public/main.364c712f32662ff0e43d.css.map +0 -1
  143. package/build/public/main.42ef3fe7e97347765c91.css +0 -118
  144. package/build/public/main.42ef3fe7e97347765c91.css.map +0 -1
  145. package/build/public/main.503446defafe7aeca2f3.css +0 -116
  146. package/build/public/main.503446defafe7aeca2f3.css.map +0 -1
  147. package/build/public/main.c50a3b5980fe26f78b65.css +0 -118
  148. package/build/public/main.c50a3b5980fe26f78b65.css.map +0 -1
  149. package/build/public/main.cda25e5813776c2af295.css +0 -116
  150. package/build/public/main.cda25e5813776c2af295.css.map +0 -1
  151. package/build/public/main.dbac3b290f78404ff579.css +0 -116
  152. package/build/public/main.dbac3b290f78404ff579.css.map +0 -1
  153. package/build/public/main.f8ce44e122e5e2b8f778.css +0 -118
  154. package/build/public/main.f8ce44e122e5e2b8f778.css.map +0 -1
  155. package/build/public/main.fc9ea7521a4aecce1a77.css +0 -118
  156. package/build/public/main.fc9ea7521a4aecce1a77.css.map +0 -1
  157. package/build/public/main.js +0 -403
  158. package/build/public/main.js.map +0 -1
  159. package/build/public/mainChunk.0a84f3ba4d2ab481e877.css +0 -116
  160. package/build/public/mainChunk.1b327d58afbddc917bce.css +0 -118
  161. package/build/public/mainChunk.2cdf583b2bd51aa67587.css +0 -118
  162. package/build/public/mainChunk.544af00f7e9ffcbe782c.css +0 -118
  163. package/build/public/mainChunk.56f96a13868b2b4a53be.css +0 -118
  164. package/build/public/mainChunk.5cee429bfbf06e7ecb39.css +0 -118
  165. package/build/public/mainChunk.a862474ed4cdb421ffa2.css +0 -118
  166. package/build/public/mainChunk.ada34153c4911b5ac22b.css +0 -118
  167. package/build/public/mainChunk.c16a8d01b2c49b2f2751.css +0 -118
  168. package/build/public/mainChunk.ca4a878d5478b9320be8.css +0 -116
  169. package/build/public/mainChunk.e3adc8758b4395546cef.css +0 -116
  170. package/build/public/mainChunk.f2c59fcbfc455d8b9de5.css +0 -118
  171. package/build/public/mainChunk.js +0 -396
  172. package/build/public/manifest.json +0 -34
  173. package/build/public/preview.html +0 -16
  174. package/build/public/previewBus.js +0 -2
  175. package/build/public/previewChunk.js +0 -2
  176. package/build/public/projects.html +0 -86
  177. package/build/public/server.html +0 -16
  178. package/build/public/serverBus.js +0 -2
  179. package/build/public/serverChunk.js +0 -2
  180. package/build/public/splash.html +0 -17
  181. package/build/public/studioBundle.828f34b1781061528841.css +0 -118
  182. package/build/public/studioBundle.bfe9138b2e0293fcb7da.css +0 -118
  183. package/build/public/studioBundle.c5b256eede880e502aac.css +0 -118
  184. package/build/public/studioBundle.e43df511c8e2e368900a.css +0 -118
  185. package/build/public/studioBundle.e69382554c2a2942ae32.css +0 -118
  186. package/build/public/studioBundle.ee21aa56a3999a2b380b.css +0 -118
  187. package/build/public/studioBundle.js +0 -396
  188. package/build/public/vercel.html +0 -16
  189. package/build/public/vercelChunk.js +0 -2
  190. package/build/public/views/index.pug +0 -89
  191. package/build/xdg-open +0 -1066
  192. package/install/index.js +0 -5
  193. package/preinstall/index.js +0 -46
  194. package/prisma-client/README.md +0 -27
  195. package/prisma-client/generator-build/.DS_Store +0 -0
  196. package/prisma-client/generator-build/index.js +0 -79697
  197. package/prisma-client/index-browser.js +0 -3
  198. package/prisma-client/index.d.ts +0 -1
  199. package/prisma-client/index.js +0 -11
  200. package/prisma-client/package.json +0 -138
  201. package/prisma-client/runtime/index-browser.d.ts +0 -267
  202. package/prisma-client/runtime/index-browser.js +0 -2273
  203. package/prisma-client/runtime/index.d.ts +0 -1018
  204. package/prisma-client/runtime/index.js +0 -35028
  205. package/prisma-client/scripts/backup-index-browser.js +0 -3
  206. package/prisma-client/scripts/backup-index.d.ts +0 -1
  207. package/prisma-client/scripts/backup-index.js +0 -11
  208. package/prisma-client/scripts/colors.js +0 -180
  209. package/prisma-client/scripts/default-index-browser.js +0 -12
  210. package/prisma-client/scripts/default-index.d.ts +0 -47
  211. package/prisma-client/scripts/default-index.js +0 -12
  212. package/prisma-client/scripts/get-packed-client.js +0 -12
  213. package/prisma-client/scripts/mock-fs.js +0 -14
  214. package/prisma-client/scripts/postinstall.d.ts +0 -5
  215. package/prisma-client/scripts/postinstall.js +0 -398
  216. package/scripts/install-entry.js +0 -8
  217. package/scripts/preinstall-entry.js +0 -9
@@ -0,0 +1,78 @@
1
+ import { formatDescriptorLabel, getDescriptorForCommand } from "./command-meta.js";
2
+ import { resolveGlobalFlags } from "./global-flags.js";
3
+ import { createShellUi, padDisplay, wrapText } from "./ui.js";
4
+ //#region src/shell/help.ts
5
+ function renderHelp(command, runtime) {
6
+ const descriptor = getDescriptorForCommand(command);
7
+ const ui = createShellUi(runtime, resolveGlobalFlags(runtime.argv, {}));
8
+ const rail = ui.isTTY ? ui.dim("│") : "│";
9
+ const lines = [`${formatDescriptorLabel(descriptor)} ${ui.dim("→")} ${ui.dim(descriptor.description)}`, ""];
10
+ const visibleCommands = command.commands.filter((candidate) => candidate.name() !== "help" && !candidate.hidden);
11
+ const visibleOptions = command.options.filter((candidate) => !candidate.hidden);
12
+ if (visibleCommands.length > 0) lines.push(...renderCommandRows(rail, ui, visibleCommands));
13
+ if (visibleOptions.length > 0) {
14
+ if (visibleCommands.length > 0) lines.push(`${rail}`);
15
+ lines.push(...renderOptionRows(rail, ui, visibleOptions));
16
+ }
17
+ if (descriptor.examples && descriptor.examples.length > 0) {
18
+ lines.push(`${rail}`);
19
+ lines.push(`${rail} Examples:`);
20
+ for (const example of descriptor.examples) lines.push(`${rail} $ ${example}`);
21
+ }
22
+ if (descriptor.longDescription) {
23
+ lines.push(`${rail}`);
24
+ const wrapped = wrapText(descriptor.longDescription, Math.max(ui.width - 3, 40));
25
+ for (const line of wrapped) lines.push(`${rail} ${line}`);
26
+ }
27
+ if (descriptor.docsPath) {
28
+ lines.push(`${rail}`);
29
+ lines.push(`${rail} ${ui.accent(padDisplay("Read more", 16))} ${ui.link(descriptor.docsPath)}`);
30
+ }
31
+ lines.push("");
32
+ return `${lines.join("\n")}`;
33
+ }
34
+ function renderCommandRows(rail, ui, commands) {
35
+ return renderAlignedRows(rail, ui, commands.map((command) => {
36
+ const descriptor = getDescriptorForCommand(command);
37
+ return {
38
+ term: renderCommandTerm(command),
39
+ description: descriptor.description
40
+ };
41
+ }));
42
+ }
43
+ function renderOptionRows(rail, ui, options) {
44
+ return renderAlignedRows(rail, ui, options.map((option) => ({
45
+ term: option.flags,
46
+ description: option.description || "",
47
+ defaultValue: option.defaultValueDescription ?? formatDefaultValue(option.defaultValue)
48
+ })));
49
+ }
50
+ function renderAlignedRows(rail, ui, rows) {
51
+ const termWidth = rows.reduce((width, row) => Math.max(width, row.term.length), 0);
52
+ const descriptionWidth = Math.max(ui.width - 3 - termWidth - 4, 30);
53
+ const lines = [];
54
+ for (const row of rows) {
55
+ const [firstLine, ...rest] = wrapText(row.description, descriptionWidth, " ".repeat(termWidth + 2));
56
+ lines.push(`${rail} ${ui.accent(padDisplay(row.term, termWidth))} ${firstLine}`);
57
+ for (const line of rest) lines.push(`${rail} ${" ".repeat(termWidth)} ${line.trimStart()}`);
58
+ if (row.defaultValue) lines.push(`${rail} ${" ".repeat(termWidth)} ${ui.dim(`default: ${row.defaultValue}`)}`);
59
+ }
60
+ return lines;
61
+ }
62
+ function renderCommandTerm(command) {
63
+ const argumentsList = command.registeredArguments.map(renderArgumentLabel).join(" ");
64
+ return `${command.name()}${argumentsList ? ` ${argumentsList}` : ""}`;
65
+ }
66
+ function renderArgumentLabel(argument) {
67
+ const name = argument.name();
68
+ return argument.required ? `<${name}>` : `[${name}]`;
69
+ }
70
+ function formatDefaultValue(value) {
71
+ if (value === void 0) return null;
72
+ if (Array.isArray(value)) return value.join(", ");
73
+ if (typeof value === "boolean" || typeof value === "number") return String(value);
74
+ if (typeof value === "string" && value.length > 0) return value;
75
+ return null;
76
+ }
77
+ //#endregion
78
+ export { renderHelp };
@@ -0,0 +1,54 @@
1
+ import { renderNextSteps, renderSummaryLine } from "./ui.js";
2
+ //#region src/shell/output.ts
3
+ function writeJsonSuccess(output, success) {
4
+ output.stdout.write(`${JSON.stringify({
5
+ ok: true,
6
+ ...success
7
+ }, null, 2)}\n`);
8
+ }
9
+ function writeJsonError(output, command, error) {
10
+ output.stdout.write(`${JSON.stringify({
11
+ ok: false,
12
+ command,
13
+ error: {
14
+ code: error.code,
15
+ domain: error.domain,
16
+ severity: error.severity,
17
+ summary: error.summary,
18
+ why: error.why,
19
+ fix: error.fix,
20
+ where: error.where,
21
+ meta: error.meta,
22
+ docsUrl: error.docsUrl
23
+ },
24
+ warnings: [],
25
+ nextSteps: error.nextSteps
26
+ }, null, 2)}\n`);
27
+ }
28
+ function writeHumanLines(output, lines) {
29
+ if (lines.length === 0) return;
30
+ output.stderr.write(`${lines.join("\n")}\n`);
31
+ }
32
+ function writeHumanError(output, ui, error, options) {
33
+ const lines = [renderSummaryLine(ui, "error", `${error.summary} [${error.code}]`)];
34
+ if (error.where) lines.push(...["", `Where: ${error.where}`]);
35
+ if (error.why) {
36
+ if (!error.where) lines.push("");
37
+ lines.push(`Why: ${error.why}`);
38
+ }
39
+ if (error.fix) lines.push(`Fix: ${error.fix}`);
40
+ if (options.trace) {
41
+ if (error.debug) {
42
+ lines.push("");
43
+ lines.push("Trace:");
44
+ lines.push(...error.debug.trimEnd().split("\n"));
45
+ }
46
+ } else {
47
+ lines.push("");
48
+ lines.push("More: Re-run with --trace for deeper diagnostics");
49
+ }
50
+ lines.push(...renderNextSteps(error.nextSteps));
51
+ writeHumanLines(output, lines);
52
+ }
53
+ //#endregion
54
+ export { writeHumanError, writeHumanLines, writeJsonError, writeJsonSuccess };
@@ -0,0 +1,31 @@
1
+ import { usageError } from "./errors.js";
2
+ import { isCancel, select, text } from "@clack/prompts";
3
+ //#region src/shell/prompt.ts
4
+ async function selectPrompt(options) {
5
+ const promptOptions = options.choices.map((choice) => ({
6
+ label: choice.label,
7
+ value: choice.value
8
+ }));
9
+ const response = await select({
10
+ input: options.input,
11
+ output: options.output,
12
+ message: options.message,
13
+ options: promptOptions
14
+ });
15
+ if (isCancel(response)) throw usageError("Interactive prompt canceled", "The command was canceled before a selection was made.", "Re-run the command and choose an option to continue.");
16
+ return response;
17
+ }
18
+ async function textPrompt(options) {
19
+ const response = await text({
20
+ input: options.input,
21
+ output: options.output,
22
+ message: options.message,
23
+ placeholder: options.placeholder,
24
+ validate: options.validate
25
+ });
26
+ if (isCancel(response)) throw usageError("Interactive prompt canceled", "The command was canceled before a value was entered.", "Re-run the command and provide a value to continue.");
27
+ return response;
28
+ }
29
+ function disposePromptState(_input) {}
30
+ //#endregion
31
+ export { disposePromptState, selectPrompt, textPrompt };
@@ -0,0 +1,51 @@
1
+ import { LocalStateStore } from "../adapters/local-state.js";
2
+ import { MockApi } from "../adapters/mock-api.js";
3
+ import { createShellUi } from "./ui.js";
4
+ import { renderHelp } from "./help.js";
5
+ import path from "node:path";
6
+ //#region src/shell/runtime.ts
7
+ const DEFAULT_STATE_DIR_NAME = path.join(".prisma", "cli");
8
+ function configureRuntimeCommand(command, runtime) {
9
+ return command.helpCommand(false).configureHelp({ formatHelp: (configuredCommand) => renderHelp(configuredCommand, runtime) }).configureOutput({
10
+ writeOut: (text) => {
11
+ runtime.stderr.write(text);
12
+ },
13
+ writeErr: (text) => {
14
+ runtime.stderr.write(text);
15
+ },
16
+ outputError: (text, write) => {
17
+ write(text);
18
+ }
19
+ }).exitOverride();
20
+ }
21
+ async function createCommandContext(runtime, flags) {
22
+ const fixturePath = runtime.fixturePath ?? runtime.env.PRISMA_CLI_MOCK_FIXTURE_PATH;
23
+ const stateDir = resolveStateDir(runtime);
24
+ let loadedApi;
25
+ if (fixturePath) loadedApi = await MockApi.load(fixturePath);
26
+ return {
27
+ get api() {
28
+ if (!loadedApi) throw new Error("context.api accessed in real mode. Set runtime.fixturePath or PRISMA_CLI_MOCK_FIXTURE_PATH to use fixture mode.");
29
+ return loadedApi;
30
+ },
31
+ stateStore: new LocalStateStore(stateDir),
32
+ output: {
33
+ stdout: runtime.stdout,
34
+ stderr: runtime.stderr
35
+ },
36
+ flags,
37
+ runtime,
38
+ ui: createShellUi(runtime, flags)
39
+ };
40
+ }
41
+ function resolveStateDir(runtime) {
42
+ return runtime.stateDir ?? runtime.env.PRISMA_CLI_STATE_DIR ?? path.join(runtime.cwd, DEFAULT_STATE_DIR_NAME);
43
+ }
44
+ function canPrompt(context) {
45
+ if (context.flags.json) return false;
46
+ if (context.flags.interactive === false) return false;
47
+ if (context.runtime.env.CI && context.flags.interactive !== true) return false;
48
+ return Boolean(context.runtime.stdin.isTTY && context.runtime.stderr.isTTY);
49
+ }
50
+ //#endregion
51
+ export { canPrompt, configureRuntimeCommand, createCommandContext };
@@ -0,0 +1,59 @@
1
+ import stringWidth from "string-width";
2
+ import stripAnsi from "strip-ansi";
3
+ import wrapAnsi from "wrap-ansi";
4
+ import { createColors } from "colorette";
5
+ //#region src/shell/ui.ts
6
+ const DEFAULT_WIDTH = 80;
7
+ function createShellUi(runtime, flags) {
8
+ const isTTY = Boolean(runtime.stderr.isTTY);
9
+ const colorEnabled = resolveColorEnabled(runtime, flags, isTTY);
10
+ const colors = createColors({ useColor: colorEnabled });
11
+ return {
12
+ isTTY,
13
+ colorEnabled,
14
+ width: runtime.stderr.columns && runtime.stderr.columns > 0 ? runtime.stderr.columns : DEFAULT_WIDTH,
15
+ quiet: flags.quiet,
16
+ verbose: flags.verbose,
17
+ trace: flags.trace,
18
+ accent: (text) => colors.cyan(text),
19
+ success: (text) => colors.greenBright(text),
20
+ error: (text) => colors.redBright(text),
21
+ warning: (text) => colors.yellow(text),
22
+ info: (text) => colors.blue(text),
23
+ link: (text) => colors.blue(text),
24
+ dim: (text) => colors.dim(text),
25
+ strong: (text) => colors.bold(text)
26
+ };
27
+ }
28
+ function renderSummaryLine(ui, status, text) {
29
+ return `${status === "success" ? ui.success("✔") : status === "error" ? ui.error("✘") : status === "warning" ? ui.warning("⚠") : ui.info("ℹ")} ${text}`;
30
+ }
31
+ function renderNextSteps(steps) {
32
+ if (steps.length === 0) return [];
33
+ return [
34
+ "",
35
+ steps.length === 1 ? "Next step:" : "Next steps:",
36
+ ...steps.map((step) => `- ${step}`)
37
+ ];
38
+ }
39
+ function wrapText(text, width, indent = "") {
40
+ return wrapAnsi(text, width, {
41
+ hard: false,
42
+ trim: false
43
+ }).split("\n").map((line, index) => index === 0 ? line : `${indent}${line}`);
44
+ }
45
+ function padDisplay(text, width) {
46
+ const padding = Math.max(width - stringWidth(stripAnsi(text)), 0);
47
+ return `${text}${" ".repeat(padding)}`;
48
+ }
49
+ function maskValue(value) {
50
+ return value.replace(/([A-Za-z0-9._%+-]{1,})(?=@)/g, "****").replace(/:\/\/[^:@/\s]+:[^@/\s]+@/g, "://****:****@");
51
+ }
52
+ function resolveColorEnabled(runtime, flags, isTTY) {
53
+ if (flags.color === true) return true;
54
+ if (flags.color === false) return false;
55
+ if (runtime.env.NO_COLOR !== void 0) return false;
56
+ return isTTY;
57
+ }
58
+ //#endregion
59
+ export { createShellUi, maskValue, padDisplay, renderNextSteps, renderSummaryLine, wrapText };
@@ -0,0 +1,70 @@
1
+ import { usageError } from "../shell/errors.js";
2
+ //#region src/use-cases/auth.ts
3
+ function createAuthUseCases(dependencies) {
4
+ return {
5
+ whoami: () => resolveCurrentAuthState(dependencies),
6
+ login: async (selection) => {
7
+ await dependencies.sessionGateway.writeAuthSession({
8
+ provider: selection.provider,
9
+ userId: selection.userId,
10
+ workspaceId: selection.workspaceId
11
+ });
12
+ return resolveCurrentAuthState(dependencies);
13
+ },
14
+ logout: async () => {
15
+ await dependencies.sessionGateway.clearAuthSession();
16
+ return resolveCurrentAuthState(dependencies);
17
+ },
18
+ listProviders: async () => dependencies.identityGateway.listProviders(),
19
+ resolveProvider: async (providerId) => {
20
+ const provider = dependencies.identityGateway.getProvider(providerId);
21
+ if (!provider) throw usageError("Login requires a valid mock provider", `The mock provider "${providerId}" does not exist.`, "Use --provider github or --provider google.", ["prisma auth login"], "auth");
22
+ return provider;
23
+ },
24
+ listUsersForProvider: async (providerId) => {
25
+ const users = dependencies.identityGateway.listUsersForProvider(providerId);
26
+ if (users.length === 0) throw usageError("Login requires a valid mock user", `No mock users support provider "${providerId}".`, "Update the fixture data or choose a different provider.", ["prisma auth login"], "auth");
27
+ return users;
28
+ },
29
+ resolveUserForProvider: async (providerId, userId) => {
30
+ const user = dependencies.identityGateway.getUserForProvider(providerId, userId);
31
+ if (!user) throw usageError("Login requires a valid mock user", `The mock user "${userId}" is not available for provider "${providerId}".`, "Choose a user that supports the selected provider.", ["prisma auth login"], "auth");
32
+ return user;
33
+ },
34
+ listWorkspacesForUser: async (userId) => dependencies.identityGateway.listUserWorkspaces(userId),
35
+ resolveWorkspaceForUser: async (userId, workspaceId) => {
36
+ const workspace = dependencies.identityGateway.getUserWorkspace(userId, workspaceId);
37
+ if (!workspace) throw usageError("Login requires a valid mock workspace", `The mock workspace "${workspaceId}" is not available for the selected user.`, "Choose a workspace that the selected user can access.", ["prisma auth login"], "auth");
38
+ return workspace;
39
+ }
40
+ };
41
+ }
42
+ async function resolveCurrentAuthState(dependencies) {
43
+ const [session, linkedProjectId] = await Promise.all([dependencies.sessionGateway.readAuthSession(), dependencies.projectConfigGateway.readLinkedProjectId()]);
44
+ if (!session) return {
45
+ authenticated: false,
46
+ provider: null,
47
+ user: null,
48
+ workspace: null,
49
+ linkedProjectId
50
+ };
51
+ const provider = dependencies.identityGateway.getProvider(session.provider);
52
+ const user = dependencies.identityGateway.getUser(session.userId);
53
+ const workspace = dependencies.identityGateway.getWorkspace(session.workspaceId);
54
+ if (!provider || !user || !workspace) return {
55
+ authenticated: false,
56
+ provider: null,
57
+ user: null,
58
+ workspace: null,
59
+ linkedProjectId
60
+ };
61
+ return {
62
+ authenticated: true,
63
+ provider: provider.id,
64
+ user,
65
+ workspace,
66
+ linkedProjectId
67
+ };
68
+ }
69
+ //#endregion
70
+ export { createAuthUseCases };
@@ -0,0 +1,95 @@
1
+ //#region src/use-cases/branch.ts
2
+ function createBranchUseCases(dependencies) {
3
+ return {
4
+ list: async () => {
5
+ const [linkedProjectId, activeBranch] = await Promise.all([dependencies.projectConfigGateway.readLinkedProjectId(), dependencies.branchStateGateway.readActiveBranch()]);
6
+ const remoteBranches = await listRemoteBranches(dependencies.branchGateway, linkedProjectId);
7
+ return {
8
+ linkedProjectId,
9
+ projectName: resolveProjectName(dependencies.projectGateway, linkedProjectId),
10
+ activeBranch,
11
+ branches: buildBranchSummaries(activeBranch, remoteBranches)
12
+ };
13
+ },
14
+ show: async () => {
15
+ const [linkedProjectId, activeBranch] = await Promise.all([dependencies.projectConfigGateway.readLinkedProjectId(), dependencies.branchStateGateway.readActiveBranch()]);
16
+ return {
17
+ linkedProjectId,
18
+ projectName: resolveProjectName(dependencies.projectGateway, linkedProjectId),
19
+ branch: buildBranchDetail(dependencies.branchGateway, linkedProjectId, activeBranch)
20
+ };
21
+ },
22
+ use: async (branchName) => {
23
+ await dependencies.branchStateGateway.writeActiveBranch(branchName);
24
+ const linkedProjectId = await dependencies.projectConfigGateway.readLinkedProjectId();
25
+ return {
26
+ linkedProjectId,
27
+ projectName: resolveProjectName(dependencies.projectGateway, linkedProjectId),
28
+ branch: buildBranchDetail(dependencies.branchGateway, linkedProjectId, branchName)
29
+ };
30
+ }
31
+ };
32
+ }
33
+ function resolveProjectName(projectGateway, linkedProjectId) {
34
+ if (!linkedProjectId) return null;
35
+ return projectGateway.getProject(linkedProjectId)?.name ?? null;
36
+ }
37
+ async function listRemoteBranches(branchGateway, linkedProjectId) {
38
+ if (!linkedProjectId) return [];
39
+ return branchGateway.listBranchesForProject(linkedProjectId);
40
+ }
41
+ function buildBranchSummaries(activeBranch, remoteBranches) {
42
+ const byName = /* @__PURE__ */ new Map();
43
+ for (const branch of remoteBranches) byName.set(branch.name, {
44
+ id: branch.id,
45
+ name: branch.name,
46
+ kind: branch.kind,
47
+ active: activeBranch === branch.name,
48
+ remoteState: true
49
+ });
50
+ if (!byName.has(activeBranch)) byName.set(activeBranch, {
51
+ id: activeBranch,
52
+ name: activeBranch,
53
+ kind: toBranchKind(activeBranch),
54
+ active: true,
55
+ remoteState: false
56
+ });
57
+ return sortBranches([...byName.values()]);
58
+ }
59
+ function buildBranchDetail(branchGateway, linkedProjectId, branchName) {
60
+ const kind = toBranchKind(branchName);
61
+ const remoteBranch = linkedProjectId ? branchGateway.getBranchForProject(linkedProjectId, branchName) : void 0;
62
+ return {
63
+ name: branchName,
64
+ kind,
65
+ active: true,
66
+ remoteState: Boolean(remoteBranch),
67
+ liveDeployment: remoteBranch && remoteBranch.currentDeploymentId ? toLiveDeployment(branchGateway.getDeployment(remoteBranch.currentDeploymentId)) : null
68
+ };
69
+ }
70
+ function toBranchKind(name) {
71
+ if (name === "production") return "production";
72
+ return "preview";
73
+ }
74
+ function sortBranches(branches) {
75
+ return branches.slice().sort((left, right) => {
76
+ const leftRank = branchOrder(left);
77
+ const rightRank = branchOrder(right);
78
+ if (leftRank !== rightRank) return leftRank - rightRank;
79
+ return left.name.localeCompare(right.name);
80
+ });
81
+ }
82
+ function branchOrder(branch) {
83
+ if (branch.name === "production") return 0;
84
+ return 1;
85
+ }
86
+ function toLiveDeployment(deployment) {
87
+ if (!deployment) return null;
88
+ return {
89
+ id: deployment.id,
90
+ status: deployment.status,
91
+ url: deployment.url
92
+ };
93
+ }
94
+ //#endregion
95
+ export { createBranchUseCases };
@@ -0,0 +1,93 @@
1
+ import { UnsafeConfigWriteError, readLinkedProjectId, writeLinkedProjectId } from "../adapters/config.js";
2
+ import { usageError } from "../shell/errors.js";
3
+ //#region src/use-cases/create-cli-gateways.ts
4
+ function createCliUseCaseGateways(context) {
5
+ return {
6
+ identityGateway: {
7
+ listProviders: () => context.api.listProviders(),
8
+ getProvider: (providerId) => context.api.getProvider(providerId),
9
+ listUsersForProvider: (providerId) => context.api.listUsersForProvider(providerId).map(toAuthUser),
10
+ getUser: (userId) => {
11
+ const user = context.api.getUser(userId);
12
+ return user ? toAuthUser(user) : void 0;
13
+ },
14
+ getUserForProvider: (providerId, userId) => {
15
+ const user = context.api.getUserForProvider(providerId, userId);
16
+ return user ? toAuthUser(user) : void 0;
17
+ },
18
+ listUserWorkspaces: (userId) => context.api.listUserWorkspaces(userId).map(toAuthWorkspace),
19
+ getWorkspace: (workspaceId) => {
20
+ const workspace = context.api.getWorkspace(workspaceId);
21
+ return workspace ? toAuthWorkspace(workspace) : void 0;
22
+ },
23
+ getUserWorkspace: (userId, workspaceId) => {
24
+ const workspace = context.api.getUserWorkspace(userId, workspaceId);
25
+ return workspace ? toAuthWorkspace(workspace) : void 0;
26
+ }
27
+ },
28
+ projectGateway: {
29
+ listProjectsForWorkspace: (workspaceId) => context.api.listProjectsForWorkspace(workspaceId),
30
+ getProject: (projectId) => context.api.getProject(projectId),
31
+ getProjectForWorkspace: (workspaceId, projectId) => context.api.getProjectForWorkspace(workspaceId, projectId)
32
+ },
33
+ branchGateway: {
34
+ listBranchesForProject: (projectId) => context.api.listBranchesForProject(projectId).map((branch) => ({
35
+ ...branch,
36
+ kind: branch.name === "production" ? "production" : "preview"
37
+ })),
38
+ getBranchForProject: (projectId, name) => {
39
+ const branch = context.api.getBranchForProject(projectId, name);
40
+ return branch ? {
41
+ ...branch,
42
+ kind: branch.name === "production" ? "production" : "preview"
43
+ } : void 0;
44
+ },
45
+ getDeployment: (deploymentId) => context.api.getDeployment(deploymentId)
46
+ },
47
+ projectConfigGateway: {
48
+ readLinkedProjectId: () => readLinkedProjectId(context.runtime.cwd),
49
+ writeLinkedProjectId: async (projectId) => {
50
+ try {
51
+ await writeLinkedProjectId(context.runtime.cwd, projectId);
52
+ } catch (error) {
53
+ if (error instanceof UnsafeConfigWriteError) throw usageError("Project link requires a writable Prisma config", error.message, "Update prisma.config.ts to use a recognizable project field, or remove it and rerun prisma project link.", ["prisma project link proj_123"], "project");
54
+ throw error;
55
+ }
56
+ }
57
+ },
58
+ sessionGateway: {
59
+ readAuthSession: async () => {
60
+ return (await context.stateStore.read()).auth;
61
+ },
62
+ writeAuthSession: async (session) => {
63
+ await context.stateStore.setAuthSession(session);
64
+ },
65
+ clearAuthSession: async () => {
66
+ await context.stateStore.clearAuthSession();
67
+ }
68
+ },
69
+ branchStateGateway: {
70
+ readActiveBranch: async () => {
71
+ return (await context.stateStore.read()).branch.active;
72
+ },
73
+ writeActiveBranch: async (branchName) => {
74
+ await context.stateStore.setActiveBranch(branchName);
75
+ }
76
+ }
77
+ };
78
+ }
79
+ function toAuthUser(user) {
80
+ return {
81
+ id: user.id,
82
+ name: user.name,
83
+ email: user.email
84
+ };
85
+ }
86
+ function toAuthWorkspace(workspace) {
87
+ return {
88
+ id: workspace.id,
89
+ name: workspace.name
90
+ };
91
+ }
92
+ //#endregion
93
+ export { createCliUseCaseGateways };
@@ -0,0 +1,75 @@
1
+ import { CliError, authRequiredError } from "../shell/errors.js";
2
+ //#region src/use-cases/project.ts
3
+ function createProjectUseCases(dependencies) {
4
+ return {
5
+ list: async (authState) => {
6
+ const workspace = requireWorkspace(authState);
7
+ return {
8
+ workspace,
9
+ linkedProjectId: authState.linkedProjectId,
10
+ projects: listSortedWorkspaceProjects(dependencies.projectGateway, workspace.id).map(toProjectSummary)
11
+ };
12
+ },
13
+ show: async (authState) => {
14
+ if (!authState.linkedProjectId) return {
15
+ linkedProjectId: null,
16
+ workspace: null,
17
+ project: null
18
+ };
19
+ if (!authState.authenticated || !authState.workspace) return {
20
+ linkedProjectId: authState.linkedProjectId,
21
+ workspace: null,
22
+ project: null
23
+ };
24
+ const project = dependencies.projectGateway.getProjectForWorkspace(authState.workspace.id, authState.linkedProjectId);
25
+ if (!project) return {
26
+ linkedProjectId: authState.linkedProjectId,
27
+ workspace: null,
28
+ project: null
29
+ };
30
+ return {
31
+ linkedProjectId: authState.linkedProjectId,
32
+ workspace: authState.workspace,
33
+ project: toProjectSummary(project)
34
+ };
35
+ },
36
+ link: async (authState, projectId) => {
37
+ const workspace = requireWorkspace(authState);
38
+ const project = dependencies.projectGateway.getProjectForWorkspace(workspace.id, projectId);
39
+ if (!project) throw projectNotFoundError(`The project "${projectId}" does not exist in workspace "${workspace.name}".`, "Run prisma project list and choose a project id from the active workspace.");
40
+ await dependencies.projectConfigGateway.writeLinkedProjectId(project.id);
41
+ return {
42
+ linkedProjectId: project.id,
43
+ workspace,
44
+ project: toProjectSummary(project)
45
+ };
46
+ },
47
+ listProjectsForWorkspace: async (workspaceId) => listSortedWorkspaceProjects(dependencies.projectGateway, workspaceId).map(toProjectSummary)
48
+ };
49
+ }
50
+ function requireWorkspace(authState) {
51
+ if (!authState.authenticated || !authState.workspace) throw authRequiredError();
52
+ return authState.workspace;
53
+ }
54
+ function listSortedWorkspaceProjects(projectGateway, workspaceId) {
55
+ return projectGateway.listProjectsForWorkspace(workspaceId).slice().sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id));
56
+ }
57
+ function toProjectSummary(project) {
58
+ return {
59
+ id: project.id,
60
+ name: project.name
61
+ };
62
+ }
63
+ function projectNotFoundError(why, fix, nextSteps = ["prisma project list"]) {
64
+ return new CliError({
65
+ code: "PROJECT_NOT_FOUND",
66
+ domain: "project",
67
+ summary: "Project not found",
68
+ why,
69
+ fix,
70
+ exitCode: 1,
71
+ nextSteps
72
+ });
73
+ }
74
+ //#endregion
75
+ export { createProjectUseCases, projectNotFoundError };