@prisma-next/cli 0.1.0-pr.32.8 → 0.1.0-pr.34.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/README.md +16 -0
- package/dist/chunk-3EODSNGS.js +914 -0
- package/dist/chunk-3EODSNGS.js.map +1 -0
- package/dist/chunk-4Q3MO4TK.js +134 -0
- package/dist/chunk-4Q3MO4TK.js.map +1 -0
- package/dist/chunk-HWYQOCAJ.js +47 -0
- package/dist/chunk-HWYQOCAJ.js.map +1 -0
- package/dist/commands/contract-emit.d.ts +5 -0
- package/dist/commands/contract-emit.js +9 -0
- package/dist/commands/contract-emit.js.map +1 -0
- package/dist/commands/db-introspect.d.ts +5 -0
- package/dist/commands/db-introspect.js +181 -0
- package/dist/commands/db-introspect.js.map +1 -0
- package/dist/commands/db-schema-verify.d.ts +5 -0
- package/dist/commands/db-schema-verify.js +147 -0
- package/dist/commands/db-schema-verify.js.map +1 -0
- package/dist/commands/db-sign.d.ts +5 -0
- package/dist/commands/db-sign.js +186 -0
- package/dist/commands/db-sign.js.map +1 -0
- package/dist/commands/db-verify.d.ts +5 -0
- package/dist/commands/db-verify.js +164 -0
- package/dist/commands/db-verify.js.map +1 -0
- package/dist/config-loader.d.ts +14 -0
- package/dist/config-loader.js +7 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +6 -631
- package/dist/index.js.map +1 -1
- package/package.json +33 -9
|
@@ -0,0 +1,914 @@
|
|
|
1
|
+
// src/utils/command-helpers.ts
|
|
2
|
+
function setCommandDescriptions(command, shortDescription, longDescription) {
|
|
3
|
+
command.description(shortDescription);
|
|
4
|
+
if (longDescription) {
|
|
5
|
+
command._longDescription = longDescription;
|
|
6
|
+
}
|
|
7
|
+
return command;
|
|
8
|
+
}
|
|
9
|
+
function getLongDescription(command) {
|
|
10
|
+
return command._longDescription;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/utils/global-flags.ts
|
|
14
|
+
function parseGlobalFlags(options) {
|
|
15
|
+
const flags = {};
|
|
16
|
+
if (options.json === true || options.json === "object") {
|
|
17
|
+
flags.json = "object";
|
|
18
|
+
} else if (options.json === "ndjson") {
|
|
19
|
+
flags.json = "ndjson";
|
|
20
|
+
}
|
|
21
|
+
if (options.quiet || options.q) {
|
|
22
|
+
flags.quiet = true;
|
|
23
|
+
}
|
|
24
|
+
if (options.vv || options.trace) {
|
|
25
|
+
flags.verbose = 2;
|
|
26
|
+
} else if (options.verbose || options.v) {
|
|
27
|
+
flags.verbose = 1;
|
|
28
|
+
} else {
|
|
29
|
+
flags.verbose = 0;
|
|
30
|
+
}
|
|
31
|
+
if (options.timestamps) {
|
|
32
|
+
flags.timestamps = true;
|
|
33
|
+
}
|
|
34
|
+
if (process.env["NO_COLOR"] || flags.json) {
|
|
35
|
+
flags.color = false;
|
|
36
|
+
} else if (options["no-color"]) {
|
|
37
|
+
flags.color = false;
|
|
38
|
+
} else if (options.color !== void 0) {
|
|
39
|
+
flags.color = options.color;
|
|
40
|
+
} else {
|
|
41
|
+
flags.color = process.stdout.isTTY && !process.env["CI"];
|
|
42
|
+
}
|
|
43
|
+
return flags;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/utils/output.ts
|
|
47
|
+
import { relative } from "path";
|
|
48
|
+
import { bgGreen, blue, bold, cyan, dim, green, magenta, red, yellow } from "colorette";
|
|
49
|
+
import stringWidth from "string-width";
|
|
50
|
+
import stripAnsi from "strip-ansi";
|
|
51
|
+
import wrapAnsi from "wrap-ansi";
|
|
52
|
+
function formatTimestamp() {
|
|
53
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
54
|
+
}
|
|
55
|
+
function createPrefix(flags) {
|
|
56
|
+
return flags.timestamps ? `[${formatTimestamp()}] ` : "";
|
|
57
|
+
}
|
|
58
|
+
function isVerbose(flags, level) {
|
|
59
|
+
return (flags.verbose ?? 0) >= level;
|
|
60
|
+
}
|
|
61
|
+
function createColorFormatter(useColor, colorFn) {
|
|
62
|
+
return useColor ? colorFn : (text) => text;
|
|
63
|
+
}
|
|
64
|
+
function formatDim(useColor, text) {
|
|
65
|
+
return useColor ? dim(text) : text;
|
|
66
|
+
}
|
|
67
|
+
function formatEmitOutput(result, flags) {
|
|
68
|
+
if (flags.quiet) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
const lines = [];
|
|
72
|
+
const prefix = createPrefix(flags);
|
|
73
|
+
const jsonPath = relative(process.cwd(), result.files.json);
|
|
74
|
+
const dtsPath = relative(process.cwd(), result.files.dts);
|
|
75
|
+
lines.push(`${prefix}\u2714 Emitted contract.json \u2192 ${jsonPath}`);
|
|
76
|
+
lines.push(`${prefix}\u2714 Emitted contract.d.ts \u2192 ${dtsPath}`);
|
|
77
|
+
lines.push(`${prefix} coreHash: ${result.coreHash}`);
|
|
78
|
+
if (result.profileHash) {
|
|
79
|
+
lines.push(`${prefix} profileHash: ${result.profileHash}`);
|
|
80
|
+
}
|
|
81
|
+
if (isVerbose(flags, 1)) {
|
|
82
|
+
lines.push(`${prefix} Total time: ${result.timings.total}ms`);
|
|
83
|
+
}
|
|
84
|
+
return lines.join("\n");
|
|
85
|
+
}
|
|
86
|
+
function formatEmitJson(result) {
|
|
87
|
+
const output = {
|
|
88
|
+
ok: true,
|
|
89
|
+
coreHash: result.coreHash,
|
|
90
|
+
...result.profileHash ? { profileHash: result.profileHash } : {},
|
|
91
|
+
outDir: result.outDir,
|
|
92
|
+
files: result.files,
|
|
93
|
+
timings: result.timings
|
|
94
|
+
};
|
|
95
|
+
return JSON.stringify(output, null, 2);
|
|
96
|
+
}
|
|
97
|
+
function formatErrorOutput(error, flags) {
|
|
98
|
+
const lines = [];
|
|
99
|
+
const prefix = createPrefix(flags);
|
|
100
|
+
const useColor = flags.color !== false;
|
|
101
|
+
const formatRed = createColorFormatter(useColor, red);
|
|
102
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
103
|
+
lines.push(`${prefix}${formatRed("\u2716")} ${error.summary} (${error.code})`);
|
|
104
|
+
if (error.why) {
|
|
105
|
+
lines.push(`${prefix}${formatDimText(` Why: ${error.why}`)}`);
|
|
106
|
+
}
|
|
107
|
+
if (error.fix) {
|
|
108
|
+
lines.push(`${prefix}${formatDimText(` Fix: ${error.fix}`)}`);
|
|
109
|
+
}
|
|
110
|
+
if (error.where?.path) {
|
|
111
|
+
const whereLine = error.where.line ? `${error.where.path}:${error.where.line}` : error.where.path;
|
|
112
|
+
lines.push(`${prefix}${formatDimText(` Where: ${whereLine}`)}`);
|
|
113
|
+
}
|
|
114
|
+
if (error.docsUrl && isVerbose(flags, 1)) {
|
|
115
|
+
lines.push(formatDimText(error.docsUrl));
|
|
116
|
+
}
|
|
117
|
+
if (isVerbose(flags, 2) && error.meta) {
|
|
118
|
+
lines.push(`${prefix}${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);
|
|
119
|
+
}
|
|
120
|
+
return lines.join("\n");
|
|
121
|
+
}
|
|
122
|
+
function formatErrorJson(error) {
|
|
123
|
+
return JSON.stringify(error, null, 2);
|
|
124
|
+
}
|
|
125
|
+
function formatVerifyOutput(result, flags) {
|
|
126
|
+
if (flags.quiet) {
|
|
127
|
+
return "";
|
|
128
|
+
}
|
|
129
|
+
const lines = [];
|
|
130
|
+
const prefix = createPrefix(flags);
|
|
131
|
+
const useColor = flags.color !== false;
|
|
132
|
+
const formatGreen = createColorFormatter(useColor, green);
|
|
133
|
+
const formatRed = createColorFormatter(useColor, red);
|
|
134
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
135
|
+
if (result.ok) {
|
|
136
|
+
lines.push(`${prefix}${formatGreen("\u2714")} ${result.summary}`);
|
|
137
|
+
lines.push(`${prefix}${formatDimText(` coreHash: ${result.contract.coreHash}`)}`);
|
|
138
|
+
if (result.contract.profileHash) {
|
|
139
|
+
lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
lines.push(`${prefix}${formatRed("\u2716")} ${result.summary} (${result.code})`);
|
|
143
|
+
}
|
|
144
|
+
if (isVerbose(flags, 1)) {
|
|
145
|
+
if (result.codecCoverageSkipped) {
|
|
146
|
+
lines.push(
|
|
147
|
+
`${prefix}${formatDimText(" Codec coverage check skipped (helper returned no supported types)")}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);
|
|
151
|
+
}
|
|
152
|
+
return lines.join("\n");
|
|
153
|
+
}
|
|
154
|
+
function formatVerifyJson(result) {
|
|
155
|
+
const output = {
|
|
156
|
+
ok: result.ok,
|
|
157
|
+
...result.code ? { code: result.code } : {},
|
|
158
|
+
summary: result.summary,
|
|
159
|
+
contract: result.contract,
|
|
160
|
+
...result.marker ? { marker: result.marker } : {},
|
|
161
|
+
target: result.target,
|
|
162
|
+
...result.missingCodecs ? { missingCodecs: result.missingCodecs } : {},
|
|
163
|
+
...result.meta ? { meta: result.meta } : {},
|
|
164
|
+
timings: result.timings
|
|
165
|
+
};
|
|
166
|
+
return JSON.stringify(output, null, 2);
|
|
167
|
+
}
|
|
168
|
+
function formatIntrospectJson(result) {
|
|
169
|
+
return JSON.stringify(result, null, 2);
|
|
170
|
+
}
|
|
171
|
+
function renderSchemaTree(node, flags, options) {
|
|
172
|
+
const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;
|
|
173
|
+
const lines = [];
|
|
174
|
+
let formattedLabel = node.label;
|
|
175
|
+
if (useColor) {
|
|
176
|
+
switch (node.kind) {
|
|
177
|
+
case "root":
|
|
178
|
+
formattedLabel = bold(node.label);
|
|
179
|
+
break;
|
|
180
|
+
case "entity": {
|
|
181
|
+
const tableMatch = node.label.match(/^table\s+(.+)$/);
|
|
182
|
+
if (tableMatch?.[1]) {
|
|
183
|
+
const tableName = tableMatch[1];
|
|
184
|
+
formattedLabel = `${dim("table")} ${cyan(tableName)}`;
|
|
185
|
+
} else {
|
|
186
|
+
formattedLabel = cyan(node.label);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
case "collection": {
|
|
191
|
+
formattedLabel = dim(node.label);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
case "field": {
|
|
195
|
+
const columnMatch = node.label.match(/^([^:]+):\s*(.+)$/);
|
|
196
|
+
if (columnMatch?.[1] && columnMatch[2]) {
|
|
197
|
+
const columnName = columnMatch[1];
|
|
198
|
+
const rest = columnMatch[2];
|
|
199
|
+
const typeMatch = rest.match(/^([^\s(]+)\s*(\([^)]+\))$/);
|
|
200
|
+
if (typeMatch?.[1] && typeMatch[2]) {
|
|
201
|
+
const typeDisplay = typeMatch[1];
|
|
202
|
+
const nullability = typeMatch[2];
|
|
203
|
+
formattedLabel = `${cyan(columnName)}: ${typeDisplay} ${dim(nullability)}`;
|
|
204
|
+
} else {
|
|
205
|
+
formattedLabel = `${cyan(columnName)}: ${rest}`;
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
formattedLabel = node.label;
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
case "index": {
|
|
213
|
+
const pkMatch = node.label.match(/^primary key:\s*(.+)$/);
|
|
214
|
+
if (pkMatch?.[1]) {
|
|
215
|
+
const columnNames = pkMatch[1];
|
|
216
|
+
formattedLabel = `${dim("primary key")}: ${cyan(columnNames)}`;
|
|
217
|
+
} else {
|
|
218
|
+
const uniqueMatch = node.label.match(/^unique\s+(.+)$/);
|
|
219
|
+
if (uniqueMatch?.[1]) {
|
|
220
|
+
const name = uniqueMatch[1];
|
|
221
|
+
formattedLabel = `${dim("unique")} ${cyan(name)}`;
|
|
222
|
+
} else {
|
|
223
|
+
const indexMatch = node.label.match(/^(unique\s+)?index\s+(.+)$/);
|
|
224
|
+
if (indexMatch?.[2]) {
|
|
225
|
+
const prefix2 = indexMatch[1] ? `${dim("unique")} ` : "";
|
|
226
|
+
const name = indexMatch[2];
|
|
227
|
+
formattedLabel = `${prefix2}${dim("index")} ${cyan(name)}`;
|
|
228
|
+
} else {
|
|
229
|
+
formattedLabel = dim(node.label);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
case "extension": {
|
|
236
|
+
const extMatch = node.label.match(/^([^\s]+)\s+(extension is enabled)$/);
|
|
237
|
+
if (extMatch?.[1] && extMatch[2]) {
|
|
238
|
+
const extName = extMatch[1];
|
|
239
|
+
const rest = extMatch[2];
|
|
240
|
+
formattedLabel = `${cyan(extName)} ${dim(rest)}`;
|
|
241
|
+
} else {
|
|
242
|
+
formattedLabel = magenta(node.label);
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
default:
|
|
247
|
+
formattedLabel = node.label;
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (isRoot) {
|
|
252
|
+
lines.push(formattedLabel);
|
|
253
|
+
} else {
|
|
254
|
+
const treeChar = isLast ? "\u2514" : "\u251C";
|
|
255
|
+
const treePrefix = `${prefix}${formatDimText(treeChar)}\u2500 `;
|
|
256
|
+
const isRootChild = prefix === "";
|
|
257
|
+
const prefixWithoutAnsi = stripAnsi(prefix);
|
|
258
|
+
const prefixHasVerticalBar = prefixWithoutAnsi.includes("\u2502");
|
|
259
|
+
if (isRootChild) {
|
|
260
|
+
lines.push(`${treePrefix}${formattedLabel}`);
|
|
261
|
+
} else if (prefixHasVerticalBar) {
|
|
262
|
+
lines.push(`${treePrefix}${formattedLabel}`);
|
|
263
|
+
} else {
|
|
264
|
+
lines.push(`${formatDimText("\u2502")} ${treePrefix}${formattedLabel}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (node.children && node.children.length > 0) {
|
|
268
|
+
const childPrefix = isRoot ? "" : isLast ? `${prefix} ` : `${prefix}${formatDimText("\u2502")} `;
|
|
269
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
270
|
+
const child = node.children[i];
|
|
271
|
+
if (!child) continue;
|
|
272
|
+
const isLastChild = i === node.children.length - 1;
|
|
273
|
+
const childLines = renderSchemaTree(child, flags, {
|
|
274
|
+
isLast: isLastChild,
|
|
275
|
+
prefix: childPrefix,
|
|
276
|
+
useColor,
|
|
277
|
+
formatDimText,
|
|
278
|
+
isRoot: false
|
|
279
|
+
});
|
|
280
|
+
lines.push(...childLines);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return lines;
|
|
284
|
+
}
|
|
285
|
+
function formatIntrospectOutput(result, schemaView, flags) {
|
|
286
|
+
if (flags.quiet) {
|
|
287
|
+
return "";
|
|
288
|
+
}
|
|
289
|
+
const lines = [];
|
|
290
|
+
const prefix = createPrefix(flags);
|
|
291
|
+
const useColor = flags.color !== false;
|
|
292
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
293
|
+
if (schemaView) {
|
|
294
|
+
const treeLines = renderSchemaTree(schemaView.root, flags, {
|
|
295
|
+
isLast: true,
|
|
296
|
+
prefix: "",
|
|
297
|
+
useColor,
|
|
298
|
+
formatDimText,
|
|
299
|
+
isRoot: true
|
|
300
|
+
});
|
|
301
|
+
const prefixedTreeLines = treeLines.map((line) => `${prefix}${line}`);
|
|
302
|
+
lines.push(...prefixedTreeLines);
|
|
303
|
+
} else {
|
|
304
|
+
lines.push(`${prefix}\u2714 ${result.summary}`);
|
|
305
|
+
if (isVerbose(flags, 1)) {
|
|
306
|
+
lines.push(`${prefix} Target: ${result.target.familyId}/${result.target.id}`);
|
|
307
|
+
if (result.meta?.dbUrl) {
|
|
308
|
+
lines.push(`${prefix} Database: ${result.meta.dbUrl}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (isVerbose(flags, 1)) {
|
|
313
|
+
lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);
|
|
314
|
+
}
|
|
315
|
+
return lines.join("\n");
|
|
316
|
+
}
|
|
317
|
+
function renderSchemaVerificationTree(node, flags, options) {
|
|
318
|
+
const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;
|
|
319
|
+
const lines = [];
|
|
320
|
+
let statusGlyph = "";
|
|
321
|
+
let statusColor = (text) => text;
|
|
322
|
+
if (useColor) {
|
|
323
|
+
switch (node.status) {
|
|
324
|
+
case "pass":
|
|
325
|
+
statusGlyph = "\u2714";
|
|
326
|
+
statusColor = green;
|
|
327
|
+
break;
|
|
328
|
+
case "warn":
|
|
329
|
+
statusGlyph = "\u26A0";
|
|
330
|
+
statusColor = (text) => useColor ? yellow(text) : text;
|
|
331
|
+
break;
|
|
332
|
+
case "fail":
|
|
333
|
+
statusGlyph = "\u2716";
|
|
334
|
+
statusColor = red;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
switch (node.status) {
|
|
339
|
+
case "pass":
|
|
340
|
+
statusGlyph = "\u2714";
|
|
341
|
+
break;
|
|
342
|
+
case "warn":
|
|
343
|
+
statusGlyph = "\u26A0";
|
|
344
|
+
break;
|
|
345
|
+
case "fail":
|
|
346
|
+
statusGlyph = "\u2716";
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
let labelColor = (text) => text;
|
|
351
|
+
let formattedLabel = node.name;
|
|
352
|
+
if (useColor) {
|
|
353
|
+
switch (node.kind) {
|
|
354
|
+
case "contract":
|
|
355
|
+
case "schema":
|
|
356
|
+
labelColor = bold;
|
|
357
|
+
formattedLabel = labelColor(node.name);
|
|
358
|
+
break;
|
|
359
|
+
case "table": {
|
|
360
|
+
const tableMatch = node.name.match(/^table\s+(.+)$/);
|
|
361
|
+
if (tableMatch?.[1]) {
|
|
362
|
+
const tableName = tableMatch[1];
|
|
363
|
+
formattedLabel = `${dim("table")} ${cyan(tableName)}`;
|
|
364
|
+
} else {
|
|
365
|
+
formattedLabel = dim(node.name);
|
|
366
|
+
}
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
case "columns":
|
|
370
|
+
labelColor = dim;
|
|
371
|
+
formattedLabel = labelColor(node.name);
|
|
372
|
+
break;
|
|
373
|
+
case "column": {
|
|
374
|
+
const columnMatch = node.name.match(/^([^:]+):\s*(.+)$/);
|
|
375
|
+
if (columnMatch?.[1] && columnMatch[2]) {
|
|
376
|
+
const columnName = columnMatch[1];
|
|
377
|
+
const rest = columnMatch[2];
|
|
378
|
+
const typeMatch = rest.match(/^([^\s→]+)\s*→\s*([^\s(]+)\s*(\([^)]+\))$/);
|
|
379
|
+
if (typeMatch?.[1] && typeMatch[2] && typeMatch[3]) {
|
|
380
|
+
const contractType = typeMatch[1];
|
|
381
|
+
const nativeType = typeMatch[2];
|
|
382
|
+
const nullability = typeMatch[3];
|
|
383
|
+
formattedLabel = `${cyan(columnName)}: ${contractType} \u2192 ${dim(nativeType)} ${dim(nullability)}`;
|
|
384
|
+
} else {
|
|
385
|
+
formattedLabel = `${cyan(columnName)}: ${rest}`;
|
|
386
|
+
}
|
|
387
|
+
} else {
|
|
388
|
+
formattedLabel = node.name;
|
|
389
|
+
}
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
case "type":
|
|
393
|
+
case "nullability":
|
|
394
|
+
labelColor = (text) => text;
|
|
395
|
+
formattedLabel = labelColor(node.name);
|
|
396
|
+
break;
|
|
397
|
+
case "primaryKey": {
|
|
398
|
+
const pkMatch = node.name.match(/^primary key:\s*(.+)$/);
|
|
399
|
+
if (pkMatch?.[1]) {
|
|
400
|
+
const columnNames = pkMatch[1];
|
|
401
|
+
formattedLabel = `${dim("primary key")}: ${cyan(columnNames)}`;
|
|
402
|
+
} else {
|
|
403
|
+
formattedLabel = dim(node.name);
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
case "foreignKey":
|
|
408
|
+
case "unique":
|
|
409
|
+
case "index":
|
|
410
|
+
labelColor = dim;
|
|
411
|
+
formattedLabel = labelColor(node.name);
|
|
412
|
+
break;
|
|
413
|
+
case "extension": {
|
|
414
|
+
const dbMatch = node.name.match(/^database is\s+(.+)$/);
|
|
415
|
+
if (dbMatch?.[1]) {
|
|
416
|
+
const dbName = dbMatch[1];
|
|
417
|
+
formattedLabel = `${dim("database is")} ${cyan(dbName)}`;
|
|
418
|
+
} else {
|
|
419
|
+
const extMatch = node.name.match(/^([^\s]+)\s+(extension is enabled)$/);
|
|
420
|
+
if (extMatch?.[1] && extMatch[2]) {
|
|
421
|
+
const extName = extMatch[1];
|
|
422
|
+
const rest = extMatch[2];
|
|
423
|
+
formattedLabel = `${cyan(extName)} ${dim(rest)}`;
|
|
424
|
+
} else {
|
|
425
|
+
labelColor = magenta;
|
|
426
|
+
formattedLabel = labelColor(node.name);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
default:
|
|
432
|
+
formattedLabel = node.name;
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
} else {
|
|
436
|
+
formattedLabel = node.name;
|
|
437
|
+
}
|
|
438
|
+
const statusGlyphColored = statusColor(statusGlyph);
|
|
439
|
+
let nodeLabel = formattedLabel;
|
|
440
|
+
if ((node.status === "fail" || node.status === "warn") && node.message && node.message.length > 0) {
|
|
441
|
+
const messageText = formatDimText(`(${node.message})`);
|
|
442
|
+
nodeLabel = `${formattedLabel} ${messageText}`;
|
|
443
|
+
}
|
|
444
|
+
if (isRoot) {
|
|
445
|
+
lines.push(`${statusGlyphColored} ${nodeLabel}`);
|
|
446
|
+
} else {
|
|
447
|
+
const treeChar = isLast ? "\u2514" : "\u251C";
|
|
448
|
+
const treePrefix = `${prefix}${formatDimText(treeChar)}\u2500 `;
|
|
449
|
+
const isRootChild = prefix === "";
|
|
450
|
+
const prefixWithoutAnsi = stripAnsi(prefix);
|
|
451
|
+
const prefixHasVerticalBar = prefixWithoutAnsi.includes("\u2502");
|
|
452
|
+
if (isRootChild) {
|
|
453
|
+
lines.push(`${treePrefix}${statusGlyphColored} ${nodeLabel}`);
|
|
454
|
+
} else if (prefixHasVerticalBar) {
|
|
455
|
+
lines.push(`${treePrefix}${statusGlyphColored} ${nodeLabel}`);
|
|
456
|
+
} else {
|
|
457
|
+
lines.push(`${formatDimText("\u2502")} ${treePrefix}${statusGlyphColored} ${nodeLabel}`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (node.children && node.children.length > 0) {
|
|
461
|
+
const childPrefix = isRoot ? "" : isLast ? `${prefix} ` : `${prefix}${formatDimText("\u2502")} `;
|
|
462
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
463
|
+
const child = node.children[i];
|
|
464
|
+
if (!child) continue;
|
|
465
|
+
const isLastChild = i === node.children.length - 1;
|
|
466
|
+
const childLines = renderSchemaVerificationTree(child, flags, {
|
|
467
|
+
isLast: isLastChild,
|
|
468
|
+
prefix: childPrefix,
|
|
469
|
+
useColor,
|
|
470
|
+
formatDimText,
|
|
471
|
+
isRoot: false
|
|
472
|
+
});
|
|
473
|
+
lines.push(...childLines);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return lines;
|
|
477
|
+
}
|
|
478
|
+
function formatSchemaVerifyOutput(result, flags) {
|
|
479
|
+
if (flags.quiet) {
|
|
480
|
+
return "";
|
|
481
|
+
}
|
|
482
|
+
const lines = [];
|
|
483
|
+
const prefix = createPrefix(flags);
|
|
484
|
+
const useColor = flags.color !== false;
|
|
485
|
+
const formatGreen = createColorFormatter(useColor, green);
|
|
486
|
+
const formatRed = createColorFormatter(useColor, red);
|
|
487
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
488
|
+
const treeLines = renderSchemaVerificationTree(result.schema.root, flags, {
|
|
489
|
+
isLast: true,
|
|
490
|
+
prefix: "",
|
|
491
|
+
useColor,
|
|
492
|
+
formatDimText,
|
|
493
|
+
isRoot: true
|
|
494
|
+
});
|
|
495
|
+
const prefixedTreeLines = treeLines.map((line) => `${prefix}${line}`);
|
|
496
|
+
lines.push(...prefixedTreeLines);
|
|
497
|
+
if (isVerbose(flags, 1)) {
|
|
498
|
+
lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);
|
|
499
|
+
lines.push(
|
|
500
|
+
`${prefix}${formatDimText(` pass=${result.schema.counts.pass} warn=${result.schema.counts.warn} fail=${result.schema.counts.fail}`)}`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
lines.push("");
|
|
504
|
+
if (result.ok) {
|
|
505
|
+
lines.push(`${prefix}${formatGreen("\u2714")} ${result.summary}`);
|
|
506
|
+
} else {
|
|
507
|
+
const codeText = result.code ? ` (${result.code})` : "";
|
|
508
|
+
lines.push(`${prefix}${formatRed("\u2716")} ${result.summary}${codeText}`);
|
|
509
|
+
}
|
|
510
|
+
return lines.join("\n");
|
|
511
|
+
}
|
|
512
|
+
function formatSchemaVerifyJson(result) {
|
|
513
|
+
return JSON.stringify(result, null, 2);
|
|
514
|
+
}
|
|
515
|
+
function formatSignOutput(result, flags) {
|
|
516
|
+
if (flags.quiet) {
|
|
517
|
+
return "";
|
|
518
|
+
}
|
|
519
|
+
const lines = [];
|
|
520
|
+
const prefix = createPrefix(flags);
|
|
521
|
+
const useColor = flags.color !== false;
|
|
522
|
+
const formatGreen = createColorFormatter(useColor, green);
|
|
523
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
524
|
+
if (result.ok) {
|
|
525
|
+
lines.push(`${prefix}${formatGreen("\u2714")} Database signed`);
|
|
526
|
+
const previousHash = result.marker.previous?.coreHash ?? "none";
|
|
527
|
+
const currentHash = result.contract.coreHash;
|
|
528
|
+
lines.push(`${prefix}${formatDimText(` from: ${previousHash}`)}`);
|
|
529
|
+
lines.push(`${prefix}${formatDimText(` to: ${currentHash}`)}`);
|
|
530
|
+
if (isVerbose(flags, 1)) {
|
|
531
|
+
if (result.contract.profileHash) {
|
|
532
|
+
lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);
|
|
533
|
+
}
|
|
534
|
+
if (result.marker.previous?.profileHash) {
|
|
535
|
+
lines.push(
|
|
536
|
+
`${prefix}${formatDimText(` previous profileHash: ${result.marker.previous.profileHash}`)}`
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
lines.push(`${prefix}${formatDimText(` Total time: ${result.timings.total}ms`)}`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return lines.join("\n");
|
|
543
|
+
}
|
|
544
|
+
function formatSignJson(result) {
|
|
545
|
+
return JSON.stringify(result, null, 2);
|
|
546
|
+
}
|
|
547
|
+
var LEFT_COLUMN_WIDTH = 20;
|
|
548
|
+
var RIGHT_COLUMN_MIN_WIDTH = 40;
|
|
549
|
+
var RIGHT_COLUMN_MAX_WIDTH = 90;
|
|
550
|
+
function getTerminalWidth() {
|
|
551
|
+
const terminalWidth = process.stdout.columns;
|
|
552
|
+
const defaultWidth = Number.parseInt(process.env["CLI_WIDTH"] || "80", 10);
|
|
553
|
+
return terminalWidth || defaultWidth;
|
|
554
|
+
}
|
|
555
|
+
function calculateRightColumnWidth() {
|
|
556
|
+
const terminalWidth = getTerminalWidth();
|
|
557
|
+
const availableWidth = terminalWidth - 2 - LEFT_COLUMN_WIDTH - 2;
|
|
558
|
+
return Math.max(RIGHT_COLUMN_MIN_WIDTH, Math.min(availableWidth, RIGHT_COLUMN_MAX_WIDTH));
|
|
559
|
+
}
|
|
560
|
+
function createPrismaNextBadge(useColor) {
|
|
561
|
+
if (!useColor) {
|
|
562
|
+
return "prisma-next";
|
|
563
|
+
}
|
|
564
|
+
const text = " prisma-next ";
|
|
565
|
+
const body = bgGreen(bold(text));
|
|
566
|
+
const separator = "\uE0B0";
|
|
567
|
+
const tip = green(separator);
|
|
568
|
+
return `${body}${tip}`;
|
|
569
|
+
}
|
|
570
|
+
function createPadFunction() {
|
|
571
|
+
return (s, w) => s + " ".repeat(Math.max(0, w - s.length));
|
|
572
|
+
}
|
|
573
|
+
function formatHeaderLine(options) {
|
|
574
|
+
if (options.operation) {
|
|
575
|
+
return `${options.brand} ${options.operation} \u2192 ${options.intent}`;
|
|
576
|
+
}
|
|
577
|
+
return `${options.brand} ${options.intent}`;
|
|
578
|
+
}
|
|
579
|
+
function formatReadMoreLine(options) {
|
|
580
|
+
const pad = createPadFunction();
|
|
581
|
+
const labelPadded = pad("Read more", options.maxLabelWidth);
|
|
582
|
+
const valueColored = options.useColor ? blue(options.url) : options.url;
|
|
583
|
+
return `${options.formatDimText("\u2502")} ${labelPadded} ${valueColored}`;
|
|
584
|
+
}
|
|
585
|
+
function padToFixedWidth(text, width) {
|
|
586
|
+
const actualWidth = stringWidth(text);
|
|
587
|
+
const padding = Math.max(0, width - actualWidth);
|
|
588
|
+
return text + " ".repeat(padding);
|
|
589
|
+
}
|
|
590
|
+
function wrapTextAnsi(text, width) {
|
|
591
|
+
const wrapped = wrapAnsi(text, width, { hard: false, trim: true });
|
|
592
|
+
return wrapped.split("\n");
|
|
593
|
+
}
|
|
594
|
+
function formatDefaultValue(value, useColor) {
|
|
595
|
+
const valueStr = String(value);
|
|
596
|
+
const defaultText = `default: ${valueStr}`;
|
|
597
|
+
return useColor ? dim(defaultText) : defaultText;
|
|
598
|
+
}
|
|
599
|
+
function renderCommandTree(options) {
|
|
600
|
+
const { commands, useColor, formatDimText, hasItemsAfter, continuationPrefix } = options;
|
|
601
|
+
const lines = [];
|
|
602
|
+
if (commands.length === 0) {
|
|
603
|
+
return lines;
|
|
604
|
+
}
|
|
605
|
+
for (let i = 0; i < commands.length; i++) {
|
|
606
|
+
const cmd = commands[i];
|
|
607
|
+
if (!cmd) continue;
|
|
608
|
+
const subcommands = cmd.commands.filter((subcmd) => !subcmd.name().startsWith("_"));
|
|
609
|
+
const isLastCommand = i === commands.length - 1;
|
|
610
|
+
if (subcommands.length > 0) {
|
|
611
|
+
const prefix = isLastCommand && !hasItemsAfter ? formatDimText("\u2514") : formatDimText("\u251C");
|
|
612
|
+
const treePrefix = `${prefix}\u2500 `;
|
|
613
|
+
const treePrefixWidth = stringWidth(stripAnsi(treePrefix));
|
|
614
|
+
const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;
|
|
615
|
+
const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);
|
|
616
|
+
const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;
|
|
617
|
+
lines.push(`${formatDimText("\u2502")} ${treePrefix}${commandNameColored}`);
|
|
618
|
+
for (let j = 0; j < subcommands.length; j++) {
|
|
619
|
+
const subcmd = subcommands[j];
|
|
620
|
+
if (!subcmd) continue;
|
|
621
|
+
const isLastSubcommand = j === subcommands.length - 1;
|
|
622
|
+
const shortDescription = subcmd.description() || "";
|
|
623
|
+
const treeChar = isLastSubcommand ? "\u2514" : "\u251C";
|
|
624
|
+
const continuation = continuationPrefix ?? (isLastCommand && isLastSubcommand && !hasItemsAfter ? " " : formatDimText("\u2502"));
|
|
625
|
+
const continuationStr = continuation === " " ? " " : continuation;
|
|
626
|
+
const subTreePrefix = `${continuationStr} ${formatDimText(treeChar)}\u2500 `;
|
|
627
|
+
const subTreePrefixWidth = stringWidth(stripAnsi(subTreePrefix));
|
|
628
|
+
const subRemainingWidth = LEFT_COLUMN_WIDTH - subTreePrefixWidth;
|
|
629
|
+
const subcommandNamePadded = padToFixedWidth(subcmd.name(), subRemainingWidth);
|
|
630
|
+
const subcommandNameColored = useColor ? cyan(subcommandNamePadded) : subcommandNamePadded;
|
|
631
|
+
lines.push(
|
|
632
|
+
`${formatDimText("\u2502")} ${subTreePrefix}${subcommandNameColored} ${shortDescription}`
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
const prefix = isLastCommand && !hasItemsAfter ? formatDimText("\u2514") : formatDimText("\u251C");
|
|
637
|
+
const treePrefix = `${prefix}\u2500 `;
|
|
638
|
+
const treePrefixWidth = stringWidth(stripAnsi(treePrefix));
|
|
639
|
+
const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;
|
|
640
|
+
const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);
|
|
641
|
+
const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;
|
|
642
|
+
const shortDescription = cmd.description() || "";
|
|
643
|
+
lines.push(`${formatDimText("\u2502")} ${treePrefix}${commandNameColored} ${shortDescription}`);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return lines;
|
|
647
|
+
}
|
|
648
|
+
function formatMultilineDescription(options) {
|
|
649
|
+
const lines = [];
|
|
650
|
+
const formatGreen = (text) => options.useColor ? green(text) : text;
|
|
651
|
+
const rightColumnWidth = calculateRightColumnWidth();
|
|
652
|
+
const totalWidth = 2 + LEFT_COLUMN_WIDTH + 2 + rightColumnWidth;
|
|
653
|
+
const wrapWidth = totalWidth - 2;
|
|
654
|
+
for (const descLine of options.descriptionLines) {
|
|
655
|
+
const formattedLine = descLine.replace(/Prisma Next/g, (match) => formatGreen(match));
|
|
656
|
+
const wrappedLines = wrapTextAnsi(formattedLine, wrapWidth);
|
|
657
|
+
for (const wrappedLine of wrappedLines) {
|
|
658
|
+
lines.push(`${options.formatDimText("\u2502")} ${wrappedLine}`);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return lines;
|
|
662
|
+
}
|
|
663
|
+
function formatStyledHeader(options) {
|
|
664
|
+
const lines = [];
|
|
665
|
+
const useColor = options.flags.color !== false;
|
|
666
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
667
|
+
const brand = createPrismaNextBadge(useColor);
|
|
668
|
+
const operation = useColor ? bold(options.command) : options.command;
|
|
669
|
+
const intent = formatDimText(options.description);
|
|
670
|
+
lines.push(formatHeaderLine({ brand, operation, intent }));
|
|
671
|
+
lines.push(formatDimText("\u2502"));
|
|
672
|
+
for (const detail of options.details) {
|
|
673
|
+
const labelWithColon = `${detail.label}:`;
|
|
674
|
+
const labelPadded = padToFixedWidth(labelWithColon, LEFT_COLUMN_WIDTH);
|
|
675
|
+
const labelColored = useColor ? cyan(labelPadded) : labelPadded;
|
|
676
|
+
lines.push(`${formatDimText("\u2502")} ${labelColored} ${detail.value}`);
|
|
677
|
+
}
|
|
678
|
+
if (options.url) {
|
|
679
|
+
lines.push(formatDimText("\u2502"));
|
|
680
|
+
lines.push(
|
|
681
|
+
formatReadMoreLine({
|
|
682
|
+
url: options.url,
|
|
683
|
+
maxLabelWidth: LEFT_COLUMN_WIDTH,
|
|
684
|
+
useColor,
|
|
685
|
+
formatDimText
|
|
686
|
+
})
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
lines.push(formatDimText("\u2514"));
|
|
690
|
+
return `${lines.join("\n")}
|
|
691
|
+
`;
|
|
692
|
+
}
|
|
693
|
+
function formatSuccessMessage(flags) {
|
|
694
|
+
const useColor = flags.color !== false;
|
|
695
|
+
const formatGreen = createColorFormatter(useColor, green);
|
|
696
|
+
return `${formatGreen("\u2714")} Success`;
|
|
697
|
+
}
|
|
698
|
+
function getCommandDocsUrl(commandPath) {
|
|
699
|
+
const docsMap = {
|
|
700
|
+
"contract emit": "https://pris.ly/contract-emit",
|
|
701
|
+
"db verify": "https://pris.ly/db-verify"
|
|
702
|
+
};
|
|
703
|
+
return docsMap[commandPath];
|
|
704
|
+
}
|
|
705
|
+
function buildCommandPath(command) {
|
|
706
|
+
const parts = [];
|
|
707
|
+
let current = command;
|
|
708
|
+
while (current && current.name() !== "prisma-next") {
|
|
709
|
+
parts.unshift(current.name());
|
|
710
|
+
current = current.parent ?? void 0;
|
|
711
|
+
}
|
|
712
|
+
return parts.join(" ");
|
|
713
|
+
}
|
|
714
|
+
function formatCommandHelp(options) {
|
|
715
|
+
const { command, flags } = options;
|
|
716
|
+
const lines = [];
|
|
717
|
+
const useColor = flags.color !== false;
|
|
718
|
+
const formatDimText = (text) => formatDim(useColor, text);
|
|
719
|
+
const commandPath = buildCommandPath(command);
|
|
720
|
+
const shortDescription = command.description() || "";
|
|
721
|
+
const longDescription = getLongDescription(command);
|
|
722
|
+
const brand = createPrismaNextBadge(useColor);
|
|
723
|
+
const operation = useColor ? bold(commandPath) : commandPath;
|
|
724
|
+
const intent = formatDimText(shortDescription);
|
|
725
|
+
lines.push(formatHeaderLine({ brand, operation, intent }));
|
|
726
|
+
lines.push(formatDimText("\u2502"));
|
|
727
|
+
const optionsList = command.options.map((opt) => {
|
|
728
|
+
const flags2 = opt.flags;
|
|
729
|
+
const description = opt.description || "";
|
|
730
|
+
const defaultValue = opt.defaultValue;
|
|
731
|
+
return { flags: flags2, description, defaultValue };
|
|
732
|
+
});
|
|
733
|
+
const subcommands = command.commands.filter((cmd) => !cmd.name().startsWith("_"));
|
|
734
|
+
if (subcommands.length > 0) {
|
|
735
|
+
const hasItemsAfter = optionsList.length > 0;
|
|
736
|
+
const treeLines = renderCommandTree({
|
|
737
|
+
commands: subcommands,
|
|
738
|
+
useColor,
|
|
739
|
+
formatDimText,
|
|
740
|
+
hasItemsAfter
|
|
741
|
+
});
|
|
742
|
+
lines.push(...treeLines);
|
|
743
|
+
}
|
|
744
|
+
if (subcommands.length > 0 && optionsList.length > 0) {
|
|
745
|
+
lines.push(formatDimText("\u2502"));
|
|
746
|
+
}
|
|
747
|
+
if (optionsList.length > 0) {
|
|
748
|
+
for (const opt of optionsList) {
|
|
749
|
+
const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);
|
|
750
|
+
let flagsColored = flagsPadded;
|
|
751
|
+
if (useColor) {
|
|
752
|
+
flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match) => magenta(match));
|
|
753
|
+
flagsColored = cyan(flagsColored);
|
|
754
|
+
}
|
|
755
|
+
const rightColumnWidth = calculateRightColumnWidth();
|
|
756
|
+
const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);
|
|
757
|
+
lines.push(`${formatDimText("\u2502")} ${flagsColored} ${wrappedDescription[0] || ""}`);
|
|
758
|
+
for (let i = 1; i < wrappedDescription.length; i++) {
|
|
759
|
+
const emptyLabel = " ".repeat(LEFT_COLUMN_WIDTH);
|
|
760
|
+
lines.push(`${formatDimText("\u2502")} ${emptyLabel} ${wrappedDescription[i] || ""}`);
|
|
761
|
+
}
|
|
762
|
+
if (opt.defaultValue !== void 0) {
|
|
763
|
+
const emptyLabel = " ".repeat(LEFT_COLUMN_WIDTH);
|
|
764
|
+
const defaultText = formatDefaultValue(opt.defaultValue, useColor);
|
|
765
|
+
lines.push(`${formatDimText("\u2502")} ${emptyLabel} ${defaultText}`);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
const docsUrl = getCommandDocsUrl(commandPath);
|
|
770
|
+
if (docsUrl) {
|
|
771
|
+
lines.push(formatDimText("\u2502"));
|
|
772
|
+
lines.push(
|
|
773
|
+
formatReadMoreLine({
|
|
774
|
+
url: docsUrl,
|
|
775
|
+
maxLabelWidth: LEFT_COLUMN_WIDTH,
|
|
776
|
+
useColor,
|
|
777
|
+
formatDimText
|
|
778
|
+
})
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
if (longDescription) {
|
|
782
|
+
lines.push(formatDimText("\u2502"));
|
|
783
|
+
const descriptionLines = longDescription.split("\n").filter((line) => line.trim().length > 0);
|
|
784
|
+
lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));
|
|
785
|
+
}
|
|
786
|
+
lines.push(formatDimText("\u2514"));
|
|
787
|
+
return `${lines.join("\n")}
|
|
788
|
+
`;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// src/utils/cli-errors.ts
|
|
792
|
+
import {
|
|
793
|
+
CliStructuredError,
|
|
794
|
+
errorConfigFileNotFound,
|
|
795
|
+
errorConfigValidation,
|
|
796
|
+
errorContractConfigMissing,
|
|
797
|
+
errorContractValidationFailed,
|
|
798
|
+
errorDatabaseUrlRequired,
|
|
799
|
+
errorDriverRequired,
|
|
800
|
+
errorFamilyReadMarkerSqlRequired,
|
|
801
|
+
errorFileNotFound,
|
|
802
|
+
errorHashMismatch,
|
|
803
|
+
errorMarkerMissing,
|
|
804
|
+
errorQueryRunnerFactoryRequired,
|
|
805
|
+
errorRuntime,
|
|
806
|
+
errorTargetMismatch,
|
|
807
|
+
errorUnexpected
|
|
808
|
+
} from "@prisma-next/core-control-plane/errors";
|
|
809
|
+
|
|
810
|
+
// src/utils/result.ts
|
|
811
|
+
function ok(value) {
|
|
812
|
+
return { ok: true, value };
|
|
813
|
+
}
|
|
814
|
+
function err(error) {
|
|
815
|
+
return { ok: false, error };
|
|
816
|
+
}
|
|
817
|
+
async function performAction(fn) {
|
|
818
|
+
try {
|
|
819
|
+
const value = await fn();
|
|
820
|
+
return ok(value);
|
|
821
|
+
} catch (error) {
|
|
822
|
+
if (error instanceof CliStructuredError) {
|
|
823
|
+
return err(error);
|
|
824
|
+
}
|
|
825
|
+
throw error;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// src/utils/result-handler.ts
|
|
830
|
+
function handleResult(result, flags, onSuccess) {
|
|
831
|
+
if (result.ok) {
|
|
832
|
+
if (onSuccess) {
|
|
833
|
+
onSuccess(result.value);
|
|
834
|
+
}
|
|
835
|
+
return 0;
|
|
836
|
+
}
|
|
837
|
+
const envelope = result.error.toEnvelope();
|
|
838
|
+
if (flags.json === "object") {
|
|
839
|
+
console.error(formatErrorJson(envelope));
|
|
840
|
+
} else {
|
|
841
|
+
console.error(formatErrorOutput(envelope, flags));
|
|
842
|
+
}
|
|
843
|
+
const exitCode = result.error.domain === "CLI" ? 2 : 1;
|
|
844
|
+
return exitCode;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// src/utils/spinner.ts
|
|
848
|
+
import ora from "ora";
|
|
849
|
+
async function withSpinner(operation, options) {
|
|
850
|
+
const { message, flags, delayThreshold = 100 } = options;
|
|
851
|
+
const shouldShowSpinner = !flags.quiet && flags.json !== "object" && process.stdout.isTTY;
|
|
852
|
+
if (!shouldShowSpinner) {
|
|
853
|
+
return operation();
|
|
854
|
+
}
|
|
855
|
+
const startTime = Date.now();
|
|
856
|
+
let spinner = null;
|
|
857
|
+
let timeoutId = null;
|
|
858
|
+
let operationCompleted = false;
|
|
859
|
+
timeoutId = setTimeout(() => {
|
|
860
|
+
if (!operationCompleted) {
|
|
861
|
+
spinner = ora({
|
|
862
|
+
text: message,
|
|
863
|
+
color: flags.color !== false ? "cyan" : false
|
|
864
|
+
}).start();
|
|
865
|
+
}
|
|
866
|
+
}, delayThreshold);
|
|
867
|
+
try {
|
|
868
|
+
const result = await operation();
|
|
869
|
+
operationCompleted = true;
|
|
870
|
+
if (timeoutId) {
|
|
871
|
+
clearTimeout(timeoutId);
|
|
872
|
+
timeoutId = null;
|
|
873
|
+
}
|
|
874
|
+
if (spinner !== null) {
|
|
875
|
+
const elapsed = Date.now() - startTime;
|
|
876
|
+
spinner.succeed(`${message} (${elapsed}ms)`);
|
|
877
|
+
}
|
|
878
|
+
return result;
|
|
879
|
+
} catch (error) {
|
|
880
|
+
operationCompleted = true;
|
|
881
|
+
if (timeoutId) {
|
|
882
|
+
clearTimeout(timeoutId);
|
|
883
|
+
timeoutId = null;
|
|
884
|
+
}
|
|
885
|
+
if (spinner !== null) {
|
|
886
|
+
spinner.fail(
|
|
887
|
+
`${message} failed: ${error instanceof Error ? error.message : String(error)}`
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
throw error;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
export {
|
|
895
|
+
setCommandDescriptions,
|
|
896
|
+
parseGlobalFlags,
|
|
897
|
+
formatEmitOutput,
|
|
898
|
+
formatEmitJson,
|
|
899
|
+
formatVerifyOutput,
|
|
900
|
+
formatVerifyJson,
|
|
901
|
+
formatIntrospectJson,
|
|
902
|
+
formatIntrospectOutput,
|
|
903
|
+
formatSchemaVerifyOutput,
|
|
904
|
+
formatSchemaVerifyJson,
|
|
905
|
+
formatSignOutput,
|
|
906
|
+
formatSignJson,
|
|
907
|
+
formatStyledHeader,
|
|
908
|
+
formatSuccessMessage,
|
|
909
|
+
formatCommandHelp,
|
|
910
|
+
performAction,
|
|
911
|
+
handleResult,
|
|
912
|
+
withSpinner
|
|
913
|
+
};
|
|
914
|
+
//# sourceMappingURL=chunk-3EODSNGS.js.map
|