@prisma-next/cli 0.3.0-dev.5 → 0.3.0-dev.52
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 +145 -74
- package/dist/cli.d.mts +1 -0
- package/dist/cli.js +1 -2376
- package/dist/cli.mjs +169 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-BSZKpZTF.mjs +711 -0
- package/dist/client-BSZKpZTF.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts +7 -0
- package/dist/commands/contract-emit.d.mts.map +1 -0
- package/dist/commands/contract-emit.mjs +147 -0
- package/dist/commands/contract-emit.mjs.map +1 -0
- package/dist/commands/db-init.d.mts +7 -0
- package/dist/commands/db-init.d.mts.map +1 -0
- package/dist/commands/db-init.mjs +179 -0
- package/dist/commands/db-init.mjs.map +1 -0
- package/dist/commands/db-introspect.d.mts +7 -0
- package/dist/commands/db-introspect.d.mts.map +1 -0
- package/dist/commands/db-introspect.mjs +120 -0
- package/dist/commands/db-introspect.mjs.map +1 -0
- package/dist/commands/db-schema-verify.d.mts +7 -0
- package/dist/commands/db-schema-verify.d.mts.map +1 -0
- package/dist/commands/db-schema-verify.mjs +116 -0
- package/dist/commands/db-schema-verify.mjs.map +1 -0
- package/dist/commands/db-sign.d.mts +7 -0
- package/dist/commands/db-sign.d.mts.map +1 -0
- package/dist/commands/db-sign.mjs +138 -0
- package/dist/commands/db-sign.mjs.map +1 -0
- package/dist/commands/db-verify.d.mts +7 -0
- package/dist/commands/db-verify.d.mts.map +1 -0
- package/dist/commands/db-verify.mjs +129 -0
- package/dist/commands/db-verify.mjs.map +1 -0
- package/dist/config-loader-BJ8HsEdA.mjs +42 -0
- package/dist/config-loader-BJ8HsEdA.mjs.map +1 -0
- package/dist/{config-loader.d.ts → config-loader.d.mts} +8 -3
- package/dist/config-loader.d.mts.map +1 -0
- package/dist/config-loader.mjs +3 -0
- package/dist/exports/config-types.d.mts +2 -0
- package/dist/exports/config-types.mjs +3 -0
- package/dist/exports/control-api.d.mts +433 -0
- package/dist/exports/control-api.d.mts.map +1 -0
- package/dist/exports/control-api.mjs +96 -0
- package/dist/exports/control-api.mjs.map +1 -0
- package/dist/{load-ts-contract.d.ts → exports/index.d.mts} +10 -5
- package/dist/exports/index.d.mts.map +1 -0
- package/dist/exports/index.mjs +132 -0
- package/dist/exports/index.mjs.map +1 -0
- package/dist/result-handler-BZPY7HX4.mjs +1029 -0
- package/dist/result-handler-BZPY7HX4.mjs.map +1 -0
- package/package.json +48 -37
- package/src/commands/contract-emit.ts +205 -111
- package/src/commands/db-init.ts +258 -359
- package/src/commands/db-introspect.ts +151 -184
- package/src/commands/db-schema-verify.ts +151 -149
- package/src/commands/db-sign.ts +202 -200
- package/src/commands/db-verify.ts +181 -155
- package/src/control-api/client.ts +610 -0
- package/src/control-api/operations/contract-emit.ts +161 -0
- package/src/control-api/operations/db-init.ts +281 -0
- package/src/control-api/types.ts +475 -0
- package/src/exports/control-api.ts +48 -0
- package/src/load-ts-contract.ts +16 -11
- package/src/utils/cli-errors.ts +1 -1
- package/src/utils/framework-components.ts +11 -30
- package/src/utils/output.ts +16 -10
- package/src/utils/progress-adapter.ts +86 -0
- package/dist/chunk-464LNZCE.js +0 -134
- package/dist/chunk-464LNZCE.js.map +0 -1
- package/dist/chunk-BZMBKEEQ.js +0 -997
- package/dist/chunk-BZMBKEEQ.js.map +0 -1
- package/dist/chunk-HWYQOCAJ.js +0 -47
- package/dist/chunk-HWYQOCAJ.js.map +0 -1
- package/dist/chunk-ZKYEJROM.js +0 -94
- package/dist/chunk-ZKYEJROM.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/contract-emit.d.ts +0 -3
- package/dist/commands/contract-emit.d.ts.map +0 -1
- package/dist/commands/contract-emit.js +0 -9
- package/dist/commands/contract-emit.js.map +0 -1
- package/dist/commands/db-init.d.ts +0 -3
- package/dist/commands/db-init.d.ts.map +0 -1
- package/dist/commands/db-init.js +0 -341
- package/dist/commands/db-init.js.map +0 -1
- package/dist/commands/db-introspect.d.ts +0 -3
- package/dist/commands/db-introspect.d.ts.map +0 -1
- package/dist/commands/db-introspect.js +0 -190
- package/dist/commands/db-introspect.js.map +0 -1
- package/dist/commands/db-schema-verify.d.ts +0 -3
- package/dist/commands/db-schema-verify.d.ts.map +0 -1
- package/dist/commands/db-schema-verify.js +0 -164
- package/dist/commands/db-schema-verify.js.map +0 -1
- package/dist/commands/db-sign.d.ts +0 -3
- package/dist/commands/db-sign.d.ts.map +0 -1
- package/dist/commands/db-sign.js +0 -199
- package/dist/commands/db-sign.js.map +0 -1
- package/dist/commands/db-verify.d.ts +0 -3
- package/dist/commands/db-verify.d.ts.map +0 -1
- package/dist/commands/db-verify.js +0 -173
- package/dist/commands/db-verify.js.map +0 -1
- package/dist/config-loader.d.ts.map +0 -1
- package/dist/config-loader.js +0 -7
- package/dist/config-loader.js.map +0 -1
- package/dist/exports/config-types.d.ts +0 -3
- package/dist/exports/config-types.d.ts.map +0 -1
- package/dist/exports/config-types.js +0 -6
- package/dist/exports/config-types.js.map +0 -1
- package/dist/exports/index.d.ts +0 -4
- package/dist/exports/index.d.ts.map +0 -1
- package/dist/exports/index.js +0 -175
- package/dist/exports/index.js.map +0 -1
- package/dist/load-ts-contract.d.ts.map +0 -1
- package/dist/utils/action.d.ts +0 -16
- package/dist/utils/action.d.ts.map +0 -1
- package/dist/utils/cli-errors.d.ts +0 -7
- package/dist/utils/cli-errors.d.ts.map +0 -1
- package/dist/utils/command-helpers.d.ts +0 -12
- package/dist/utils/command-helpers.d.ts.map +0 -1
- package/dist/utils/framework-components.d.ts +0 -81
- package/dist/utils/framework-components.d.ts.map +0 -1
- package/dist/utils/global-flags.d.ts +0 -25
- package/dist/utils/global-flags.d.ts.map +0 -1
- package/dist/utils/output.d.ts +0 -142
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/result-handler.d.ts +0 -15
- package/dist/utils/result-handler.d.ts.map +0 -1
- package/dist/utils/spinner.d.ts +0 -29
- package/dist/utils/spinner.d.ts.map +0 -1
- package/src/utils/action.ts +0 -43
- package/src/utils/spinner.ts +0 -67
package/src/utils/output.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { relative } from 'node:path';
|
|
2
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
2
3
|
import { bgGreen, blue, bold, cyan, dim, green, magenta, red, yellow } from 'colorette';
|
|
3
4
|
import type { Command } from 'commander';
|
|
4
5
|
import stringWidth from 'string-width';
|
|
@@ -6,7 +7,8 @@ import stripAnsi from 'strip-ansi';
|
|
|
6
7
|
import wrapAnsi from 'wrap-ansi';
|
|
7
8
|
// EmitContractResult type for CLI output formatting (includes file paths)
|
|
8
9
|
export interface EmitContractResult {
|
|
9
|
-
readonly
|
|
10
|
+
readonly storageHash: string;
|
|
11
|
+
readonly executionHash?: string;
|
|
10
12
|
readonly profileHash: string;
|
|
11
13
|
readonly outDir: string;
|
|
12
14
|
readonly files: {
|
|
@@ -94,7 +96,10 @@ export function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags)
|
|
|
94
96
|
|
|
95
97
|
lines.push(`${prefix}✔ Emitted contract.json → ${jsonPath}`);
|
|
96
98
|
lines.push(`${prefix}✔ Emitted contract.d.ts → ${dtsPath}`);
|
|
97
|
-
lines.push(`${prefix}
|
|
99
|
+
lines.push(`${prefix} storageHash: ${result.storageHash}`);
|
|
100
|
+
if (result.executionHash) {
|
|
101
|
+
lines.push(`${prefix} executionHash: ${result.executionHash}`);
|
|
102
|
+
}
|
|
98
103
|
if (result.profileHash) {
|
|
99
104
|
lines.push(`${prefix} profileHash: ${result.profileHash}`);
|
|
100
105
|
}
|
|
@@ -111,7 +116,8 @@ export function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags)
|
|
|
111
116
|
export function formatEmitJson(result: EmitContractResult): string {
|
|
112
117
|
const output = {
|
|
113
118
|
ok: true,
|
|
114
|
-
|
|
119
|
+
storageHash: result.storageHash,
|
|
120
|
+
...ifDefined('executionHash', result.executionHash),
|
|
115
121
|
...(result.profileHash ? { profileHash: result.profileHash } : {}),
|
|
116
122
|
outDir: result.outDir,
|
|
117
123
|
files: result.files,
|
|
@@ -223,7 +229,7 @@ export function formatVerifyOutput(result: VerifyDatabaseResult, flags: GlobalFl
|
|
|
223
229
|
|
|
224
230
|
if (result.ok) {
|
|
225
231
|
lines.push(`${prefix}${formatGreen('✔')} ${result.summary}`);
|
|
226
|
-
lines.push(`${prefix}${formatDimText(`
|
|
232
|
+
lines.push(`${prefix}${formatDimText(` storageHash: ${result.contract.storageHash}`)}`);
|
|
227
233
|
if (result.contract.profileHash) {
|
|
228
234
|
lines.push(`${prefix}${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);
|
|
229
235
|
}
|
|
@@ -772,8 +778,8 @@ export function formatSignOutput(result: SignDatabaseResult, flags: GlobalFlags)
|
|
|
772
778
|
lines.push(`${prefix}${formatGreen('✔')} Database signed`);
|
|
773
779
|
|
|
774
780
|
// Show from -> to hashes with clear labels
|
|
775
|
-
const previousHash = result.marker.previous?.
|
|
776
|
-
const currentHash = result.contract.
|
|
781
|
+
const previousHash = result.marker.previous?.storageHash ?? 'none';
|
|
782
|
+
const currentHash = result.contract.storageHash;
|
|
777
783
|
|
|
778
784
|
lines.push(`${prefix}${formatDimText(` from: ${previousHash}`)}`);
|
|
779
785
|
lines.push(`${prefix}${formatDimText(` to: ${currentHash}`)}`);
|
|
@@ -814,7 +820,7 @@ export interface DbInitResult {
|
|
|
814
820
|
readonly plan?: {
|
|
815
821
|
readonly targetId: string;
|
|
816
822
|
readonly destination: {
|
|
817
|
-
readonly
|
|
823
|
+
readonly storageHash: string;
|
|
818
824
|
readonly profileHash?: string;
|
|
819
825
|
};
|
|
820
826
|
readonly operations: readonly {
|
|
@@ -828,7 +834,7 @@ export interface DbInitResult {
|
|
|
828
834
|
readonly operationsExecuted: number;
|
|
829
835
|
};
|
|
830
836
|
readonly marker?: {
|
|
831
|
-
readonly
|
|
837
|
+
readonly storageHash: string;
|
|
832
838
|
readonly profileHash?: string;
|
|
833
839
|
};
|
|
834
840
|
readonly summary: string;
|
|
@@ -872,7 +878,7 @@ export function formatDbInitPlanOutput(result: DbInitResult, flags: GlobalFlags)
|
|
|
872
878
|
if (result.plan?.destination) {
|
|
873
879
|
lines.push(`${prefix}`);
|
|
874
880
|
lines.push(
|
|
875
|
-
`${prefix}${formatDimText(`Destination hash: ${result.plan.destination.
|
|
881
|
+
`${prefix}${formatDimText(`Destination hash: ${result.plan.destination.storageHash}`)}`,
|
|
876
882
|
);
|
|
877
883
|
}
|
|
878
884
|
|
|
@@ -910,7 +916,7 @@ export function formatDbInitApplyOutput(result: DbInitResult, flags: GlobalFlags
|
|
|
910
916
|
|
|
911
917
|
// Marker info
|
|
912
918
|
if (result.marker) {
|
|
913
|
-
lines.push(`${prefix}${formatDimText(` Marker written: ${result.marker.
|
|
919
|
+
lines.push(`${prefix}${formatDimText(` Marker written: ${result.marker.storageHash}`)}`);
|
|
914
920
|
if (result.marker.profileHash) {
|
|
915
921
|
lines.push(`${prefix}${formatDimText(` Profile hash: ${result.marker.profileHash}`)}`);
|
|
916
922
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import type { ControlProgressEvent, OnControlProgress } from '../control-api/types';
|
|
3
|
+
import type { GlobalFlags } from './global-flags';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for creating a progress adapter.
|
|
7
|
+
*/
|
|
8
|
+
interface ProgressAdapterOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Global flags that control progress output behavior (quiet, json, color).
|
|
11
|
+
*/
|
|
12
|
+
readonly flags: GlobalFlags;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* State for tracking active spans in the progress adapter.
|
|
17
|
+
*/
|
|
18
|
+
interface SpanState {
|
|
19
|
+
readonly spinner: ReturnType<typeof ora>;
|
|
20
|
+
readonly startTime: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a progress adapter that converts control-api progress events
|
|
25
|
+
* into CLI spinner/progress output.
|
|
26
|
+
*
|
|
27
|
+
* The adapter:
|
|
28
|
+
* - Starts/succeeds spinners for top-level span boundaries
|
|
29
|
+
* - Prints per-operation lines for nested spans (e.g., migration operations under 'apply')
|
|
30
|
+
* - Respects quiet/json/non-TTY flags (no-op in those cases)
|
|
31
|
+
*
|
|
32
|
+
* @param options - Progress adapter configuration
|
|
33
|
+
* @returns An onProgress callback compatible with control-api operations
|
|
34
|
+
*/
|
|
35
|
+
export function createProgressAdapter(options: ProgressAdapterOptions): OnControlProgress {
|
|
36
|
+
const { flags } = options;
|
|
37
|
+
|
|
38
|
+
// Skip progress if quiet, JSON output, or non-TTY
|
|
39
|
+
const shouldShowProgress = !flags.quiet && flags.json !== 'object' && process.stdout.isTTY;
|
|
40
|
+
|
|
41
|
+
if (!shouldShowProgress) {
|
|
42
|
+
// Return a no-op callback
|
|
43
|
+
return () => {
|
|
44
|
+
// No-op
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Track active spans by spanId
|
|
49
|
+
const activeSpans = new Map<string, SpanState>();
|
|
50
|
+
|
|
51
|
+
return (event: ControlProgressEvent) => {
|
|
52
|
+
if (event.kind === 'spanStart') {
|
|
53
|
+
// Nested spans (with parentSpanId) are printed as lines, not spinners
|
|
54
|
+
if (event.parentSpanId) {
|
|
55
|
+
console.log(` → ${event.label}...`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Top-level spans get a spinner
|
|
60
|
+
const spinner = ora({
|
|
61
|
+
text: event.label,
|
|
62
|
+
color: flags.color !== false ? 'cyan' : false,
|
|
63
|
+
}).start();
|
|
64
|
+
|
|
65
|
+
activeSpans.set(event.spanId, {
|
|
66
|
+
spinner,
|
|
67
|
+
startTime: Date.now(),
|
|
68
|
+
});
|
|
69
|
+
} else if (event.kind === 'spanEnd') {
|
|
70
|
+
// Complete the spinner for this span (only top-level spans have spinners)
|
|
71
|
+
const spanState = activeSpans.get(event.spanId);
|
|
72
|
+
if (spanState) {
|
|
73
|
+
const elapsed = Date.now() - spanState.startTime;
|
|
74
|
+
if (event.outcome === 'error') {
|
|
75
|
+
spanState.spinner.fail(`${spanState.spinner.text} (failed)`);
|
|
76
|
+
} else if (event.outcome === 'skipped') {
|
|
77
|
+
spanState.spinner.info(`${spanState.spinner.text} (skipped)`);
|
|
78
|
+
} else {
|
|
79
|
+
spanState.spinner.succeed(`${spanState.spinner.text} (${elapsed}ms)`);
|
|
80
|
+
}
|
|
81
|
+
activeSpans.delete(event.spanId);
|
|
82
|
+
}
|
|
83
|
+
// Nested span ends are no-ops (could log completion if needed)
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
package/dist/chunk-464LNZCE.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
formatCommandHelp,
|
|
3
|
-
formatEmitJson,
|
|
4
|
-
formatEmitOutput,
|
|
5
|
-
formatStyledHeader,
|
|
6
|
-
formatSuccessMessage,
|
|
7
|
-
handleResult,
|
|
8
|
-
parseGlobalFlags,
|
|
9
|
-
performAction,
|
|
10
|
-
setCommandDescriptions,
|
|
11
|
-
withSpinner
|
|
12
|
-
} from "./chunk-BZMBKEEQ.js";
|
|
13
|
-
import {
|
|
14
|
-
loadConfig
|
|
15
|
-
} from "./chunk-HWYQOCAJ.js";
|
|
16
|
-
|
|
17
|
-
// src/commands/contract-emit.ts
|
|
18
|
-
import { mkdirSync, writeFileSync } from "fs";
|
|
19
|
-
import { dirname, relative, resolve } from "path";
|
|
20
|
-
import { errorContractConfigMissing } from "@prisma-next/core-control-plane/errors";
|
|
21
|
-
import { Command } from "commander";
|
|
22
|
-
function createContractEmitCommand() {
|
|
23
|
-
const command = new Command("emit");
|
|
24
|
-
setCommandDescriptions(
|
|
25
|
-
command,
|
|
26
|
-
"Write your contract to JSON and sign it",
|
|
27
|
-
"Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\ncontract.d.ts. The contract.json contains the canonical contract structure, and\ncontract.d.ts provides TypeScript types for type-safe query building."
|
|
28
|
-
);
|
|
29
|
-
command.configureHelp({
|
|
30
|
-
formatHelp: (cmd) => {
|
|
31
|
-
const flags = parseGlobalFlags({});
|
|
32
|
-
return formatCommandHelp({ command: cmd, flags });
|
|
33
|
-
}
|
|
34
|
-
}).option("--config <path>", "Path to prisma-next.config.ts").option("--json [format]", "Output as JSON (object or ndjson)", false).option("-q, --quiet", "Quiet mode: errors only").option("-v, --verbose", "Verbose output: debug info, timings").option("-vv, --trace", "Trace output: deep internals, stack traces").option("--timestamps", "Add timestamps to output").option("--color", "Force color output").option("--no-color", "Disable color output").action(async (options) => {
|
|
35
|
-
const flags = parseGlobalFlags(options);
|
|
36
|
-
const result = await performAction(async () => {
|
|
37
|
-
const config = await loadConfig(options.config);
|
|
38
|
-
if (!config.contract) {
|
|
39
|
-
throw errorContractConfigMissing({
|
|
40
|
-
why: "Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ..., types: ... }"
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
const contractConfig = config.contract;
|
|
44
|
-
if (!contractConfig.output || !contractConfig.types) {
|
|
45
|
-
throw errorContractConfigMissing({
|
|
46
|
-
why: "Contract config must have output and types paths. This should not happen if defineConfig() was used."
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
const outputJsonPath = resolve(contractConfig.output);
|
|
50
|
-
const outputDtsPath = resolve(contractConfig.types);
|
|
51
|
-
if (flags.json !== "object" && !flags.quiet) {
|
|
52
|
-
const configPath = options.config ? relative(process.cwd(), resolve(options.config)) : "prisma-next.config.ts";
|
|
53
|
-
const contractPath = relative(process.cwd(), outputJsonPath);
|
|
54
|
-
const typesPath = relative(process.cwd(), outputDtsPath);
|
|
55
|
-
const header = formatStyledHeader({
|
|
56
|
-
command: "contract emit",
|
|
57
|
-
description: "Write your contract to JSON and sign it",
|
|
58
|
-
url: "https://pris.ly/contract-emit",
|
|
59
|
-
details: [
|
|
60
|
-
{ label: "config", value: configPath },
|
|
61
|
-
{ label: "contract", value: contractPath },
|
|
62
|
-
{ label: "types", value: typesPath }
|
|
63
|
-
],
|
|
64
|
-
flags
|
|
65
|
-
});
|
|
66
|
-
console.log(header);
|
|
67
|
-
}
|
|
68
|
-
if (!config.driver) {
|
|
69
|
-
throw errorContractConfigMissing({
|
|
70
|
-
why: "Config.driver is required. Even though emit does not use the driver, it is required by ControlFamilyDescriptor.create()"
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
const familyInstance = config.family.create({
|
|
74
|
-
target: config.target,
|
|
75
|
-
adapter: config.adapter,
|
|
76
|
-
driver: config.driver,
|
|
77
|
-
extensionPacks: config.extensionPacks ?? []
|
|
78
|
-
});
|
|
79
|
-
let contractRaw;
|
|
80
|
-
if (typeof contractConfig.source === "function") {
|
|
81
|
-
contractRaw = await contractConfig.source();
|
|
82
|
-
} else {
|
|
83
|
-
contractRaw = contractConfig.source;
|
|
84
|
-
}
|
|
85
|
-
const emitResult = await withSpinner(
|
|
86
|
-
() => familyInstance.emitContract({ contractIR: contractRaw }),
|
|
87
|
-
{
|
|
88
|
-
message: "Emitting contract...",
|
|
89
|
-
flags
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
|
-
mkdirSync(dirname(outputJsonPath), { recursive: true });
|
|
93
|
-
mkdirSync(dirname(outputDtsPath), { recursive: true });
|
|
94
|
-
writeFileSync(outputJsonPath, emitResult.contractJson, "utf-8");
|
|
95
|
-
writeFileSync(outputDtsPath, emitResult.contractDts, "utf-8");
|
|
96
|
-
if (!flags.quiet && flags.json !== "object" && process.stdout.isTTY) {
|
|
97
|
-
console.log("");
|
|
98
|
-
}
|
|
99
|
-
return {
|
|
100
|
-
coreHash: emitResult.coreHash,
|
|
101
|
-
profileHash: emitResult.profileHash,
|
|
102
|
-
outDir: dirname(outputJsonPath),
|
|
103
|
-
files: {
|
|
104
|
-
json: outputJsonPath,
|
|
105
|
-
dts: outputDtsPath
|
|
106
|
-
},
|
|
107
|
-
timings: {
|
|
108
|
-
total: 0
|
|
109
|
-
// Timing is handled by emitContract internally if needed
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
});
|
|
113
|
-
const exitCode = handleResult(result, flags, (emitResult) => {
|
|
114
|
-
if (flags.json === "object") {
|
|
115
|
-
console.log(formatEmitJson(emitResult));
|
|
116
|
-
} else {
|
|
117
|
-
const output = formatEmitOutput(emitResult, flags);
|
|
118
|
-
if (output) {
|
|
119
|
-
console.log(output);
|
|
120
|
-
}
|
|
121
|
-
if (!flags.quiet) {
|
|
122
|
-
console.log(formatSuccessMessage(flags));
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
process.exit(exitCode);
|
|
127
|
-
});
|
|
128
|
-
return command;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export {
|
|
132
|
-
createContractEmitCommand
|
|
133
|
-
};
|
|
134
|
-
//# sourceMappingURL=chunk-464LNZCE.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/contract-emit.ts"],"sourcesContent":["import { mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, relative, resolve } from 'node:path';\nimport { errorContractConfigMissing } from '@prisma-next/core-control-plane/errors';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { performAction } from '../utils/action';\nimport { setCommandDescriptions } from '../utils/command-helpers';\nimport { parseGlobalFlags } from '../utils/global-flags';\nimport {\n formatCommandHelp,\n formatEmitJson,\n formatEmitOutput,\n formatStyledHeader,\n formatSuccessMessage,\n} from '../utils/output';\nimport { handleResult } from '../utils/result-handler';\nimport { withSpinner } from '../utils/spinner';\n\ninterface ContractEmitOptions {\n readonly config?: string;\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly vv?: boolean;\n readonly trace?: boolean;\n readonly timestamps?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Write your contract to JSON and sign it',\n 'Reads your contract source (TypeScript or Prisma schema) and emits contract.json and\\n' +\n 'contract.d.ts. The contract.json contains the canonical contract structure, and\\n' +\n 'contract.d.ts provides TypeScript types for type-safe query building.',\n );\n command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--json [format]', 'Output as JSON (object or ndjson)', false)\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('-vv, --trace', 'Trace output: deep internals, stack traces')\n .option('--timestamps', 'Add timestamps to output')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n\n const result = await performAction(async () => {\n // Load config\n const config = await loadConfig(options.config);\n\n // Resolve contract from config\n if (!config.contract) {\n throw errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ..., types: ... }',\n });\n }\n\n // Contract config is already normalized by defineConfig() with defaults applied\n const contractConfig = config.contract;\n\n // Resolve artifact paths from config (already normalized by defineConfig() with defaults)\n if (!contractConfig.output || !contractConfig.types) {\n throw errorContractConfigMissing({\n why: 'Contract config must have output and types paths. This should not happen if defineConfig() was used.',\n });\n }\n const outputJsonPath = resolve(contractConfig.output);\n const outputDtsPath = resolve(contractConfig.types);\n\n // Output header (only for human-readable output)\n if (flags.json !== 'object' && !flags.quiet) {\n // Normalize config path for display (match contract path format - no ./ prefix)\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n // Convert absolute paths to relative paths for display\n const contractPath = relative(process.cwd(), outputJsonPath);\n const typesPath = relative(process.cwd(), outputDtsPath);\n const header = formatStyledHeader({\n command: 'contract emit',\n description: 'Write your contract to JSON and sign it',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'types', value: typesPath },\n ],\n flags,\n });\n console.log(header);\n }\n\n // Create family instance (assembles operation registry, type imports, extension IDs)\n // Note: emit command doesn't need driver, but ControlFamilyDescriptor.create() requires it\n // We'll need to provide a minimal driver descriptor or make driver optional for emit\n // For now, we'll require driver to be present in config even for emit\n if (!config.driver) {\n throw errorContractConfigMissing({\n why: 'Config.driver is required. Even though emit does not use the driver, it is required by ControlFamilyDescriptor.create()',\n });\n }\n const familyInstance = config.family.create({\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Resolve contract source from config (user's config handles loading)\n let contractRaw: unknown;\n if (typeof contractConfig.source === 'function') {\n contractRaw = await contractConfig.source();\n } else {\n contractRaw = contractConfig.source;\n }\n\n // Call emitContract on family instance (handles stripping mappings and validation internally)\n const emitResult = await withSpinner(\n () => familyInstance.emitContract({ contractIR: contractRaw }),\n {\n message: 'Emitting contract...',\n flags,\n },\n );\n\n // Create directories if needed\n mkdirSync(dirname(outputJsonPath), { recursive: true });\n mkdirSync(dirname(outputDtsPath), { recursive: true });\n\n // Write the results to files\n writeFileSync(outputJsonPath, emitResult.contractJson, 'utf-8');\n writeFileSync(outputDtsPath, emitResult.contractDts, 'utf-8');\n\n // Add blank line after all async operations if spinners were shown\n if (!flags.quiet && flags.json !== 'object' && process.stdout.isTTY) {\n console.log('');\n }\n\n // Return result with file paths for output formatting\n return {\n coreHash: emitResult.coreHash,\n profileHash: emitResult.profileHash,\n outDir: dirname(outputJsonPath),\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n timings: {\n total: 0, // Timing is handled by emitContract internally if needed\n },\n };\n });\n\n // Handle result - formats output and returns exit code\n const exitCode = handleResult(result, flags, (emitResult) => {\n // Output based on flags\n if (flags.json === 'object') {\n // JSON output to stdout\n console.log(formatEmitJson(emitResult));\n } else {\n // Human-readable output to stdout\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n console.log(output);\n }\n // Output success message\n if (!flags.quiet) {\n console.log(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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","names":[]}
|