@prisma-next/cli 0.14.0 → 0.15.0-dev.10
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 +33 -14
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-CJzuo5wX.mjs → client-DwOyZz0a.mjs} +141 -123
- package/dist/client-DwOyZz0a.mjs.map +1 -0
- package/dist/{command-helpers-DGMvGBeX.mjs → command-helpers-CNwURRf9.mjs} +30 -11
- package/dist/command-helpers-CNwURRf9.mjs.map +1 -0
- 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.d.mts.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.d.mts.map +1 -1
- package/dist/commands/migrate.mjs +37 -38
- 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 +9 -9
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.d.mts +6 -6
- package/dist/commands/migration-list.d.mts.map +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.d.mts.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-BHbY04pl.mjs} +2 -2
- package/dist/{contract-at-errors-CFXsstzm.mjs.map → contract-at-errors-BHbY04pl.mjs.map} +1 -1
- package/dist/{contract-emit-C8HmtboH.mjs → contract-emit-BeidkyUC.mjs} +9 -11
- package/dist/contract-emit-BeidkyUC.mjs.map +1 -0
- package/dist/{contract-emit-B_qriF8B.mjs → contract-emit-IQBYv351.mjs} +6 -6
- package/dist/contract-emit-IQBYv351.mjs.map +1 -0
- package/dist/{contract-infer-BYT_ra_U.mjs → contract-infer-B3Wq2cu1.mjs} +3 -3
- package/dist/{contract-infer-BYT_ra_U.mjs.map → contract-infer-B3Wq2cu1.mjs.map} +1 -1
- package/dist/{contract-space-aggregate-loader-ClI1KN6d.mjs → contract-space-aggregate-loader-BirzMmW1.mjs} +63 -5
- package/dist/contract-space-aggregate-loader-BirzMmW1.mjs.map +1 -0
- package/dist/{db-verify-C24FKhb7.mjs → db-verify-DpRrecs7.mjs} +57 -61
- package/dist/db-verify-DpRrecs7.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +3 -3
- package/dist/exports/control-api.d.mts.map +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-CaCF63ld.mjs +102 -0
- package/dist/format-CaCF63ld.mjs.map +1 -0
- package/dist/{framework-components-YVQHhPH7.mjs → framework-components-CnBcJDmF.mjs} +2 -2
- package/dist/{framework-components-YVQHhPH7.mjs.map → framework-components-CnBcJDmF.mjs.map} +1 -1
- package/dist/{init-0HwB-Vh8.mjs → init-Boa0LzeJ.mjs} +27 -19
- package/dist/init-Boa0LzeJ.mjs.map +1 -0
- package/dist/{inspect-live-schema-DF6IwcDl.mjs → inspect-live-schema-CldSQjVI.mjs} +4 -4
- package/dist/inspect-live-schema-CldSQjVI.mjs.map +1 -0
- package/dist/{migration-check-VwM8xCZV.mjs → migration-check-CGtYnR9k.mjs} +10 -11
- package/dist/migration-check-CGtYnR9k.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-B3m-MMAx.mjs} +4 -4
- package/dist/migration-command-scaffold-B3m-MMAx.mjs.map +1 -0
- package/dist/{migration-graph-command-render-CEez7YUK.mjs → migration-graph-command-render-B83xrnNy.mjs} +24 -24
- package/dist/{migration-graph-command-render-CEez7YUK.mjs.map → migration-graph-command-render-B83xrnNy.mjs.map} +1 -1
- package/dist/{migration-list-DlJJ_38Z.mjs → migration-list-DBU6Pneg.mjs} +16 -16
- package/dist/migration-list-DBU6Pneg.mjs.map +1 -0
- package/dist/{migration-log-CG0qQAFm.mjs → migration-log-BYngyvXa.mjs} +5 -5
- package/dist/migration-log-BYngyvXa.mjs.map +1 -0
- package/dist/{migration-path-target-Ce6OZImp.mjs → migration-path-target-DQa4Caoc.mjs} +2 -2
- package/dist/{migration-path-target-Ce6OZImp.mjs.map → migration-path-target-DQa4Caoc.mjs.map} +1 -1
- package/dist/{migration-plan-W_E8FQOk.mjs → migration-plan-D6bHpCzE.mjs} +30 -30
- package/dist/migration-plan-D6bHpCzE.mjs.map +1 -0
- package/dist/{migration-status-CD-LC2Ip.mjs → migration-status-CpQ5UhcU.mjs} +14 -14
- package/dist/migration-status-CpQ5UhcU.mjs.map +1 -0
- package/dist/{telemetry-BIM4beEO.mjs → telemetry-BQJ_XHa9.mjs} +2 -2
- package/dist/{telemetry-BIM4beEO.mjs.map → telemetry-BQJ_XHa9.mjs.map} +1 -1
- package/dist/{types-C_tYiJYx.d.mts → types-DFoqNIcQ.d.mts} +27 -21
- package/dist/types-DFoqNIcQ.d.mts.map +1 -0
- package/dist/{verify-DcOYZ1tH.mjs → verify-CInGyt4U.mjs} +58 -159
- package/dist/verify-CInGyt4U.mjs.map +1 -0
- package/package.json +28 -30
- 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 +34 -20
- 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 +47 -44
- package/src/commands/migration-check.ts +6 -6
- package/src/commands/migration-graph.ts +5 -5
- package/src/commands/migration-list.ts +13 -13
- package/src/commands/migration-log.ts +1 -1
- package/src/commands/migration-new.ts +1 -1
- package/src/commands/migration-plan.ts +15 -4
- package/src/commands/migration-show.ts +1 -1
- package/src/commands/migration-status.ts +10 -10
- package/src/commands/ref.ts +1 -1
- package/src/control-api/client.ts +8 -23
- package/src/control-api/operations/contract-emit.ts +9 -27
- package/src/control-api/operations/db-init.ts +2 -2
- package/src/control-api/operations/db-run.ts +18 -17
- package/src/control-api/operations/db-verify.ts +52 -44
- package/src/control-api/operations/format.ts +98 -0
- package/src/control-api/operations/migrate.ts +139 -95
- package/src/control-api/operations/run-migration.ts +6 -5
- package/src/control-api/types.ts +8 -8
- package/src/exports/index.ts +1 -0
- package/src/migration-cli.ts +1 -1
- package/src/utils/cli-errors.ts +14 -1
- package/src/utils/combine-verify-results.ts +94 -0
- package/src/utils/extension-pack-inputs.ts +1 -1
- package/src/utils/formatters/errors.ts +34 -5
- package/src/utils/formatters/verify.ts +89 -227
- package/src/utils/migration-command-scaffold.ts +1 -1
- package/src/utils/plan-resolution.ts +18 -18
- package/dist/client-CJzuo5wX.mjs.map +0 -1
- package/dist/command-helpers-DGMvGBeX.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/contract-space-aggregate-loader-ClI1KN6d.mjs.map +0 -1
- package/dist/db-verify-C24FKhb7.mjs.map +0 -1
- package/dist/extension-pack-inputs-1ySHqxKG.mjs +0 -62
- package/dist/extension-pack-inputs-1ySHqxKG.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-VwM8xCZV.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-CD-LC2Ip.mjs.map +0 -1
- package/dist/types-C_tYiJYx.d.mts.map +0 -1
- package/dist/verify-DcOYZ1tH.mjs.map +0 -1
- package/src/config-loader.ts +0 -92
- package/src/config-path-validation.ts +0 -74
- package/src/utils/combine-schema-results.ts +0 -84
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-CInGyt4U.mjs","names":[],"sources":["../src/utils/formatters/verify.ts"],"sourcesContent":["import type {\n CoreSchemaView,\n ExpectationFailureReason,\n IntrospectSchemaResult,\n SchemaDiffIssue,\n SchemaTreeNode,\n SignDatabaseResult,\n VerifyDatabaseResult,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { issueOutcome } from '@prisma-next/framework-components/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { bold, cyan, dim, green, magenta, red, yellow } from 'colorette';\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\n\n/** Human-readable label for each outcome, prefixed onto an issue's message for display. */\nconst OUTCOME_LABEL: Record<ExpectationFailureReason, string> = {\n 'not-found': 'missing',\n 'not-expected': 'extra',\n 'not-equal': 'mismatch',\n};\n\n/**\n * The issue's display text: its own path, prefixed with a human label for\n * why it's flagged. Turning the presence-derived outcome (and the path) into\n * prose is this formatter's job, not the differ's — the differ's issue is\n * data (`path` + nodes), not prose.\n */\nfunction formatIssueMessage(issue: SchemaDiffIssue): string {\n return `${OUTCOME_LABEL[issueOutcome(issue)]}: ${issue.path.join('/')}`;\n}\n\n// ============================================================================\n// Verify Output Formatters\n// ============================================================================\n\nexport interface DbVerifyCommandSuccessResult {\n readonly ok: true;\n readonly mode: 'full' | 'marker-only';\n readonly summary: string;\n readonly contract: VerifyDatabaseResult['contract'];\n readonly marker?: VerifyDatabaseResult['marker'];\n readonly target: VerifyDatabaseResult['target'];\n readonly missingCodecs?: VerifyDatabaseResult['missingCodecs'];\n readonly codecCoverageSkipped?: VerifyDatabaseResult['codecCoverageSkipped'];\n readonly schema?: {\n readonly summary: string;\n readonly strict: boolean;\n /**\n * Warn-graded finding messages (observed-policy drift). Informational —\n * present on a passing verify; the full-mode result summarizes them as a\n * flat message list.\n */\n readonly warnings?: readonly string[];\n };\n /**\n * Live element names no contract space declares. In full success this is\n * only ever non-empty in lenient mode — strict mode fails on it — and is\n * rendered informationally.\n */\n readonly unclaimed?: readonly string[];\n readonly warning?: string;\n readonly meta?:\n | (NonNullable<VerifyDatabaseResult['meta']> & {\n readonly schemaVerification: 'performed' | 'skipped';\n })\n | {\n readonly schemaVerification: 'performed' | 'skipped';\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\n/**\n * Formats human-readable output for database verify.\n */\nexport function formatVerifyOutput(\n result: DbVerifyCommandSuccessResult,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n const verificationMode =\n result.mode === 'full'\n ? `marker + schema${result.schema?.strict ? ' (strict)' : ' (tolerant)'}`\n : 'marker only (--marker-only)';\n\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n lines.push(`${formatDimText(` verification: ${verificationMode}`)}`);\n lines.push(`${formatDimText(` storageHash: ${result.contract.storageHash}`)}`);\n if (result.contract.profileHash) {\n lines.push(`${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.schema?.warnings && result.schema.warnings.length > 0) {\n lines.push('');\n lines.push(formatYellow('Schema warnings:'));\n for (const message of result.schema.warnings) {\n lines.push(` ${formatYellow('⚠')} ${message}`);\n }\n }\n\n if (result.unclaimed && result.unclaimed.length > 0) {\n lines.push('');\n lines.push(formatYellow('Unclaimed elements (declared by no contract):'));\n for (const name of result.unclaimed) {\n lines.push(` ${formatYellow('⚠')} ${name}`);\n }\n }\n\n if (result.warning) {\n lines.push('');\n lines.push(`${formatYellow('⚠')} ${result.warning}`);\n }\n\n if (isVerbose(flags, 1)) {\n if (result.codecCoverageSkipped) {\n lines.push(\n `${formatDimText(' Codec coverage check skipped (helper returned no supported types)')}`,\n );\n }\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database verify.\n */\nexport function formatVerifyJson(result: DbVerifyCommandSuccessResult): string {\n const output = {\n ok: result.ok,\n summary: result.summary,\n mode: result.mode,\n contract: result.contract,\n ...ifDefined('marker', result.marker),\n target: result.target,\n ...ifDefined('missingCodecs', result.missingCodecs),\n ...ifDefined('codecCoverageSkipped', result.codecCoverageSkipped),\n ...ifDefined('schema', result.schema),\n unclaimed: result.unclaimed ?? [],\n ...ifDefined('warning', result.warning),\n ...ifDefined('meta', result.meta),\n timings: result.timings,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Formats JSON output for database introspection.\n */\nexport function formatIntrospectJson(result: IntrospectSchemaResult<unknown>): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Renders a schema tree structure from CoreSchemaView.\n * Status-glyph tree styling shared with the retired verification-tree renderer.\n */\nfunction renderSchemaTree(\n node: SchemaTreeNode,\n flags: GlobalFlags,\n options: {\n readonly isLast: boolean;\n readonly prefix: string;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly isRoot?: boolean;\n },\n): string[] {\n const { isLast, prefix, useColor, formatDimText, isRoot = false } = options;\n const lines: string[] = [];\n\n // Format node label with color based on kind (matching schema-verify style)\n let formattedLabel: string = node.label;\n\n if (useColor) {\n switch (node.kind) {\n case 'root':\n formattedLabel = bold(node.label);\n break;\n case 'entity': {\n // Parse \"table tableName\" format - color \"table\" dim, tableName cyan\n const tableMatch = node.label.match(/^table\\s+(.+)$/);\n if (tableMatch?.[1]) {\n const tableName = tableMatch[1];\n formattedLabel = `${dim('table')} ${cyan(tableName)}`;\n } else {\n // Fallback: color entire label with cyan\n formattedLabel = cyan(node.label);\n }\n break;\n }\n case 'collection': {\n // \"columns\" grouping node - dim the label\n formattedLabel = dim(node.label);\n break;\n }\n case 'field': {\n // Parse column name format: \"columnName: typeDisplay (nullability)\"\n // Color code: column name (cyan), type (default), nullability (dim)\n const columnMatch = node.label.match(/^([^:]+):\\s*(.+)$/);\n if (columnMatch?.[1] && columnMatch[2]) {\n const columnName = columnMatch[1];\n const rest = columnMatch[2];\n // Parse rest: \"typeDisplay (nullability)\"\n const typeMatch = rest.match(/^([^\\s(]+)\\s*(\\([^)]+\\))$/);\n if (typeMatch?.[1] && typeMatch[2]) {\n const typeDisplay = typeMatch[1];\n const nullability = typeMatch[2];\n formattedLabel = `${cyan(columnName)}: ${typeDisplay} ${dim(nullability)}`;\n } else {\n // Fallback if format doesn't match\n formattedLabel = `${cyan(columnName)}: ${rest}`;\n }\n } else {\n formattedLabel = node.label;\n }\n break;\n }\n case 'index': {\n // Parse index/unique constraint/primary key formats\n // \"primary key: columnName\" -> dim \"primary key\", cyan columnName\n const pkMatch = node.label.match(/^primary key:\\s*(.+)$/);\n if (pkMatch?.[1]) {\n const columnNames = pkMatch[1];\n formattedLabel = `${dim('primary key')}: ${cyan(columnNames)}`;\n } else {\n // \"unique name\" -> dim \"unique\", cyan \"name\"\n const uniqueMatch = node.label.match(/^unique\\s+(.+)$/);\n if (uniqueMatch?.[1]) {\n const name = uniqueMatch[1];\n formattedLabel = `${dim('unique')} ${cyan(name)}`;\n } else {\n // \"index name\" or \"unique index name\" -> dim label prefix, cyan name\n const indexMatch = node.label.match(/^(unique\\s+)?index\\s+(.+)$/);\n if (indexMatch?.[2]) {\n const indexPrefix = indexMatch[1] ? `${dim('unique')} ` : '';\n const name = indexMatch[2];\n formattedLabel = `${indexPrefix}${dim('index')} ${cyan(name)}`;\n } else {\n formattedLabel = dim(node.label);\n }\n }\n }\n break;\n }\n case 'dependency': {\n // Parse extension message formats similar to schema-verify\n // \"extensionName extension is enabled\" -> cyan extensionName, dim rest\n const extMatch = node.label.match(/^([^\\s]+)\\s+(extension is enabled)$/);\n if (extMatch?.[1] && extMatch[2]) {\n const extName = extMatch[1];\n const rest = extMatch[2];\n formattedLabel = `${cyan(extName)} ${dim(rest)}`;\n } else {\n // Fallback: color entire label with magenta\n formattedLabel = magenta(node.label);\n }\n break;\n }\n default:\n formattedLabel = node.label;\n break;\n }\n }\n\n // Root node renders without tree characters or prefix\n if (isRoot) {\n lines.push(formattedLabel);\n } else {\n const treeChar = isLast ? '└' : '├';\n const treePrefix = `${formatDimText(treeChar)}─ `;\n lines.push(`${prefix}${treePrefix}${formattedLabel}`);\n }\n\n // Render children if present\n if (node.children && node.children.length > 0) {\n const childPrefix = isRoot ? '' : `${prefix}${isLast ? ' ' : `${formatDimText('│')} `}`;\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (!child) continue;\n const isLastChild = i === node.children.length - 1;\n const childLines = renderSchemaTree(child, flags, {\n isLast: isLastChild,\n prefix: childPrefix,\n useColor,\n formatDimText,\n isRoot: false,\n });\n lines.push(...childLines);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats human-readable output for database introspection.\n */\nexport function formatIntrospectOutput(\n result: IntrospectSchemaResult<unknown>,\n schemaView: CoreSchemaView | undefined,\n flags: GlobalFlags,\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (schemaView) {\n // Render tree structure - root node is special (no tree characters)\n const treeLines = renderSchemaTree(schemaView.root, flags, {\n isLast: true,\n prefix: '',\n useColor,\n formatDimText,\n isRoot: true,\n });\n lines.push(...treeLines);\n } else {\n // Fallback: print summary when toSchemaView is not available\n lines.push(`✔ ${result.summary}`);\n if (isVerbose(flags, 1)) {\n lines.push(` Target: ${result.target.familyId}/${result.target.id}`);\n if (result.meta?.dbUrl) {\n lines.push(` Database: ${result.meta.dbUrl}`);\n }\n }\n }\n\n // Add timings in verbose mode\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats human-readable output for database schema verification.\n */\nexport function formatSchemaVerifyOutput(\n result: VerifyDatabaseSchemaResult,\n flags: GlobalFlags,\n unclaimed: readonly string[] = [],\n): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatRed = createColorFormatter(useColor, red);\n const formatYellow = createColorFormatter(useColor, yellow);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n const issueMessages = result.schema.issues.map(formatIssueMessage);\n if (issueMessages.length > 0) {\n lines.push(formatRed('Schema issues:'));\n for (const message of issueMessages) {\n lines.push(` ${formatRed('✖')} ${message}`);\n }\n }\n\n const warningMessages = (result.schema.warnings?.issues ?? []).map(formatIssueMessage);\n if (warningMessages.length > 0) {\n if (lines.length > 0) lines.push('');\n lines.push(formatYellow('Schema warnings:'));\n for (const message of warningMessages) {\n lines.push(` ${formatYellow('⚠')} ${message}`);\n }\n }\n\n if (unclaimed.length > 0) {\n const strict = result.meta?.strict ?? false;\n if (lines.length > 0) lines.push('');\n lines.push(\n (strict ? formatRed : formatYellow)('Unclaimed elements (declared by no contract):'),\n );\n for (const name of unclaimed) {\n lines.push(` ${(strict ? formatRed : formatYellow)(strict ? '✖' : '⚠')} ${name}`);\n }\n }\n\n if (isVerbose(flags, 1)) {\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n\n // Blank line before summary\n if (lines.length > 0) lines.push('');\n\n // Summary line at the end: verdict with status glyph\n if (result.ok) {\n lines.push(`${formatGreen('✔')} ${result.summary}`);\n } else {\n const codeText = result.code ? ` (${result.code})` : '';\n lines.push(`${formatRed('✖')} ${result.summary}${codeText}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database schema verification. The unclaimed-elements\n * list is a top-level field alongside the combined result, reported once for\n * the whole database.\n */\nexport function formatSchemaVerifyJson(\n result: VerifyDatabaseSchemaResult,\n unclaimed: readonly string[] = [],\n): string {\n return JSON.stringify({ ...result, unclaimed }, null, 2);\n}\n\n// ============================================================================\n// Sign Output Formatters\n// ============================================================================\n\n/**\n * Formats human-readable output for database sign.\n */\nexport function formatSignOutput(result: SignDatabaseResult, flags: GlobalFlags): string {\n if (flags.quiet) {\n return '';\n }\n\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n if (result.ok) {\n // Main success message in white (not dimmed)\n lines.push(`${formatGreen('✔')} Database signed`);\n\n // Show from -> to hashes with clear labels\n const previousHash = result.marker.previous?.storageHash ?? 'none';\n const currentHash = result.contract.storageHash;\n\n lines.push(`${formatDimText(` from: ${previousHash}`)}`);\n lines.push(`${formatDimText(` to: ${currentHash}`)}`);\n\n if (isVerbose(flags, 1)) {\n if (result.contract.profileHash) {\n lines.push(`${formatDimText(` profileHash: ${result.contract.profileHash}`)}`);\n }\n if (result.marker.previous?.profileHash) {\n lines.push(\n `${formatDimText(` previous profileHash: ${result.marker.previous.profileHash}`)}`,\n );\n }\n lines.push(`${formatDimText(` Total time: ${result.timings.total}ms`)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats JSON output for database sign.\n */\nexport function formatSignJson(result: SignDatabaseResult): string {\n return JSON.stringify(result, null, 2);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0-dev.10",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -8,44 +8,46 @@
|
|
|
8
8
|
"prisma-next": "./dist/cli.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@clack/prompts": "^1.
|
|
12
|
-
"@prisma-next/config": "0.
|
|
13
|
-
"@prisma-next/
|
|
14
|
-
"@prisma-next/
|
|
15
|
-
"@prisma-next/
|
|
16
|
-
"@prisma-next/
|
|
17
|
-
"@prisma-next/
|
|
18
|
-
"@prisma-next/
|
|
19
|
-
"@prisma-next/
|
|
20
|
-
"@prisma-next/
|
|
21
|
-
"
|
|
22
|
-
"
|
|
11
|
+
"@clack/prompts": "^1.6.0",
|
|
12
|
+
"@prisma-next/config": "0.15.0-dev.10",
|
|
13
|
+
"@prisma-next/config-loader": "0.15.0-dev.10",
|
|
14
|
+
"@prisma-next/contract": "0.15.0-dev.10",
|
|
15
|
+
"@prisma-next/emitter": "0.15.0-dev.10",
|
|
16
|
+
"@prisma-next/errors": "0.15.0-dev.10",
|
|
17
|
+
"@prisma-next/framework-components": "0.15.0-dev.10",
|
|
18
|
+
"@prisma-next/language-server": "0.15.0-dev.10",
|
|
19
|
+
"@prisma-next/migration-tools": "0.15.0-dev.10",
|
|
20
|
+
"@prisma-next/psl-parser": "0.15.0-dev.10",
|
|
21
|
+
"@prisma-next/psl-printer": "0.15.0-dev.10",
|
|
22
|
+
"@prisma-next/cli-telemetry": "0.15.0-dev.10",
|
|
23
|
+
"@prisma-next/utils": "0.15.0-dev.10",
|
|
24
|
+
"arktype": "^2.2.2",
|
|
23
25
|
"ci-info": "^4.3.1",
|
|
24
26
|
"clipanion": "4.0.0-rc.4",
|
|
25
27
|
"closest-match": "^1.3.3",
|
|
26
28
|
"colorette": "^2.0.20",
|
|
27
29
|
"commander": "^14.0.3",
|
|
28
|
-
"esbuild": "^0.28.
|
|
30
|
+
"esbuild": "^0.28.1",
|
|
29
31
|
"jsonc-parser": "^3.3.1",
|
|
30
|
-
"package-manager-detector": "^1.
|
|
32
|
+
"package-manager-detector": "^1.7.0",
|
|
31
33
|
"pathe": "^2.0.3",
|
|
32
34
|
"string-width": "^8.2.1",
|
|
33
35
|
"strip-ansi": "^7.2.0",
|
|
34
36
|
"wrap-ansi": "^10.0.0"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@prisma-next/sql-contract": "0.
|
|
38
|
-
"@prisma-next/sql-contract-emitter": "0.
|
|
39
|
-
"@prisma-next/sql-contract-ts": "0.
|
|
40
|
-
"@prisma-next/sql-operations": "0.
|
|
41
|
-
"@prisma-next/sql-runtime": "0.
|
|
42
|
-
"@prisma-next/test-utils": "0.
|
|
43
|
-
"@prisma-next/tsconfig": "0.
|
|
44
|
-
"@prisma-next/tsdown": "0.
|
|
45
|
-
"@types/node": "25.9.
|
|
46
|
-
"tsdown": "0.22.
|
|
39
|
+
"@prisma-next/sql-contract": "0.15.0-dev.10",
|
|
40
|
+
"@prisma-next/sql-contract-emitter": "0.15.0-dev.10",
|
|
41
|
+
"@prisma-next/sql-contract-ts": "0.15.0-dev.10",
|
|
42
|
+
"@prisma-next/sql-operations": "0.15.0-dev.10",
|
|
43
|
+
"@prisma-next/sql-runtime": "0.15.0-dev.10",
|
|
44
|
+
"@prisma-next/test-utils": "0.15.0-dev.10",
|
|
45
|
+
"@prisma-next/tsconfig": "0.15.0-dev.10",
|
|
46
|
+
"@prisma-next/tsdown": "0.15.0-dev.10",
|
|
47
|
+
"@types/node": "25.9.4",
|
|
48
|
+
"tsdown": "0.22.3",
|
|
47
49
|
"typescript": "5.9.3",
|
|
48
|
-
"vitest": "4.1.
|
|
50
|
+
"vitest": "4.1.10"
|
|
49
51
|
},
|
|
50
52
|
"peerDependencies": {
|
|
51
53
|
"typescript": ">=5.9"
|
|
@@ -144,10 +146,6 @@
|
|
|
144
146
|
"types": "./dist/commands/telemetry/index.d.mts",
|
|
145
147
|
"import": "./dist/commands/telemetry/index.mjs"
|
|
146
148
|
},
|
|
147
|
-
"./config-loader": {
|
|
148
|
-
"types": "./dist/config-loader.d.mts",
|
|
149
|
-
"import": "./dist/config-loader.mjs"
|
|
150
|
-
},
|
|
151
149
|
"./migration-cli": {
|
|
152
150
|
"types": "./dist/migration-cli.d.mts",
|
|
153
151
|
"import": "./dist/migration-cli.mjs"
|
package/src/cli.ts
CHANGED
|
@@ -13,6 +13,8 @@ import { createDbSchemaCommand } from './commands/db-schema';
|
|
|
13
13
|
import { createDbSignCommand } from './commands/db-sign';
|
|
14
14
|
import { createDbUpdateCommand } from './commands/db-update';
|
|
15
15
|
import { createDbVerifyCommand } from './commands/db-verify';
|
|
16
|
+
import { createFormatCommand } from './commands/format';
|
|
17
|
+
import { createLspCommand } from './commands/lsp';
|
|
16
18
|
import { createMigrateCommand } from './commands/migrate';
|
|
17
19
|
import { createMigrationCheckCommand } from './commands/migration-check';
|
|
18
20
|
import { createMigrationGraphCommand } from './commands/migration-graph';
|
|
@@ -310,6 +312,9 @@ const telemetryCommand = createTelemetryCommand();
|
|
|
310
312
|
// Top-level init command
|
|
311
313
|
const initCommand = createInitCommand();
|
|
312
314
|
|
|
315
|
+
const formatCommand = createFormatCommand();
|
|
316
|
+
const lspCommand = createLspCommand();
|
|
317
|
+
|
|
313
318
|
// Register top-level commands in the order the spec's intended-surface
|
|
314
319
|
// diagram lists them: verbs (init, migrate) first, then subject
|
|
315
320
|
// namespaces (contract, db, migration, ref). The order shows up in
|
|
@@ -317,6 +322,8 @@ const initCommand = createInitCommand();
|
|
|
317
322
|
// matches the order spec.md uses to introduce the surface.
|
|
318
323
|
program.addCommand(initCommand);
|
|
319
324
|
program.addCommand(migrateCommand);
|
|
325
|
+
program.addCommand(formatCommand);
|
|
326
|
+
program.addCommand(lspCommand);
|
|
320
327
|
program.addCommand(contractCommand);
|
|
321
328
|
program.addCommand(dbCommand);
|
|
322
329
|
program.addCommand(migrationCommand);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { loadConfig } from '@prisma-next/config-loader';
|
|
1
2
|
import { getEmittedArtifactPaths } from '@prisma-next/emitter';
|
|
2
3
|
import { errorContractConfigMissing } from '@prisma-next/errors/control';
|
|
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
7
|
import { dirname, join, relative, resolve } from 'pathe';
|
|
7
|
-
import { loadConfig } from '../config-loader';
|
|
8
8
|
import { executeContractEmit } from '../control-api/operations/contract-emit';
|
|
9
9
|
import type { ContractEmitResult } from '../control-api/types';
|
|
10
10
|
import { CliStructuredError, errorUnexpected } from '../utils/cli-errors';
|
package/src/commands/db-sign.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 {
|
|
3
4
|
SignDatabaseResult,
|
|
4
5
|
VerifyDatabaseSchemaResult,
|
|
@@ -8,7 +9,6 @@ import { parseContractRef } from '@prisma-next/migration-tools/ref-resolution';
|
|
|
8
9
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
9
10
|
import { Command } from 'commander';
|
|
10
11
|
import { join, relative, resolve } from 'pathe';
|
|
11
|
-
import { loadConfig } from '../config-loader';
|
|
12
12
|
import { createControlClient } from '../control-api/client';
|
|
13
13
|
import { ContractValidationError } from '../control-api/errors';
|
|
14
14
|
import {
|
|
@@ -1,9 +1,7 @@
|
|
|
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
|
-
import type {
|
|
4
|
-
VerifyDatabaseResult,
|
|
5
|
-
VerifyDatabaseSchemaResult,
|
|
6
|
-
} from '@prisma-next/framework-components/control';
|
|
4
|
+
import type { VerifyDatabaseResult } from '@prisma-next/framework-components/control';
|
|
7
5
|
import {
|
|
8
6
|
createControlStack,
|
|
9
7
|
VERIFY_CODE_HASH_MISMATCH,
|
|
@@ -14,7 +12,6 @@ import { ifDefined } from '@prisma-next/utils/defined';
|
|
|
14
12
|
import { notOk, ok, type Result } from '@prisma-next/utils/result';
|
|
15
13
|
import { Command } from 'commander';
|
|
16
14
|
import { relative, resolve } from 'pathe';
|
|
17
|
-
import { loadConfig } from '../config-loader';
|
|
18
15
|
import { createControlClient } from '../control-api/client';
|
|
19
16
|
import { ContractValidationError } from '../control-api/errors';
|
|
20
17
|
import {
|
|
@@ -29,7 +26,7 @@ import {
|
|
|
29
26
|
errorTargetMismatch,
|
|
30
27
|
errorUnexpected,
|
|
31
28
|
} from '../utils/cli-errors';
|
|
32
|
-
import {
|
|
29
|
+
import { type CombinedVerifyResult, combineVerifyResults } from '../utils/combine-verify-results';
|
|
33
30
|
import {
|
|
34
31
|
addGlobalOptions,
|
|
35
32
|
maskConnectionUrl,
|
|
@@ -103,7 +100,7 @@ function mapVerifyFailure(verifyResult: VerifyDatabaseResult): CliStructuredErro
|
|
|
103
100
|
return errorRuntime(verifyResult.summary);
|
|
104
101
|
}
|
|
105
102
|
|
|
106
|
-
type DbVerifyFailure = CliStructuredError |
|
|
103
|
+
type DbVerifyFailure = CliStructuredError | CombinedVerifyResult;
|
|
107
104
|
|
|
108
105
|
function errorInvalidVerifyMode(options: {
|
|
109
106
|
readonly why: string;
|
|
@@ -419,12 +416,13 @@ async function executeDbVerifyCommand(
|
|
|
419
416
|
});
|
|
420
417
|
}
|
|
421
418
|
|
|
422
|
-
const combined =
|
|
419
|
+
const combined = combineVerifyResults(
|
|
423
420
|
aggregateResult.value.schemaResults,
|
|
424
421
|
aggregateResult.value.appSpaceId,
|
|
425
422
|
options.strict ?? false,
|
|
423
|
+
aggregateResult.value.unclaimed,
|
|
426
424
|
);
|
|
427
|
-
if (!combined.ok) {
|
|
425
|
+
if (!combined.result.ok) {
|
|
428
426
|
return notOk(combined);
|
|
429
427
|
}
|
|
430
428
|
|
|
@@ -438,10 +436,13 @@ async function executeDbVerifyCommand(
|
|
|
438
436
|
...ifDefined('missingCodecs', verifyResult.missingCodecs),
|
|
439
437
|
...ifDefined('codecCoverageSkipped', verifyResult.codecCoverageSkipped),
|
|
440
438
|
schema: {
|
|
441
|
-
summary: combined.summary,
|
|
442
|
-
|
|
443
|
-
|
|
439
|
+
summary: combined.result.summary,
|
|
440
|
+
strict: combined.result.meta?.strict ?? false,
|
|
441
|
+
warnings: (combined.result.schema.warnings?.issues ?? []).map((issue) =>
|
|
442
|
+
issue.path.join('/'),
|
|
443
|
+
),
|
|
444
444
|
},
|
|
445
|
+
unclaimed: combined.unclaimed,
|
|
445
446
|
meta: {
|
|
446
447
|
...(verifyResult.meta ?? {}),
|
|
447
448
|
schemaVerification: 'performed',
|
|
@@ -459,7 +460,7 @@ async function executeDbSchemaOnlyVerifyCommand(
|
|
|
459
460
|
options: DbVerifyOptions,
|
|
460
461
|
flags: GlobalFlags,
|
|
461
462
|
ui: TerminalUI,
|
|
462
|
-
): Promise<Result<
|
|
463
|
+
): Promise<Result<CombinedVerifyResult, CliStructuredError>> {
|
|
463
464
|
const paths = await resolveVerifyPaths(options);
|
|
464
465
|
renderVerifyHeader(paths, options, 'schema-only', flags, ui);
|
|
465
466
|
|
|
@@ -484,10 +485,11 @@ async function executeDbSchemaOnlyVerifyCommand(
|
|
|
484
485
|
if (!aggregateResult.ok) return notOk(aggregateResult.failure);
|
|
485
486
|
|
|
486
487
|
return ok(
|
|
487
|
-
|
|
488
|
+
combineVerifyResults(
|
|
488
489
|
aggregateResult.value.schemaResults,
|
|
489
490
|
aggregateResult.value.appSpaceId,
|
|
490
491
|
options.strict ?? false,
|
|
492
|
+
aggregateResult.value.unclaimed,
|
|
491
493
|
),
|
|
492
494
|
);
|
|
493
495
|
} catch (error) {
|
|
@@ -542,18 +544,26 @@ export function createDbVerifyCommand(): Command {
|
|
|
542
544
|
|
|
543
545
|
if (mode === 'schema-only') {
|
|
544
546
|
const result = await executeDbSchemaOnlyVerifyCommand(options, flags, ui);
|
|
545
|
-
const exitCode = handleResult(result, flags, ui, (
|
|
547
|
+
const exitCode = handleResult(result, flags, ui, (combined) => {
|
|
546
548
|
if (flags.json) {
|
|
547
|
-
ui.output(formatSchemaVerifyJson(
|
|
549
|
+
ui.output(formatSchemaVerifyJson(combined.result, combined.unclaimed));
|
|
548
550
|
} else {
|
|
549
|
-
|
|
551
|
+
// Always show schema-drift failures, even in quiet mode — exiting 1
|
|
552
|
+
// without diagnostics is unhelpful (same policy as the full-mode
|
|
553
|
+
// failure branch below).
|
|
554
|
+
const renderFlags = combined.result.ok ? flags : { ...flags, quiet: false };
|
|
555
|
+
const output = formatSchemaVerifyOutput(
|
|
556
|
+
combined.result,
|
|
557
|
+
renderFlags,
|
|
558
|
+
combined.unclaimed,
|
|
559
|
+
);
|
|
550
560
|
if (output) {
|
|
551
561
|
ui.log(output);
|
|
552
562
|
}
|
|
553
563
|
}
|
|
554
564
|
});
|
|
555
565
|
|
|
556
|
-
if (result.ok && !result.value.ok) {
|
|
566
|
+
if (result.ok && !result.value.result.ok) {
|
|
557
567
|
process.exit(1);
|
|
558
568
|
}
|
|
559
569
|
|
|
@@ -580,11 +590,15 @@ export function createDbVerifyCommand(): Command {
|
|
|
580
590
|
}
|
|
581
591
|
|
|
582
592
|
if (flags.json) {
|
|
583
|
-
ui.output(formatSchemaVerifyJson(result.failure));
|
|
593
|
+
ui.output(formatSchemaVerifyJson(result.failure.result, result.failure.unclaimed));
|
|
584
594
|
} else {
|
|
585
595
|
// Always show schema-drift failures, even in quiet mode — exiting 1 without
|
|
586
596
|
// diagnostics is unhelpful.
|
|
587
|
-
const output = formatSchemaVerifyOutput(
|
|
597
|
+
const output = formatSchemaVerifyOutput(
|
|
598
|
+
result.failure.result,
|
|
599
|
+
{ ...flags, quiet: false },
|
|
600
|
+
result.failure.unclaimed,
|
|
601
|
+
);
|
|
588
602
|
if (output) {
|
|
589
603
|
ui.log(output);
|
|
590
604
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { relative, resolve } from 'pathe';
|
|
4
|
+
import { executeFormat } from '../control-api/operations/format';
|
|
5
|
+
import {
|
|
6
|
+
addGlobalOptions,
|
|
7
|
+
setCommandDescriptions,
|
|
8
|
+
setCommandExamples,
|
|
9
|
+
} from '../utils/command-helpers';
|
|
10
|
+
import { formatStyledHeader } from '../utils/formatters/styled';
|
|
11
|
+
import type { CommonCommandOptions } from '../utils/global-flags';
|
|
12
|
+
import { parseGlobalFlagsOrExit } from '../utils/global-flags';
|
|
13
|
+
import { handleResult } from '../utils/result-handler';
|
|
14
|
+
import { createTerminalUI } from '../utils/terminal-ui';
|
|
15
|
+
|
|
16
|
+
interface FormatCommandOptions extends CommonCommandOptions {
|
|
17
|
+
readonly config?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createFormatCommand(): Command {
|
|
21
|
+
const command = new Command('format');
|
|
22
|
+
setCommandDescriptions(
|
|
23
|
+
command,
|
|
24
|
+
'Format your PSL contract source',
|
|
25
|
+
'Formats the Prisma schema (PSL) contract source declared in your config\n' +
|
|
26
|
+
'(contract.source.inputs[0]) in place. Only runs when contract.source.sourceFormat\n' +
|
|
27
|
+
"is 'psl'; a TypeScript or unset source is left untouched. Indent and newline are\n" +
|
|
28
|
+
'read from the optional formatter config section, defaulting to two spaces and the\n' +
|
|
29
|
+
'system newline.',
|
|
30
|
+
);
|
|
31
|
+
setCommandExamples(command, [
|
|
32
|
+
'prisma-next format',
|
|
33
|
+
'prisma-next format --config ./custom-config.ts',
|
|
34
|
+
]);
|
|
35
|
+
addGlobalOptions(command)
|
|
36
|
+
.option('--config <path>', 'Path to prisma-next.config.ts')
|
|
37
|
+
.action(async (options: FormatCommandOptions) => {
|
|
38
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
39
|
+
const ui = createTerminalUI(flags);
|
|
40
|
+
|
|
41
|
+
if (!flags.json && !flags.quiet) {
|
|
42
|
+
const displayConfigPath = options.config
|
|
43
|
+
? relative(process.cwd(), resolve(options.config))
|
|
44
|
+
: 'prisma-next.config.ts';
|
|
45
|
+
ui.stderr(
|
|
46
|
+
formatStyledHeader({
|
|
47
|
+
command: 'format',
|
|
48
|
+
description: 'Format your PSL contract source',
|
|
49
|
+
details: [{ label: 'config', value: displayConfigPath }],
|
|
50
|
+
flags,
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const result = await executeFormat({ ...ifDefined('configPath', options.config) });
|
|
56
|
+
|
|
57
|
+
const exitCode = handleResult(result, flags, ui, (value) => {
|
|
58
|
+
if (flags.json) {
|
|
59
|
+
ui.output(JSON.stringify(value));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (flags.quiet) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (value.formatted) {
|
|
66
|
+
ui.success(`Formatted ${relative(process.cwd(), value.path ?? '')}`);
|
|
67
|
+
} else {
|
|
68
|
+
ui.info('Nothing to format (contract source is not PSL).');
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
process.exit(exitCode);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return command;
|
|
75
|
+
}
|
|
@@ -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
|
+
}
|