@prisma-next/cli 0.14.0-dev.3 → 0.14.0-dev.5
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 +2 -2
- package/dist/cli.mjs +29 -12
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-CJzuo5wX.mjs → client-EnAjSmZg.mjs} +4 -4
- package/dist/{client-CJzuo5wX.mjs.map → client-EnAjSmZg.mjs.map} +1 -1
- package/dist/{command-helpers-DGMvGBeX.mjs → command-helpers-6cNJZ863.mjs} +3 -3
- package/dist/{command-helpers-DGMvGBeX.mjs.map → command-helpers-6cNJZ863.mjs.map} +1 -1
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.mjs +3 -3
- package/dist/commands/db-schema.mjs +3 -3
- package/dist/commands/db-sign.mjs +5 -5
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.mjs +4 -4
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.mjs +6 -6
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.d.mts +1 -1
- package/dist/commands/migration-check.mjs +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +4 -4
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +1 -1
- package/dist/commands/migration-list.mjs +1 -1
- package/dist/commands/migration-log.d.mts +1 -1
- package/dist/commands/migration-log.mjs +1 -1
- package/dist/commands/migration-new.mjs +4 -4
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.mjs +4 -4
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +1 -1
- package/dist/commands/migration-status.mjs +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +3 -3
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/commands/telemetry/index.mjs +1 -1
- package/dist/{contract-at-errors-CFXsstzm.mjs → contract-at-errors-DdxWRjMc.mjs} +2 -2
- package/dist/{contract-at-errors-CFXsstzm.mjs.map → contract-at-errors-DdxWRjMc.mjs.map} +1 -1
- package/dist/{contract-emit-B_qriF8B.mjs → contract-emit-D4xDDFkO.mjs} +6 -6
- package/dist/contract-emit-D4xDDFkO.mjs.map +1 -0
- package/dist/{contract-emit-C8HmtboH.mjs → contract-emit-fz6pDR2n.mjs} +4 -4
- package/dist/contract-emit-fz6pDR2n.mjs.map +1 -0
- package/dist/{contract-infer-BYT_ra_U.mjs → contract-infer-Ars4yjBv.mjs} +3 -3
- package/dist/{contract-infer-BYT_ra_U.mjs.map → contract-infer-Ars4yjBv.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-ClI1KN6d.mjs → contract-space-aggregate-loader-Bu2fjSWV.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-ClI1KN6d.mjs.map → contract-space-aggregate-loader-Bu2fjSWV.mjs.map} +1 -1
- package/dist/{db-verify-C24FKhb7.mjs → db-verify-CZxRV_er.mjs} +5 -5
- package/dist/db-verify-CZxRV_er.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.d.mts +5 -1
- package/dist/exports/index.d.mts.map +1 -1
- package/dist/exports/index.mjs +4 -3
- package/dist/exports/index.mjs.map +1 -1
- package/dist/format-C3XdaDuA.mjs +102 -0
- package/dist/format-C3XdaDuA.mjs.map +1 -0
- package/dist/{framework-components-YVQHhPH7.mjs → framework-components-5RljWT7Q.mjs} +2 -2
- package/dist/{framework-components-YVQHhPH7.mjs.map → framework-components-5RljWT7Q.mjs.map} +1 -1
- package/dist/{init-0HwB-Vh8.mjs → init-C79Yb97u.mjs} +12 -8
- package/dist/init-C79Yb97u.mjs.map +1 -0
- package/dist/{inspect-live-schema-DF6IwcDl.mjs → inspect-live-schema-DR8Eyt29.mjs} +4 -4
- package/dist/inspect-live-schema-DR8Eyt29.mjs.map +1 -0
- package/dist/{migration-check-soB5uZEQ.mjs → migration-check-CTcJfCC4.mjs} +5 -5
- package/dist/migration-check-CTcJfCC4.mjs.map +1 -0
- package/dist/migration-cli.mjs +1 -1
- package/dist/migration-cli.mjs.map +1 -1
- package/dist/{migration-command-scaffold-DA-Lhx6o.mjs → migration-command-scaffold-6OT_Q-3Y.mjs} +4 -4
- package/dist/migration-command-scaffold-6OT_Q-3Y.mjs.map +1 -0
- package/dist/{migration-list-DlJJ_38Z.mjs → migration-list-DVHVmMrf.mjs} +4 -4
- package/dist/migration-list-DVHVmMrf.mjs.map +1 -0
- package/dist/{migration-log-CG0qQAFm.mjs → migration-log-CQpc9JoL.mjs} +4 -4
- package/dist/migration-log-CQpc9JoL.mjs.map +1 -0
- package/dist/{migration-path-target-Ce6OZImp.mjs → migration-path-target-zK6RG6JY.mjs} +2 -2
- package/dist/{migration-path-target-Ce6OZImp.mjs.map → migration-path-target-zK6RG6JY.mjs.map} +1 -1
- package/dist/{migration-plan-W_E8FQOk.mjs → migration-plan-o2aqjnfd.mjs} +6 -6
- package/dist/migration-plan-o2aqjnfd.mjs.map +1 -0
- package/dist/{migration-status-CgWSoI_g.mjs → migration-status-2aXGtYMW.mjs} +6 -6
- package/dist/migration-status-2aXGtYMW.mjs.map +1 -0
- package/dist/{telemetry-BIM4beEO.mjs → telemetry-BckOSUWG.mjs} +2 -2
- package/dist/{telemetry-BIM4beEO.mjs.map → telemetry-BckOSUWG.mjs.map} +1 -1
- package/dist/{types-C_tYiJYx.d.mts → types-qETCCNbe.d.mts} +2 -2
- package/dist/{types-C_tYiJYx.d.mts.map → types-qETCCNbe.d.mts.map} +1 -1
- package/dist/{verify-DcOYZ1tH.mjs → verify-DLqhL2LU.mjs} +2 -2
- package/dist/{verify-DcOYZ1tH.mjs.map → verify-DLqhL2LU.mjs.map} +1 -1
- package/package.json +21 -23
- package/src/cli.ts +7 -0
- package/src/commands/contract-emit.ts +1 -1
- package/src/commands/db-sign.ts +1 -1
- package/src/commands/db-verify.ts +1 -1
- package/src/commands/format.ts +75 -0
- package/src/commands/init/detect-package-manager.ts +8 -4
- package/src/commands/init/hygiene-package-scripts.ts +16 -3
- package/src/commands/inspect-live-schema.ts +1 -1
- package/src/commands/lsp.ts +30 -0
- package/src/commands/migrate.ts +1 -1
- package/src/commands/migration-check.ts +1 -1
- package/src/commands/migration-graph.ts +1 -1
- package/src/commands/migration-list.ts +1 -1
- package/src/commands/migration-log.ts +1 -1
- package/src/commands/migration-new.ts +1 -1
- package/src/commands/migration-plan.ts +1 -1
- package/src/commands/migration-show.ts +1 -1
- package/src/commands/migration-status.ts +1 -1
- package/src/commands/ref.ts +1 -1
- package/src/control-api/operations/contract-emit.ts +1 -1
- package/src/control-api/operations/format.ts +98 -0
- package/src/exports/index.ts +1 -0
- package/src/migration-cli.ts +1 -1
- package/src/utils/migration-command-scaffold.ts +1 -1
- package/dist/config-loader-p9JMrekQ.mjs +0 -88
- package/dist/config-loader-p9JMrekQ.mjs.map +0 -1
- package/dist/config-loader.d.mts +0 -16
- package/dist/config-loader.d.mts.map +0 -1
- package/dist/config-loader.mjs +0 -2
- package/dist/contract-emit-B_qriF8B.mjs.map +0 -1
- package/dist/contract-emit-C8HmtboH.mjs.map +0 -1
- package/dist/db-verify-C24FKhb7.mjs.map +0 -1
- package/dist/init-0HwB-Vh8.mjs.map +0 -1
- package/dist/inspect-live-schema-DF6IwcDl.mjs.map +0 -1
- package/dist/migration-check-soB5uZEQ.mjs.map +0 -1
- package/dist/migration-command-scaffold-DA-Lhx6o.mjs.map +0 -1
- package/dist/migration-list-DlJJ_38Z.mjs.map +0 -1
- package/dist/migration-log-CG0qQAFm.mjs.map +0 -1
- package/dist/migration-plan-W_E8FQOk.mjs.map +0 -1
- package/dist/migration-status-CgWSoI_g.mjs.map +0 -1
- package/src/config-loader.ts +0 -92
- package/src/config-path-validation.ts +0 -74
|
@@ -6,6 +6,10 @@ export type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun' | 'deno';
|
|
|
6
6
|
|
|
7
7
|
const KNOWN: ReadonlySet<string> = new Set<PackageManager>(['pnpm', 'npm', 'yarn', 'bun', 'deno']);
|
|
8
8
|
|
|
9
|
+
function isPackageManager(name: string): name is PackageManager {
|
|
10
|
+
return KNOWN.has(name);
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
/**
|
|
10
14
|
* Resolves the package manager `init` should drive for `add` / `install`
|
|
11
15
|
* commands. Tries, in order:
|
|
@@ -28,12 +32,12 @@ const KNOWN: ReadonlySet<string> = new Set<PackageManager>(['pnpm', 'npm', 'yarn
|
|
|
28
32
|
*/
|
|
29
33
|
export async function detectPackageManager(cwd: string): Promise<PackageManager> {
|
|
30
34
|
const detected = await detect({ cwd });
|
|
31
|
-
if (detected &&
|
|
32
|
-
return detected.name
|
|
35
|
+
if (detected && isPackageManager(detected.name)) {
|
|
36
|
+
return detected.name;
|
|
33
37
|
}
|
|
34
38
|
const userAgent = getUserAgent();
|
|
35
|
-
if (userAgent !== null &&
|
|
36
|
-
return userAgent
|
|
39
|
+
if (userAgent !== null && isPackageManager(userAgent)) {
|
|
40
|
+
return userAgent;
|
|
37
41
|
}
|
|
38
42
|
return 'npm';
|
|
39
43
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The package.json `scripts` entries `init` adds idempotently (FR3.5).
|
|
3
5
|
* The script *name* mirrors the CLI subcommand path (`contract:emit` →
|
|
@@ -58,10 +60,18 @@ export function mergePackageScripts(
|
|
|
58
60
|
existing: string,
|
|
59
61
|
required: readonly RequiredScript[] = REQUIRED_SCRIPTS,
|
|
60
62
|
): PackageScriptsMergeResult {
|
|
61
|
-
const parsed =
|
|
63
|
+
const parsed = blindCast<
|
|
64
|
+
Record<string, unknown>,
|
|
65
|
+
'JSON.parse returns `unknown`; package.json is a JSON object so its top level is a string-keyed record'
|
|
66
|
+
>(JSON.parse(existing));
|
|
62
67
|
const scripts: Record<string, string> =
|
|
63
68
|
typeof parsed['scripts'] === 'object' && parsed['scripts'] !== null
|
|
64
|
-
? {
|
|
69
|
+
? {
|
|
70
|
+
...blindCast<
|
|
71
|
+
Record<string, string>,
|
|
72
|
+
'guarded above: parsed.scripts is a non-null object; package.json `scripts` values are command strings'
|
|
73
|
+
>(parsed['scripts']),
|
|
74
|
+
}
|
|
65
75
|
: {};
|
|
66
76
|
|
|
67
77
|
const warnings: string[] = [];
|
|
@@ -131,7 +141,10 @@ export interface EsmModuleTypeResult {
|
|
|
131
141
|
* ESM and we don't silently overwrite that.
|
|
132
142
|
*/
|
|
133
143
|
export function ensureEsmModuleType(existing: string): EsmModuleTypeResult {
|
|
134
|
-
const parsed =
|
|
144
|
+
const parsed = blindCast<
|
|
145
|
+
Record<string, unknown>,
|
|
146
|
+
'JSON.parse returns `unknown`; package.json is a JSON object so its top level is a string-keyed record'
|
|
147
|
+
>(JSON.parse(existing));
|
|
135
148
|
const currentType = parsed['type'];
|
|
136
149
|
|
|
137
150
|
if (currentType === 'module') {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
1
2
|
import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring';
|
|
2
3
|
import type { CoreSchemaView } from '@prisma-next/framework-components/control';
|
|
3
4
|
import type { PslDocumentAst } from '@prisma-next/framework-components/psl-ast';
|
|
4
5
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
5
6
|
import { relative, resolve } from 'pathe';
|
|
6
|
-
import { loadConfig } from '../config-loader';
|
|
7
7
|
import { createControlClient } from '../control-api/client';
|
|
8
8
|
import {
|
|
9
9
|
CliStructuredError,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import {
|
|
3
|
+
addGlobalOptions,
|
|
4
|
+
setCommandDescriptions,
|
|
5
|
+
setCommandExamples,
|
|
6
|
+
} from '../utils/command-helpers';
|
|
7
|
+
|
|
8
|
+
export function createLspCommand(): Command {
|
|
9
|
+
const command = new Command('lsp');
|
|
10
|
+
setCommandDescriptions(
|
|
11
|
+
command,
|
|
12
|
+
'Start the Prisma Next language server',
|
|
13
|
+
'Launches a Language Server Protocol server that publishes PSL parse diagnostics\n' +
|
|
14
|
+
'for the schema inputs declared in your config (contract.source.inputs).\n' +
|
|
15
|
+
'Communicates over stdio; intended to be spawned by an\n' +
|
|
16
|
+
'editor, not run interactively. The server keeps running until the editor client\n' +
|
|
17
|
+
'disconnects.',
|
|
18
|
+
);
|
|
19
|
+
setCommandExamples(command, ['prisma-next lsp --stdio']);
|
|
20
|
+
addGlobalOptions(command)
|
|
21
|
+
.option('--stdio', 'Communicate with the editor over stdio (the default and only transport)')
|
|
22
|
+
.action(async () => {
|
|
23
|
+
// Lazy import so `vscode-languageserver` stays off every other command's
|
|
24
|
+
// startup path — only `prisma-next lsp` pays its load cost.
|
|
25
|
+
const { startServer } = await import('@prisma-next/language-server');
|
|
26
|
+
startServer();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return command;
|
|
30
|
+
}
|
package/src/commands/migrate.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
2
3
|
import type { Contract } from '@prisma-next/contract/types';
|
|
3
4
|
import { createControlStack } from '@prisma-next/framework-components/control';
|
|
4
5
|
import { type ContractSpaceMember, requireHeadRef } from '@prisma-next/migration-tools/aggregate';
|
|
@@ -11,7 +12,6 @@ import { readRefs } from '@prisma-next/migration-tools/refs';
|
|
|
11
12
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
12
13
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
13
14
|
import { Command } from 'commander';
|
|
14
|
-
import { loadConfig } from '../config-loader';
|
|
15
15
|
import { createControlClient } from '../control-api/client';
|
|
16
16
|
import { planMemberPath } from '../control-api/operations/migrate';
|
|
17
17
|
import type {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
3
4
|
import { createControlStack } from '@prisma-next/framework-components/control';
|
|
4
5
|
import type {
|
|
5
6
|
ContractSpaceAggregate,
|
|
@@ -25,7 +26,6 @@ import { ifDefined } from '@prisma-next/utils/defined';
|
|
|
25
26
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
26
27
|
import { Command } from 'commander';
|
|
27
28
|
import { join, relative } from 'pathe';
|
|
28
|
-
import { loadConfig } from '../config-loader';
|
|
29
29
|
import {
|
|
30
30
|
type CliStructuredError,
|
|
31
31
|
errorAmbiguousMigrationRef,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
1
2
|
import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';
|
|
2
3
|
import type { MigrationGraph } from '@prisma-next/migration-tools/graph';
|
|
3
4
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
4
5
|
import { ok, type Result } from '@prisma-next/utils/result';
|
|
5
6
|
import { Command } from 'commander';
|
|
6
|
-
import { loadConfig } from '../config-loader';
|
|
7
7
|
import type { CliStructuredError } from '../utils/cli-errors';
|
|
8
8
|
import {
|
|
9
9
|
addGlobalOptions,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
1
2
|
import type {
|
|
2
3
|
ContractSpaceAggregate,
|
|
3
4
|
ContractSpaceMember,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
14
15
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
15
16
|
import { Command } from 'commander';
|
|
16
|
-
import { loadConfig } from '../config-loader';
|
|
17
17
|
import {
|
|
18
18
|
type CliStructuredError,
|
|
19
19
|
errorInvalidSpaceId,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
1
2
|
import type { LedgerEntryRecord } from '@prisma-next/contract/types';
|
|
2
3
|
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
3
4
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
4
5
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
5
6
|
import { Command } from 'commander';
|
|
6
|
-
import { loadConfig } from '../config-loader';
|
|
7
7
|
import { createControlClient } from '../control-api/client';
|
|
8
8
|
import {
|
|
9
9
|
CliStructuredError,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { readFile } from 'node:fs/promises';
|
|
12
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
12
13
|
import type { Contract } from '@prisma-next/contract/types';
|
|
13
14
|
import { getEmittedArtifactPaths } from '@prisma-next/emitter';
|
|
14
15
|
import { APP_SPACE_ID, createControlStack } from '@prisma-next/framework-components/control';
|
|
@@ -25,7 +26,6 @@ import { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';
|
|
|
25
26
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
26
27
|
import { Command } from 'commander';
|
|
27
28
|
import { join, relative } from 'pathe';
|
|
28
|
-
import { loadConfig } from '../config-loader';
|
|
29
29
|
import {
|
|
30
30
|
CliStructuredError,
|
|
31
31
|
errorFileNotFound,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
2
3
|
import type { Contract } from '@prisma-next/contract/types';
|
|
3
4
|
import { getEmittedArtifactPaths } from '@prisma-next/emitter';
|
|
4
5
|
import {
|
|
@@ -21,7 +22,6 @@ import { writeMigrationTs } from '@prisma-next/migration-tools/migration-ts';
|
|
|
21
22
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
22
23
|
import { Command } from 'commander';
|
|
23
24
|
import { join, relative } from 'pathe';
|
|
24
|
-
import { loadConfig } from '../config-loader';
|
|
25
25
|
import {
|
|
26
26
|
type CliErrorConflict,
|
|
27
27
|
CliStructuredError,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
2
3
|
import type { Contract } from '@prisma-next/contract/types';
|
|
3
4
|
import {
|
|
4
5
|
APP_SPACE_ID,
|
|
@@ -13,7 +14,6 @@ import { ifDefined } from '@prisma-next/utils/defined';
|
|
|
13
14
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
14
15
|
import { Command } from 'commander';
|
|
15
16
|
import { relative } from 'pathe';
|
|
16
|
-
import { loadConfig } from '../config-loader';
|
|
17
17
|
import { createControlClient } from '../control-api/client';
|
|
18
18
|
import {
|
|
19
19
|
type CliStructuredError,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
1
2
|
import type { LedgerEntryRecord } from '@prisma-next/contract/types';
|
|
2
3
|
import type {
|
|
3
4
|
ContractMarkerRecordLike,
|
|
@@ -17,7 +18,6 @@ import { ifDefined } from '@prisma-next/utils/defined';
|
|
|
17
18
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
18
19
|
import { dim, yellow } from 'colorette';
|
|
19
20
|
import { Command } from 'commander';
|
|
20
|
-
import { loadConfig } from '../config-loader';
|
|
21
21
|
import { createControlClient } from '../control-api/client';
|
|
22
22
|
import {
|
|
23
23
|
CliStructuredError,
|
package/src/commands/ref.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
2
3
|
import { EMPTY_CONTRACT_HASH } from '@prisma-next/migration-tools/constants';
|
|
3
4
|
import { MigrationToolsError } from '@prisma-next/migration-tools/errors';
|
|
4
5
|
import { findLatestMigration, isGraphNode } from '@prisma-next/migration-tools/migration-graph';
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
15
16
|
import { Command } from 'commander';
|
|
16
17
|
import { join } from 'pathe';
|
|
17
|
-
import { loadConfig } from '../config-loader';
|
|
18
18
|
import {
|
|
19
19
|
CliStructuredError,
|
|
20
20
|
errorFileNotFound,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mkdir } from 'node:fs/promises';
|
|
2
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
2
3
|
import type { Contract } from '@prisma-next/contract/types';
|
|
3
4
|
import { emit, getEmittedArtifactPaths } from '@prisma-next/emitter';
|
|
4
5
|
import { createControlStack } from '@prisma-next/framework-components/control';
|
|
@@ -7,7 +8,6 @@ import { blindCast } from '@prisma-next/utils/casts';
|
|
|
7
8
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
8
9
|
import type { JsonObject } from '@prisma-next/utils/json';
|
|
9
10
|
import { dirname, join } from 'pathe';
|
|
10
|
-
import { loadConfig } from '../../config-loader';
|
|
11
11
|
import { errorContractConfigMissing, errorRuntime } from '../../utils/cli-errors';
|
|
12
12
|
import { queueEmitByOutput } from '../../utils/emit-queue';
|
|
13
13
|
import { toExtensionInputs } from '../../utils/extension-pack-inputs';
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { EOL } from 'node:os';
|
|
3
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
4
|
+
import { type FormatOptions, format, PslFormatError } from '@prisma-next/psl-parser/format';
|
|
5
|
+
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
6
|
+
import { CliStructuredError, errorRuntime, errorUnexpected } from '../../utils/cli-errors';
|
|
7
|
+
|
|
8
|
+
export interface FormatOperationOptions {
|
|
9
|
+
readonly configPath?: string;
|
|
10
|
+
readonly eol?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface FormatOperationResult {
|
|
14
|
+
readonly formatted: boolean;
|
|
15
|
+
readonly path?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function resolveNewline(
|
|
19
|
+
formatterNewline: 'LF' | 'CRLF' | undefined,
|
|
20
|
+
eol: string,
|
|
21
|
+
): 'LF' | 'CRLF' {
|
|
22
|
+
if (formatterNewline !== undefined) {
|
|
23
|
+
return formatterNewline;
|
|
24
|
+
}
|
|
25
|
+
return eol === '\r\n' ? 'CRLF' : 'LF';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function executeFormat(
|
|
29
|
+
options: FormatOperationOptions,
|
|
30
|
+
): Promise<Result<FormatOperationResult, CliStructuredError>> {
|
|
31
|
+
const eol = options.eol ?? EOL;
|
|
32
|
+
|
|
33
|
+
let config: Awaited<ReturnType<typeof loadConfig>>;
|
|
34
|
+
try {
|
|
35
|
+
config = await loadConfig(options.configPath);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (CliStructuredError.is(error)) {
|
|
38
|
+
return notOk(error);
|
|
39
|
+
}
|
|
40
|
+
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error)));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const source = config.contract?.source;
|
|
44
|
+
if (source?.sourceFormat !== 'psl') {
|
|
45
|
+
return ok({ formatted: false });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const inputPath = source.inputs?.[0];
|
|
49
|
+
if (inputPath === undefined) {
|
|
50
|
+
return ok({ formatted: false });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let contents: string;
|
|
54
|
+
try {
|
|
55
|
+
contents = await readFile(inputPath, 'utf-8');
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return notOk(
|
|
58
|
+
errorRuntime('Failed to read contract source file', {
|
|
59
|
+
why: error instanceof Error ? error.message : String(error),
|
|
60
|
+
fix: `Check that ${inputPath} exists and is readable.`,
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const formatOptions: FormatOptions = {
|
|
66
|
+
indent: config.formatter?.indent ?? 2,
|
|
67
|
+
newline: resolveNewline(config.formatter?.newline, eol),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
let formatted: string;
|
|
71
|
+
try {
|
|
72
|
+
formatted = format(contents, formatOptions);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof PslFormatError) {
|
|
75
|
+
return notOk(
|
|
76
|
+
errorRuntime('Cannot format PSL with parse errors', {
|
|
77
|
+
why: error.message,
|
|
78
|
+
fix: 'Fix the parse errors in your schema and try again.',
|
|
79
|
+
meta: { diagnostics: error.diagnostics },
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return notOk(errorUnexpected(error instanceof Error ? error.message : String(error)));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
await writeFile(inputPath, formatted, 'utf-8');
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return notOk(
|
|
90
|
+
errorRuntime('Failed to write formatted contract source file', {
|
|
91
|
+
why: error instanceof Error ? error.message : String(error),
|
|
92
|
+
fix: `Check that ${inputPath} is writable.`,
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return ok({ formatted: true, path: inputPath });
|
|
98
|
+
}
|
package/src/exports/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// CLI-specific exports
|
|
2
2
|
export { createContractEmitCommand } from '../commands/contract-emit';
|
|
3
|
+
export { createFormatCommand } from '../commands/format';
|
|
3
4
|
export type { LoadTsContractOptions } from '../load-ts-contract';
|
|
4
5
|
export { loadContractFromTs } from '../load-ts-contract';
|
package/src/migration-cli.ts
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
import { readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
|
46
46
|
import type { Writable } from 'node:stream';
|
|
47
47
|
import { fileURLToPath } from 'node:url';
|
|
48
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
48
49
|
import {
|
|
49
50
|
CliStructuredError,
|
|
50
51
|
errorMigrationCliInvalidConfigArg,
|
|
@@ -57,7 +58,6 @@ import type { MigrationMetadata } from '@prisma-next/migration-tools/metadata';
|
|
|
57
58
|
import { buildMigrationArtifacts, type Migration } from '@prisma-next/migration-tools/migration';
|
|
58
59
|
import { Cli, Command, Option, UsageError } from 'clipanion';
|
|
59
60
|
import { dirname, join } from 'pathe';
|
|
60
|
-
import { loadConfig } from './config-loader';
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* Constructor shape accepted by `MigrationCLI.run`. `Migration` subclasses
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { relative, resolve } from 'node:path';
|
|
3
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
3
4
|
import { hasMigrations } from '@prisma-next/framework-components/control';
|
|
4
5
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
5
6
|
import type { Command } from 'commander';
|
|
6
|
-
import { loadConfig } from '../config-loader';
|
|
7
7
|
import { createControlClient } from '../control-api/client';
|
|
8
8
|
import type { ControlClient } from '../control-api/types';
|
|
9
9
|
import {
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { getEmittedArtifactPaths } from "@prisma-next/emitter";
|
|
2
|
-
import { errorConfigFileNotFound, errorConfigValidation, errorUnexpected } from "@prisma-next/errors/control";
|
|
3
|
-
import { ifDefined } from "@prisma-next/utils/defined";
|
|
4
|
-
import { dirname, resolve } from "pathe";
|
|
5
|
-
import { ConfigValidationError, validateConfig } from "@prisma-next/config/config-validation";
|
|
6
|
-
import { loadConfig } from "c12";
|
|
7
|
-
import { normalizeContractConfig } from "@prisma-next/config/config-types";
|
|
8
|
-
//#region src/config-path-validation.ts
|
|
9
|
-
function throwValidation(field, why) {
|
|
10
|
-
throw new ConfigValidationError(field, why);
|
|
11
|
-
}
|
|
12
|
-
function finalizeContractSource(source, configDir) {
|
|
13
|
-
const resolvedInputs = source.inputs?.map((input) => resolve(configDir, input));
|
|
14
|
-
if (resolvedInputs === void 0) return source;
|
|
15
|
-
return {
|
|
16
|
-
...source,
|
|
17
|
-
inputs: resolvedInputs
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
function validateNoOutputsAreInputs(inputs, output) {
|
|
21
|
-
if (inputs === void 0 || output === void 0) return;
|
|
22
|
-
let emittedArtifactPaths;
|
|
23
|
-
try {
|
|
24
|
-
emittedArtifactPaths = getEmittedArtifactPaths(output);
|
|
25
|
-
} catch (error) {
|
|
26
|
-
throwValidation("contract.output", error instanceof Error ? error.message : String(error));
|
|
27
|
-
}
|
|
28
|
-
const emittedPaths = new Set([emittedArtifactPaths.jsonPath, emittedArtifactPaths.dtsPath]);
|
|
29
|
-
for (const input of inputs) if (emittedPaths.has(input)) throwValidation("contract.source.inputs[]", "Config.contract.source.inputs must not include emitted artifact paths derived from contract.output");
|
|
30
|
-
}
|
|
31
|
-
function finalizeConfig(config, configDir) {
|
|
32
|
-
if (!config.contract) return config;
|
|
33
|
-
const contract = normalizeContractConfig(config.contract);
|
|
34
|
-
const source = finalizeContractSource(contract.source, configDir);
|
|
35
|
-
const output = resolve(configDir, contract.output);
|
|
36
|
-
validateNoOutputsAreInputs(source.inputs, output);
|
|
37
|
-
return {
|
|
38
|
-
...config,
|
|
39
|
-
contract: {
|
|
40
|
-
...contract,
|
|
41
|
-
source,
|
|
42
|
-
output
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region src/config-loader.ts
|
|
48
|
-
async function loadValidatedConfig(configPath) {
|
|
49
|
-
const cwd = process.cwd();
|
|
50
|
-
const resolvedConfigPath = configPath ? resolve(cwd, configPath) : void 0;
|
|
51
|
-
const configCwd = resolvedConfigPath ? dirname(resolvedConfigPath) : cwd;
|
|
52
|
-
const result = await loadConfig({
|
|
53
|
-
name: "prisma-next",
|
|
54
|
-
...ifDefined("configFile", resolvedConfigPath),
|
|
55
|
-
cwd: configCwd
|
|
56
|
-
});
|
|
57
|
-
if (resolvedConfigPath && result.configFile !== resolvedConfigPath) throw errorConfigFileNotFound(resolvedConfigPath);
|
|
58
|
-
if (!result.config || Object.keys(result.config).length === 0) throw errorConfigFileNotFound(result.configFile || resolvedConfigPath || configPath);
|
|
59
|
-
validateConfig(result.config);
|
|
60
|
-
const loadedConfigDir = result.configFile ? dirname(result.configFile) : configCwd;
|
|
61
|
-
return finalizeConfig(result.config, loadedConfigDir);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Loads the Prisma Next config from a TypeScript file.
|
|
65
|
-
* Supports both default export and named export.
|
|
66
|
-
* Uses c12 to automatically handle TypeScript compilation and config file discovery.
|
|
67
|
-
*
|
|
68
|
-
* @param configPath - Optional path to config file. Defaults to `./prisma-next.config.ts` in current directory.
|
|
69
|
-
* @returns The loaded config object.
|
|
70
|
-
* @throws Error if config file doesn't exist or is invalid.
|
|
71
|
-
*/
|
|
72
|
-
async function loadConfig$1(configPath) {
|
|
73
|
-
try {
|
|
74
|
-
return await loadValidatedConfig(configPath);
|
|
75
|
-
} catch (error) {
|
|
76
|
-
if (error instanceof ConfigValidationError) throw errorConfigValidation(error.field, { why: error.why });
|
|
77
|
-
if (error instanceof Error && "code" in error && typeof error.code === "string") throw error;
|
|
78
|
-
if (error instanceof Error) {
|
|
79
|
-
if (error.message.includes("not found") || error.message.includes("Cannot find") || error.message.includes("ENOENT")) throw errorConfigFileNotFound(configPath ? resolve(process.cwd(), configPath) : void 0, { why: error.message });
|
|
80
|
-
throw errorUnexpected(error.message, { why: `Failed to load config: ${error.message}` });
|
|
81
|
-
}
|
|
82
|
-
throw errorUnexpected(String(error));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
//#endregion
|
|
86
|
-
export { loadConfig$1 as t };
|
|
87
|
-
|
|
88
|
-
//# sourceMappingURL=config-loader-p9JMrekQ.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader-p9JMrekQ.mjs","names":["loadConfigC12","loadConfig"],"sources":["../src/config-path-validation.ts","../src/config-loader.ts"],"sourcesContent":["import {\n type ContractSourceProvider,\n normalizeContractConfig,\n type PrismaNextConfig,\n} from '@prisma-next/config/config-types';\nimport { ConfigValidationError } from '@prisma-next/config/config-validation';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { resolve } from 'pathe';\n\nfunction throwValidation(field: string, why: string): never {\n throw new ConfigValidationError(field, why);\n}\n\nfunction finalizeContractSource(\n source: ContractSourceProvider,\n configDir: string,\n): ContractSourceProvider {\n const resolvedInputs = source.inputs?.map((input) => resolve(configDir, input));\n if (resolvedInputs === undefined) {\n return source;\n }\n\n return {\n ...source,\n inputs: resolvedInputs,\n };\n}\n\nfunction validateNoOutputsAreInputs(\n inputs: readonly string[] | undefined,\n output: string | undefined,\n): void {\n if (inputs === undefined || output === undefined) {\n return;\n }\n\n let emittedArtifactPaths: ReturnType<typeof getEmittedArtifactPaths>;\n try {\n emittedArtifactPaths = getEmittedArtifactPaths(output);\n } catch (error) {\n throwValidation('contract.output', error instanceof Error ? error.message : String(error));\n }\n\n const emittedPaths = new Set([emittedArtifactPaths.jsonPath, emittedArtifactPaths.dtsPath]);\n\n for (const input of inputs) {\n if (emittedPaths.has(input)) {\n throwValidation(\n 'contract.source.inputs[]',\n 'Config.contract.source.inputs must not include emitted artifact paths derived from contract.output',\n );\n }\n }\n}\n\nexport function finalizeConfig(config: PrismaNextConfig, configDir: string): PrismaNextConfig {\n if (!config.contract) {\n return config;\n }\n const contract = normalizeContractConfig(config.contract);\n const source = finalizeContractSource(contract.source, configDir);\n const output = resolve(configDir, contract.output);\n\n validateNoOutputsAreInputs(source.inputs, output);\n\n return {\n ...config,\n contract: {\n ...contract,\n source,\n output,\n },\n };\n}\n","import type { PrismaNextConfig } from '@prisma-next/config/config-types';\nimport { ConfigValidationError, validateConfig } from '@prisma-next/config/config-validation';\nimport {\n errorConfigFileNotFound,\n errorConfigValidation,\n errorUnexpected,\n} from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { loadConfig as loadConfigC12 } from 'c12';\nimport { dirname, resolve } from 'pathe';\nimport { finalizeConfig } from './config-path-validation';\n\nasync function loadValidatedConfig(configPath?: string): Promise<PrismaNextConfig> {\n const cwd = process.cwd();\n const resolvedConfigPath = configPath ? resolve(cwd, configPath) : undefined;\n const configCwd = resolvedConfigPath ? dirname(resolvedConfigPath) : cwd;\n\n const result = await loadConfigC12<PrismaNextConfig>({\n name: 'prisma-next',\n ...ifDefined('configFile', resolvedConfigPath),\n cwd: configCwd,\n });\n\n // When a specific config file was requested, verify it was actually loaded\n // (c12 falls back to searching by name if the specified file doesn't exist)\n if (resolvedConfigPath && result.configFile !== resolvedConfigPath) {\n throw errorConfigFileNotFound(resolvedConfigPath);\n }\n\n // Check if config is missing or empty (c12 may return empty object when file doesn't exist)\n if (!result.config || Object.keys(result.config).length === 0) {\n // Use c12's configFile if available, otherwise use explicit configPath, otherwise omit path\n const displayPath = result.configFile || resolvedConfigPath || configPath;\n throw errorConfigFileNotFound(displayPath);\n }\n\n // Validate config structure\n validateConfig(result.config);\n\n const loadedConfigDir = result.configFile ? dirname(result.configFile) : configCwd;\n return finalizeConfig(result.config, loadedConfigDir);\n}\n\n/**\n * Loads the Prisma Next config from a TypeScript file.\n * Supports both default export and named export.\n * Uses c12 to automatically handle TypeScript compilation and config file discovery.\n *\n * @param configPath - Optional path to config file. Defaults to `./prisma-next.config.ts` in current directory.\n * @returns The loaded config object.\n * @throws Error if config file doesn't exist or is invalid.\n */\nexport async function loadConfig(configPath?: string): Promise<PrismaNextConfig> {\n try {\n return await loadValidatedConfig(configPath);\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw errorConfigValidation(error.field, {\n why: error.why,\n });\n }\n\n // Re-throw structured errors as-is\n if (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code: string }).code === 'string'\n ) {\n throw error;\n }\n\n if (error instanceof Error) {\n // Check for file not found errors\n if (\n error.message.includes('not found') ||\n error.message.includes('Cannot find') ||\n error.message.includes('ENOENT')\n ) {\n // Use resolved path if available, otherwise use original configPath\n const displayPath = configPath ? resolve(process.cwd(), configPath) : undefined;\n throw errorConfigFileNotFound(displayPath, {\n why: error.message,\n });\n }\n // For other errors, wrap in unexpected error\n throw errorUnexpected(error.message, {\n why: `Failed to load config: ${error.message}`,\n });\n }\n throw errorUnexpected(String(error));\n }\n}\n"],"mappings":";;;;;;;;AASA,SAAS,gBAAgB,OAAe,KAAoB;CAC1D,MAAM,IAAI,sBAAsB,OAAO,GAAG;AAC5C;AAEA,SAAS,uBACP,QACA,WACwB;CACxB,MAAM,iBAAiB,OAAO,QAAQ,KAAK,UAAU,QAAQ,WAAW,KAAK,CAAC;CAC9E,IAAI,mBAAmB,KAAA,GACrB,OAAO;CAGT,OAAO;EACL,GAAG;EACH,QAAQ;CACV;AACF;AAEA,SAAS,2BACP,QACA,QACM;CACN,IAAI,WAAW,KAAA,KAAa,WAAW,KAAA,GACrC;CAGF,IAAI;CACJ,IAAI;EACF,uBAAuB,wBAAwB,MAAM;CACvD,SAAS,OAAO;EACd,gBAAgB,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;CAC3F;CAEA,MAAM,eAAe,IAAI,IAAI,CAAC,qBAAqB,UAAU,qBAAqB,OAAO,CAAC;CAE1F,KAAK,MAAM,SAAS,QAClB,IAAI,aAAa,IAAI,KAAK,GACxB,gBACE,4BACA,oGACF;AAGN;AAEA,SAAgB,eAAe,QAA0B,WAAqC;CAC5F,IAAI,CAAC,OAAO,UACV,OAAO;CAET,MAAM,WAAW,wBAAwB,OAAO,QAAQ;CACxD,MAAM,SAAS,uBAAuB,SAAS,QAAQ,SAAS;CAChE,MAAM,SAAS,QAAQ,WAAW,SAAS,MAAM;CAEjD,2BAA2B,OAAO,QAAQ,MAAM;CAEhD,OAAO;EACL,GAAG;EACH,UAAU;GACR,GAAG;GACH;GACA;EACF;CACF;AACF;;;AC7DA,eAAe,oBAAoB,YAAgD;CACjF,MAAM,MAAM,QAAQ,IAAI;CACxB,MAAM,qBAAqB,aAAa,QAAQ,KAAK,UAAU,IAAI,KAAA;CACnE,MAAM,YAAY,qBAAqB,QAAQ,kBAAkB,IAAI;CAErE,MAAM,SAAS,MAAMA,WAAgC;EACnD,MAAM;EACN,GAAG,UAAU,cAAc,kBAAkB;EAC7C,KAAK;CACP,CAAC;CAID,IAAI,sBAAsB,OAAO,eAAe,oBAC9C,MAAM,wBAAwB,kBAAkB;CAIlD,IAAI,CAAC,OAAO,UAAU,OAAO,KAAK,OAAO,MAAM,CAAC,CAAC,WAAW,GAG1D,MAAM,wBADc,OAAO,cAAc,sBAAsB,UACtB;CAI3C,eAAe,OAAO,MAAM;CAE5B,MAAM,kBAAkB,OAAO,aAAa,QAAQ,OAAO,UAAU,IAAI;CACzE,OAAO,eAAe,OAAO,QAAQ,eAAe;AACtD;;;;;;;;;;AAWA,eAAsBC,aAAW,YAAgD;CAC/E,IAAI;EACF,OAAO,MAAM,oBAAoB,UAAU;CAC7C,SAAS,OAAO;EACd,IAAI,iBAAiB,uBACnB,MAAM,sBAAsB,MAAM,OAAO,EACvC,KAAK,MAAM,IACb,CAAC;EAIH,IACE,iBAAiB,SACjB,UAAU,SACV,OAAQ,MAA2B,SAAS,UAE5C,MAAM;EAGR,IAAI,iBAAiB,OAAO;GAE1B,IACE,MAAM,QAAQ,SAAS,WAAW,KAClC,MAAM,QAAQ,SAAS,aAAa,KACpC,MAAM,QAAQ,SAAS,QAAQ,GAI/B,MAAM,wBADc,aAAa,QAAQ,QAAQ,IAAI,GAAG,UAAU,IAAI,KAAA,GAC3B,EACzC,KAAK,MAAM,QACb,CAAC;GAGH,MAAM,gBAAgB,MAAM,SAAS,EACnC,KAAK,0BAA0B,MAAM,UACvC,CAAC;EACH;EACA,MAAM,gBAAgB,OAAO,KAAK,CAAC;CACrC;AACF"}
|
package/dist/config-loader.d.mts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { PrismaNextConfig } from "@prisma-next/config/config-types";
|
|
2
|
-
|
|
3
|
-
//#region src/config-loader.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Loads the Prisma Next config from a TypeScript file.
|
|
6
|
-
* Supports both default export and named export.
|
|
7
|
-
* Uses c12 to automatically handle TypeScript compilation and config file discovery.
|
|
8
|
-
*
|
|
9
|
-
* @param configPath - Optional path to config file. Defaults to `./prisma-next.config.ts` in current directory.
|
|
10
|
-
* @returns The loaded config object.
|
|
11
|
-
* @throws Error if config file doesn't exist or is invalid.
|
|
12
|
-
*/
|
|
13
|
-
declare function loadConfig(configPath?: string): Promise<PrismaNextConfig>;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { loadConfig };
|
|
16
|
-
//# sourceMappingURL=config-loader.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.mts","names":[],"sources":["../src/config-loader.ts"],"mappings":";;;;;AAoDA;;;;;;;iBAAsB,UAAA,CAAW,UAAA,YAAsB,OAAO,CAAC,gBAAA"}
|
package/dist/config-loader.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract-emit-B_qriF8B.mjs","names":["CliStructuredError","errorUnexpected"],"sources":["../src/utils/formatters/emit.ts","../src/commands/contract-emit.ts"],"sourcesContent":["import { ifDefined } from '@prisma-next/utils/defined';\nimport { relative } from 'pathe';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { isVerbose } from './helpers';\n\n// EmitContractResult type for CLI output formatting (includes file paths)\nexport interface EmitContractResult {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n readonly outDir: string;\n readonly files: {\n readonly json: string;\n readonly dts: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for contract emit.\n */\nexport function formatEmitOutput(result: EmitContractResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n // Convert absolute paths to relative paths from cwd\n const jsonPath = relative(process.cwd(), result.files.json);\n const dtsPath = relative(process.cwd(), result.files.dts);\n\n lines.push(`✔ Emitted contract.json → ${jsonPath}`);\n lines.push(`✔ Emitted contract.d.ts → ${dtsPath}`);\n lines.push(` storageHash: ${result.storageHash}`);\n if (result.executionHash) {\n lines.push(` executionHash: ${result.executionHash}`);\n }\n if (result.profileHash) {\n lines.push(` profileHash: ${result.profileHash}`);\n }\n if (isVerbose(flags, 1)) {\n lines.push(` Total time: ${result.timings.total}ms`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for contract emit.\n */\nexport function formatEmitJson(result: EmitContractResult): string {\n const output = {\n ok: true,\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n ...(result.profileHash ? { profileHash: result.profileHash } : {}),\n outDir: result.outDir,\n files: result.files,\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n","import { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { executeContractEmit } from '../control-api/operations/contract-emit';\nimport type { ContractEmitResult } from '../control-api/types';\nimport { CliStructuredError, errorUnexpected } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport {\n type EmitContractResult,\n formatEmitJson,\n formatEmitOutput,\n} from '../utils/formatters/emit';\nimport { formatStyledHeader, formatSuccessMessage } from '../utils/formatters/styled';\nimport type { CommonCommandOptions } from '../utils/global-flags';\nimport { type GlobalFlags, parseGlobalFlagsOrExit } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { createTerminalUI, type TerminalUI } from '../utils/terminal-ui';\n\ninterface ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n readonly outputPath?: string;\n}\n\ninterface HeaderPaths {\n readonly displayConfigPath: string;\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n}\n\n/**\n * Pre-load the config just to compute display paths for the styled header. The\n * actual emit work goes through `executeContractEmit`, which loads the config\n * itself; the redundant load here is bounded and lets the header render before\n * the emit spans start.\n */\nasync function resolveHeaderPaths(\n configOption: string | undefined,\n outputPath: string | undefined,\n): Promise<Result<HeaderPaths, CliStructuredError>> {\n const displayConfigPath = configOption\n ? relative(process.cwd(), resolve(configOption))\n : 'prisma-next.config.ts';\n\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(configOption);\n } catch (error) {\n if (error instanceof CliStructuredError) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: 'Failed to load config',\n }),\n );\n }\n\n const effectiveJsonPath =\n outputPath !== undefined ? join(outputPath, 'contract.json') : config.contract?.output;\n\n if (!effectiveJsonPath) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract.output is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n try {\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } =\n getEmittedArtifactPaths(effectiveJsonPath);\n return ok({ displayConfigPath, outputJsonPath, outputDtsPath });\n } catch (error) {\n return notOk(\n errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n}\n\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n const outputPath = options.outputPath !== undefined ? resolve(options.outputPath) : undefined;\n\n const headerPathsResult = await resolveHeaderPaths(options.config, outputPath);\n if (!headerPathsResult.ok) {\n return headerPathsResult;\n }\n const { displayConfigPath, outputJsonPath, outputDtsPath } = headerPathsResult.value;\n\n if (!flags.json && !flags.quiet) {\n ui.stderr(\n formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: displayConfigPath },\n { label: 'contract', value: relative(process.cwd(), outputJsonPath) },\n { label: 'types', value: relative(process.cwd(), outputDtsPath) },\n ],\n flags,\n }),\n );\n }\n\n const onProgress = createProgressAdapter({ ui, flags });\n const configPath = options.config ? resolve(options.config) : 'prisma-next.config.ts';\n\n let result: ContractEmitResult;\n try {\n result = await executeContractEmit({\n configPath,\n onProgress,\n ...ifDefined('outputPath', outputPath),\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n\n if (result.validationWarning) {\n ui.warn(result.validationWarning);\n }\n\n return ok({\n storageHash: result.storageHash,\n ...ifDefined('executionHash', result.executionHash),\n profileHash: result.profileHash,\n outDir: dirname(result.files.json),\n files: result.files,\n timings: { total: Date.now() - startTime },\n });\n}\n\nexport function createContractEmitCommand(): Command {\n const command = new Command('emit');\n setCommandDescriptions(\n command,\n 'Emit your contract artifacts',\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 setCommandExamples(command, [\n 'prisma-next contract emit',\n 'prisma-next contract emit --config ./custom-config.ts',\n 'prisma-next contract emit --output-path ./generated',\n ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--output-path <dir>', 'Directory to write contract.json and contract.d.ts into')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlagsOrExit(options);\n const ui = createTerminalUI(flags);\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n const exitCode = handleResult(result, flags, ui, (emitResult) => {\n if (flags.json) {\n ui.output(formatEmitJson(emitResult));\n } else {\n const output = formatEmitOutput(emitResult, flags);\n if (output) {\n ui.log(output);\n }\n if (!flags.quiet) {\n ui.success(formatSuccessMessage(flags));\n }\n }\n });\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract-emit-C8HmtboH.mjs","names":["isRecord"],"sources":["../src/utils/emit-queue.ts","../src/utils/publish-contract-artifact-pair.ts","../src/utils/validate-contract-deps.ts","../src/control-api/operations/contract-emit.ts"],"sourcesContent":["/**\n * Per-output FIFO queue for `executeContractEmit`.\n *\n * Ensures that at most one emit (load → resolve source → emit bytes → publish)\n * runs per output JSON path at a time. Concurrent calls for the same path\n * line up behind the in-flight one and run in submission order; the user-visible\n * outcome is \"last submission wins on disk\" without any supersession bookkeeping.\n *\n * Long-lived hosts (Vite dev server, watch CLIs) must call `disposeEmitQueue`\n * when they stop publishing to a path, otherwise the module-global `Map`\n * accumulates one entry per unique output path for the lifetime of the process.\n */\nconst emitQueues = new Map<string, Promise<unknown>>();\n\nexport function queueEmitByOutput<T>(outputJsonPath: string, action: () => Promise<T>): Promise<T> {\n const previous = emitQueues.get(outputJsonPath) ?? Promise.resolve();\n // Continue regardless of the previous task's outcome — a failed emit must not\n // block subsequent ones. The current task's outcome propagates via `next`.\n const next = previous.then(action, action);\n emitQueues.set(outputJsonPath, next);\n return next;\n}\n\nexport function disposeEmitQueue(outputJsonPath: string): void {\n emitQueues.delete(outputJsonPath);\n}\n","import { readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'pathe';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction createTempArtifactPath(path: string, publicationToken: string, phase: string): string {\n return join(dirname(path), `.${basename(path)}.${process.pid}.${publicationToken}.${phase}.tmp`);\n}\n\ntype PreviousArtifact = { readonly content: string } | 'remove';\n\nasync function readExistingArtifact(path: string): Promise<PreviousArtifact> {\n try {\n return { content: await readFile(path, 'utf-8') };\n } catch (error) {\n if (isRecord(error) && error['code'] === 'ENOENT') {\n return 'remove';\n }\n throw error;\n }\n}\n\nasync function restoreArtifact(\n path: string,\n previous: PreviousArtifact,\n publicationToken: string,\n): Promise<void> {\n if (previous === 'remove') {\n await rm(path, { force: true });\n return;\n }\n\n const restorePath = createTempArtifactPath(path, publicationToken, 'rollback');\n await writeFile(restorePath, previous.content, 'utf-8');\n try {\n await rename(restorePath, path);\n } finally {\n await rm(restorePath, { force: true });\n }\n}\n\ninterface PublishEntry {\n readonly tempPath: string;\n readonly outputPath: string;\n readonly previous: PreviousArtifact;\n}\n\nfunction withRollbackFailureCause(error: unknown, rollbackFailures: readonly unknown[]): Error {\n const rollbackCause = new AggregateError(\n rollbackFailures,\n 'Failed to restore published artifacts',\n );\n\n if (error instanceof Error) {\n Object.defineProperty(error, 'cause', {\n value: rollbackCause,\n configurable: true,\n writable: true,\n });\n return error;\n }\n\n return new Error(String(error), { cause: rollbackCause });\n}\n\nasync function publishPairWithRollback(\n entries: readonly PublishEntry[],\n publicationToken: string,\n): Promise<void> {\n const replaced: PublishEntry[] = [];\n try {\n for (const entry of entries) {\n await rename(entry.tempPath, entry.outputPath);\n replaced.push(entry);\n }\n } catch (error) {\n const rollbackResults = await Promise.allSettled(\n replaced.map((entry) => restoreArtifact(entry.outputPath, entry.previous, publicationToken)),\n );\n const rollbackFailures = rollbackResults.flatMap((result) =>\n result.status === 'rejected' ? [result.reason] : [],\n );\n\n if (rollbackFailures.length > 0) {\n throw withRollbackFailureCause(error, rollbackFailures);\n }\n\n throw error;\n }\n}\n\nexport async function publishContractArtifactPair({\n outputJsonPath,\n outputDtsPath,\n contractJson,\n contractDts,\n publicationToken,\n beforePublish,\n}: {\n readonly outputJsonPath: string;\n readonly outputDtsPath: string;\n readonly contractJson: string;\n readonly contractDts: string;\n readonly publicationToken: string;\n readonly beforePublish?: () => Promise<boolean> | boolean;\n}): Promise<boolean> {\n const tempJsonPath = createTempArtifactPath(outputJsonPath, publicationToken, 'next');\n const tempDtsPath = createTempArtifactPath(outputDtsPath, publicationToken, 'next');\n\n try {\n await writeFile(tempJsonPath, contractJson, 'utf-8');\n await writeFile(tempDtsPath, contractDts, 'utf-8');\n\n if ((await beforePublish?.()) === false) {\n return false;\n }\n\n const previousJson = await readExistingArtifact(outputJsonPath);\n const previousDts = await readExistingArtifact(outputDtsPath);\n\n await publishPairWithRollback(\n [\n { tempPath: tempDtsPath, outputPath: outputDtsPath, previous: previousDts },\n { tempPath: tempJsonPath, outputPath: outputJsonPath, previous: previousJson },\n ],\n publicationToken,\n );\n return true;\n } finally {\n await Promise.allSettled([rm(tempJsonPath, { force: true }), rm(tempDtsPath, { force: true })]);\n }\n}\n","import { createRequire } from 'node:module';\n\nconst IMPORT_PATTERN = /import\\s+type\\s+.*?\\s+from\\s+['\"](@[^/]+\\/[^/'\"]+)/g;\n\nexport function extractPackageSpecifiers(dtsContent: string): string[] {\n const packages = new Set<string>();\n for (const match of dtsContent.matchAll(IMPORT_PATTERN)) {\n const pkg = match[1];\n if (pkg) packages.add(pkg);\n }\n return [...packages];\n}\n\nexport interface ContractDepsValidation {\n readonly missing: readonly string[];\n readonly warning?: string;\n}\n\nexport function validateContractDeps(\n dtsContent: string,\n projectRoot: string,\n): ContractDepsValidation {\n const packages = extractPackageSpecifiers(dtsContent);\n const resolve = createRequire(`${projectRoot}/package.json`);\n\n const missing: string[] = [];\n for (const pkg of packages) {\n try {\n resolve.resolve(`${pkg}/package.json`);\n } catch {\n missing.push(pkg);\n }\n }\n\n if (missing.length === 0) {\n return { missing };\n }\n\n const list = missing.map((p) => ` - ${p}`).join('\\n');\n const warning = [\n 'contract.d.ts imports types from packages that are not installed:',\n list,\n '',\n 'Install them with your package manager:',\n ...missing.map((p) => ` ${p}`),\n ].join('\\n');\n\n return { missing, warning };\n}\n","import { mkdir } from 'node:fs/promises';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { emit, getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { createControlStack } from '@prisma-next/framework-components/control';\nimport { abortable } from '@prisma-next/utils/abortable';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { dirname, join } from 'pathe';\nimport { loadConfig } from '../../config-loader';\nimport { errorContractConfigMissing, errorRuntime } from '../../utils/cli-errors';\nimport { queueEmitByOutput } from '../../utils/emit-queue';\nimport { toExtensionInputs } from '../../utils/extension-pack-inputs';\nimport { assertFrameworkComponentsCompatible } from '../../utils/framework-components';\nimport { publishContractArtifactPair } from '../../utils/publish-contract-artifact-pair';\nimport { validateContractDeps } from '../../utils/validate-contract-deps';\nimport { enrichContract } from '../contract-enrichment';\nimport type {\n ContractEmitOptions,\n ContractEmitResult,\n ControlActionName,\n OnControlProgress,\n} from '../types';\n\nconst EMIT_ACTION: ControlActionName = 'emit';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction startSpan(onProgress: OnControlProgress | undefined, spanId: string, label: string): void {\n onProgress?.({ action: EMIT_ACTION, kind: 'spanStart', spanId, label });\n}\n\nfunction endSpan(\n onProgress: OnControlProgress | undefined,\n spanId: string,\n outcome: 'ok' | 'error',\n): void {\n onProgress?.({ action: EMIT_ACTION, kind: 'spanEnd', spanId, outcome });\n}\n\nfunction failedToResolveContractSource(why: string, fix: string, meta?: Record<string, unknown>) {\n return errorRuntime('Failed to resolve contract source', {\n why,\n fix,\n ...ifDefined('meta', meta),\n });\n}\n\ntype ValidatedProviderResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly error: ReturnType<typeof errorRuntime> };\n\nfunction diagnosticLocationSuffix(diagnostic: Record<string, unknown>): string {\n const sourceId = typeof diagnostic['sourceId'] === 'string' ? diagnostic['sourceId'] : undefined;\n const span = isRecord(diagnostic['span']) ? diagnostic['span'] : undefined;\n const start = span && isRecord(span['start']) ? span['start'] : undefined;\n const line = start && typeof start['line'] === 'number' ? start['line'] : undefined;\n const column = start && typeof start['column'] === 'number' ? start['column'] : undefined;\n if (sourceId && line !== undefined && column !== undefined) {\n return ` (${sourceId}:${line}:${column})`;\n }\n if (sourceId) {\n return ` (${sourceId})`;\n }\n return '';\n}\n\nfunction mapDiagnosticsToIssues(\n diagnostics: readonly unknown[],\n): ReadonlyArray<{ readonly kind: string; readonly message: string }> {\n const issues: { readonly kind: string; readonly message: string }[] = [];\n for (const raw of diagnostics) {\n if (!isRecord(raw)) continue;\n const code = typeof raw['code'] === 'string' ? raw['code'] : 'diagnostic';\n const message = typeof raw['message'] === 'string' ? raw['message'] : '';\n issues.push({ kind: code, message: `${message}${diagnosticLocationSuffix(raw)}` });\n }\n return issues;\n}\n\nfunction validateProviderResult(providerResult: unknown): ValidatedProviderResult {\n if (!isRecord(providerResult) || typeof providerResult['ok'] !== 'boolean') {\n return {\n ok: false,\n error: failedToResolveContractSource(\n 'Contract source provider returned malformed result shape.',\n 'Ensure contract.source.load resolves to ok(Contract) or notOk({ summary, diagnostics }).',\n ),\n };\n }\n\n if (providerResult['ok']) {\n if (!('value' in providerResult)) {\n return {\n ok: false,\n error: failedToResolveContractSource(\n 'Contract source provider returned malformed success result: missing value.',\n 'Ensure contract.source.load success payload is ok(Contract).',\n ),\n };\n }\n return { ok: true, value: providerResult['value'] };\n }\n\n const failure = providerResult['failure'];\n if (\n !isRecord(failure) ||\n typeof failure['summary'] !== 'string' ||\n !Array.isArray(failure['diagnostics'])\n ) {\n return {\n ok: false,\n error: failedToResolveContractSource(\n 'Contract source provider returned malformed failure result: expected summary and diagnostics.',\n 'Ensure contract.source.load failure payload is notOk({ summary, diagnostics, meta? }).',\n ),\n };\n }\n return {\n ok: false,\n error: failedToResolveContractSource(\n String(failure['summary']),\n 'Fix contract source diagnostics and return ok(Contract).',\n {\n diagnostics: failure['diagnostics'],\n issues: mapDiagnosticsToIssues(failure['diagnostics']),\n ...ifDefined('providerMeta', failure['meta']),\n },\n ),\n };\n}\n\n/**\n * Canonical contract emit operation.\n *\n * This is the SINGLE publication path used by both the CLI command\n * (`prisma-next contract emit`) and the Vite plugin\n * (`@prisma-next/vite-plugin-contract-emit`). New callers must go through this\n * function rather than re-implementing load → emit → publish.\n *\n * The whole flow (load config → resolve source → emit bytes → atomic publish)\n * is serialized per output JSON path via `queueEmitByOutput`. Concurrent calls\n * for the same output line up FIFO; the user-visible outcome is \"last\n * submission wins on disk\" without any supersession bookkeeping. Within a\n * single emit, `publishContractArtifactPair` stages temp files, renames\n * `contract.d.ts` before `contract.json`, and attempts to restore the previous\n * pair if either rename fails — so type-only consumers never observe a\n * mismatched pair.\n *\n * @throws {CliStructuredError} on config/source/validation problems\n * @throws {DOMException} `AbortError` if cancelled via `signal`\n */\nexport async function executeContractEmit(\n options: ContractEmitOptions,\n): Promise<ContractEmitResult> {\n const { configPath, outputPath, signal = new AbortController().signal, onProgress } = options;\n const unlessAborted = abortable(signal);\n\n const config = await unlessAborted(loadConfig(configPath));\n\n if (!config.contract) {\n throw errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n });\n }\n\n const contractConfig = config.contract;\n\n const effectiveOutput =\n outputPath !== undefined ? join(outputPath, 'contract.json') : contractConfig.output;\n\n if (!effectiveOutput) {\n throw errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n });\n }\n\n if (typeof contractConfig.source?.load !== 'function') {\n throw errorContractConfigMissing({\n why: 'Contract config must include a valid source provider object',\n });\n }\n\n let outputPaths: ReturnType<typeof getEmittedArtifactPaths>;\n try {\n outputPaths = getEmittedArtifactPaths(effectiveOutput);\n } catch (error) {\n throw errorContractConfigMissing({\n why: error instanceof Error ? error.message : String(error),\n });\n }\n const { jsonPath: outputJsonPath, dtsPath: outputDtsPath } = outputPaths;\n\n return queueEmitByOutput(outputJsonPath, async () => {\n const stack = createControlStack(config);\n\n const extensionInputs = toExtensionInputs(\n blindCast<\n readonly unknown[],\n 'toExtensionInputs accepts readonly unknown[] per its documented structural cast boundary'\n >(stack.extensionPacks),\n );\n const composedExtensionContracts = new Map<string, Contract>(\n extensionInputs\n .filter((p) => p.contractSpace !== undefined)\n .map((p) => [\n p.id,\n blindCast<\n Contract,\n 'contractSpace.contractJson is the typed contract for this extension space'\n >(p.contractSpace!.contractJson),\n ]),\n );\n const sourceContext = {\n composedExtensionPacks: stack.extensionPacks.map((p) => p.id),\n composedExtensionContracts,\n scalarTypeDescriptors: stack.scalarTypeDescriptors,\n authoringContributions: stack.authoringContributions,\n codecLookup: stack.codecLookup,\n controlMutationDefaults: stack.controlMutationDefaults,\n resolvedInputs: contractConfig.source.inputs ?? [],\n };\n\n startSpan(onProgress, 'resolveSource', 'Resolving contract source...');\n let providerResult: Awaited<ReturnType<typeof contractConfig.source.load>>;\n try {\n providerResult = await unlessAborted(contractConfig.source.load(sourceContext));\n } catch (error) {\n endSpan(onProgress, 'resolveSource', 'error');\n if (signal.aborted || (isRecord(error) && error['name'] === 'AbortError')) {\n throw error;\n }\n throw failedToResolveContractSource(\n error instanceof Error ? error.message : String(error),\n 'Ensure contract.source.load resolves to ok(Contract) or returns structured diagnostics.',\n );\n }\n\n const validatedContract = validateProviderResult(providerResult);\n if (!validatedContract.ok) {\n endSpan(onProgress, 'resolveSource', 'error');\n throw validatedContract.error;\n }\n endSpan(onProgress, 'resolveSource', 'ok');\n\n startSpan(onProgress, 'emit', 'Emitting contract...');\n let emitResult: Awaited<ReturnType<typeof emit>>;\n try {\n const familyInstance = config.family.create(stack);\n const rawComponents = [config.target, config.adapter, ...(config.extensionPacks ?? [])];\n const frameworkComponents = assertFrameworkComponentsCompatible(\n config.family.familyId,\n config.target.targetId,\n rawComponents,\n );\n // Blind cast: `validateProviderResult` upstream has already\n // pinned `validatedContract.value` to the provider's loose\n // `Contract` envelope, but the local `Contract` type at this\n // call site is the precise structural interface. Re-narrowing\n // the envelope into the precise type is exactly what the\n // `familyInstance.deserializeContract(enrichedIR)` call on the\n // next line does — the cast just defers the structural check\n // by one statement so `enrichContract` can decorate first.\n const enrichedIR = enrichContract(\n validatedContract.value as unknown as Contract,\n frameworkComponents,\n );\n const deserializedContract = familyInstance.deserializeContract(enrichedIR);\n // Each target's descriptor ships a `contractSerializer` SPI; the\n // framework canonicalizer threads its `serializeContract` so the\n // on-disk JSON envelope is constructed by target-owned code\n // rather than by walking the in-memory contract with\n // `Object.entries` (which would leak runtime-only class API\n // fields into the persisted shape). The optional `shouldPreserveEmpty`\n // and `sortStorage` hooks let the family contribute storage-specific\n // canonicalization rules without the framework importing family code.\n const { contractSerializer } = config.target;\n const serializeContract = (c: Contract): JsonObject =>\n contractSerializer.serializeContract(c);\n emitResult = await unlessAborted(\n emit(deserializedContract, stack, config.family.emission, {\n outputJsonPath,\n serializeContract,\n ...ifDefined('shouldPreserveEmpty', contractSerializer.shouldPreserveEmpty),\n ...ifDefined('sortStorage', contractSerializer.sortStorage),\n }),\n );\n } catch (error) {\n endSpan(onProgress, 'emit', 'error');\n throw error;\n }\n endSpan(onProgress, 'emit', 'ok');\n\n await unlessAborted(mkdir(dirname(outputJsonPath), { recursive: true }));\n await publishContractArtifactPair({\n outputJsonPath,\n outputDtsPath,\n contractJson: emitResult.contractJson,\n contractDts: emitResult.contractDts,\n publicationToken: String(process.hrtime.bigint()),\n });\n\n const validationWarning = validateContractDeps(\n emitResult.contractDts,\n dirname(outputDtsPath),\n ).warning;\n\n return {\n storageHash: emitResult.storageHash,\n ...ifDefined('executionHash', emitResult.executionHash),\n profileHash: emitResult.profileHash,\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n ...ifDefined('validationWarning', validationWarning),\n };\n });\n}\n"],"mappings":"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"}
|