@prisma-next/cli 0.14.0-dev.2 → 0.14.0-dev.20
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-Dm_Efs9g.mjs} +5 -4
- package/dist/client-Dm_Efs9g.mjs.map +1 -0
- 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-BMaib2U-.mjs} +3 -3
- package/dist/{contract-infer-BYT_ra_U.mjs.map → contract-infer-BMaib2U-.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-PPxMkghu.mjs} +8 -5
- package/dist/db-verify-PPxMkghu.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-BmgdUJcj.mjs} +4 -4
- package/dist/inspect-live-schema-BmgdUJcj.mjs.map +1 -0
- package/dist/{migration-check-soB5uZEQ.mjs → migration-check-DWX4qdOB.mjs} +6 -5
- package/dist/migration-check-DWX4qdOB.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-Dv0tKmIJ.mjs} +4 -4
- package/dist/migration-command-scaffold-Dv0tKmIJ.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-BlkNEV6F.mjs} +4 -4
- package/dist/migration-log-BlkNEV6F.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-DCmV7fWX.mjs} +7 -6
- package/dist/migration-status-DCmV7fWX.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-CLw3YRbl.mjs} +7 -2
- package/dist/{verify-DcOYZ1tH.mjs.map → verify-CLw3YRbl.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 +32 -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/db-verify.ts +1 -0
- 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/combine-schema-results.ts +3 -0
- package/src/utils/formatters/verify.ts +8 -0
- package/src/utils/migration-command-scaffold.ts +1 -1
- package/dist/client-CJzuo5wX.mjs.map +0 -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,32 @@
|
|
|
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
|
+
'and handles whole-document PSL formatting for the schema inputs declared in\n' +
|
|
15
|
+
'your config (contract.source.inputs). Formatting uses the Prisma Next PSL\n' +
|
|
16
|
+
'formatter and the formatter block from the project config.\n' +
|
|
17
|
+
'Communicates over stdio; intended to be spawned by an\n' +
|
|
18
|
+
'editor, not run interactively. The server keeps running until the editor client\n' +
|
|
19
|
+
'disconnects.',
|
|
20
|
+
);
|
|
21
|
+
setCommandExamples(command, ['prisma-next lsp --stdio']);
|
|
22
|
+
addGlobalOptions(command)
|
|
23
|
+
.option('--stdio', 'Communicate with the editor over stdio (the default and only transport)')
|
|
24
|
+
.action(async () => {
|
|
25
|
+
// Lazy import so `vscode-languageserver` stays off every other command's
|
|
26
|
+
// startup path — only `prisma-next lsp` pays its load cost.
|
|
27
|
+
const { startServer } = await import('@prisma-next/language-server');
|
|
28
|
+
startServer();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return command;
|
|
32
|
+
}
|
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
|
|
@@ -30,6 +30,7 @@ export function combineSchemaResults(
|
|
|
30
30
|
let okAll = true;
|
|
31
31
|
let firstFailure: VerifyDatabaseSchemaResult | undefined;
|
|
32
32
|
let issues: VerifyDatabaseSchemaResult['schema']['issues'] = [];
|
|
33
|
+
let schemaDiffIssues: VerifyDatabaseSchemaResult['schema']['schemaDiffIssues'] = [];
|
|
33
34
|
const counts = { pass: 0, warn: 0, fail: 0, totalNodes: 0 };
|
|
34
35
|
const childRoots: Array<VerifyDatabaseSchemaResult['schema']['root']> = [];
|
|
35
36
|
for (const [, result] of perSpace) {
|
|
@@ -38,6 +39,7 @@ export function combineSchemaResults(
|
|
|
38
39
|
if (firstFailure === undefined) firstFailure = result;
|
|
39
40
|
}
|
|
40
41
|
issues = [...issues, ...result.schema.issues];
|
|
42
|
+
schemaDiffIssues = [...schemaDiffIssues, ...result.schema.schemaDiffIssues];
|
|
41
43
|
counts.pass += result.schema.counts.pass;
|
|
42
44
|
counts.warn += result.schema.counts.warn;
|
|
43
45
|
counts.fail += result.schema.counts.fail;
|
|
@@ -65,6 +67,7 @@ export function combineSchemaResults(
|
|
|
65
67
|
target: appResult.target,
|
|
66
68
|
schema: {
|
|
67
69
|
issues,
|
|
70
|
+
schemaDiffIssues,
|
|
68
71
|
root: {
|
|
69
72
|
status: okAll ? 'pass' : 'fail',
|
|
70
73
|
kind: 'aggregate',
|
|
@@ -539,6 +539,14 @@ export function formatSchemaVerifyOutput(
|
|
|
539
539
|
});
|
|
540
540
|
lines.push(...treeLines);
|
|
541
541
|
|
|
542
|
+
if (result.schema.schemaDiffIssues.length > 0) {
|
|
543
|
+
lines.push('');
|
|
544
|
+
lines.push(formatRed('Schema drift:'));
|
|
545
|
+
for (const issue of result.schema.schemaDiffIssues) {
|
|
546
|
+
lines.push(` ${formatRed('✖')} ${issue.message}`);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
542
550
|
// Add counts and timings in verbose mode
|
|
543
551
|
if (isVerbose(flags, 1)) {
|
|
544
552
|
lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);
|
|
@@ -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 {
|