@prisma-next/cli 0.4.0-dev.2 → 0.4.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/cli.mjs +4 -11
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-DiUkJAeN.mjs → client-tdnbk0OR.mjs} +9 -2
- package/dist/{client-DiUkJAeN.mjs.map → client-tdnbk0OR.mjs.map} +1 -1
- package/dist/commands/contract-emit.mjs +1 -6
- package/dist/commands/contract-infer.mjs +1 -7
- package/dist/commands/db-init.mjs +2 -3
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +1 -4
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.mjs +1 -2
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.mjs +2 -3
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.mjs +1 -2
- package/dist/commands/db-verify.mjs.map +1 -1
- package/dist/commands/migration-apply.mjs +1 -2
- package/dist/commands/migration-apply.mjs.map +1 -1
- package/dist/commands/migration-status.mjs +1 -6
- package/dist/contract-emit-CGpb33vs.mjs +4 -0
- package/dist/{contract-emit-Zm_sd1wQ.mjs → contract-emit-CRoS1nx5.mjs} +9 -3
- package/dist/contract-emit-CRoS1nx5.mjs.map +1 -0
- package/dist/{contract-emit-D2wDXfyo.mjs → contract-emit-Ctn6mH9H.mjs} +2 -2
- package/dist/{contract-emit-D2wDXfyo.mjs.map → contract-emit-Ctn6mH9H.mjs.map} +1 -1
- package/dist/{contract-infer-DozZT511.mjs → contract-infer-Ba1SE57Q.mjs} +2 -2
- package/dist/{contract-infer-DozZT511.mjs.map → contract-infer-Ba1SE57Q.mjs.map} +1 -1
- package/dist/exports/control-api.mjs +2 -4
- package/dist/exports/index.mjs +1 -6
- package/dist/exports/index.mjs.map +1 -1
- package/dist/{init-6Pvm_esG.mjs → init-Dx5uJ-6Q.mjs} +7 -7
- package/dist/{init-6Pvm_esG.mjs.map → init-Dx5uJ-6Q.mjs.map} +1 -1
- package/dist/{inspect-live-schema-BYnhztxZ.mjs → inspect-live-schema-gYQiWfpl.mjs} +2 -2
- package/dist/{inspect-live-schema-BYnhztxZ.mjs.map → inspect-live-schema-gYQiWfpl.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-CntCcntR.mjs → migration-command-scaffold-x4n_ZhAh.mjs} +2 -2
- package/dist/{migration-command-scaffold-CntCcntR.mjs.map → migration-command-scaffold-x4n_ZhAh.mjs.map} +1 -1
- package/dist/{migration-status-CJANY4yr.mjs → migration-status-DyVDf5NI.mjs} +2 -2
- package/dist/{migration-status-CJANY4yr.mjs.map → migration-status-DyVDf5NI.mjs.map} +1 -1
- package/package.json +16 -16
- package/src/commands/init/init.ts +5 -5
- package/src/control-api/client.ts +6 -1
- package/src/control-api/operations/contract-emit.ts +7 -2
- package/dist/contract-emit-Zm_sd1wQ.mjs.map +0 -1
- package/dist/contract-emit-kN-IkKTE.mjs +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-emit-D2wDXfyo.mjs","names":["lines: string[]","exhaustive: never","config: Awaited<ReturnType<typeof loadConfig>>","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 { mkdirSync, writeFileSync } from 'node:fs';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, isAbsolute, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { EmitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorRuntime,\n errorUnexpected,\n} 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, parseGlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nfunction mapDiagnosticsToIssues(\n failure: EmitFailure,\n): ReadonlyArray<{ kind: string; message: string }> {\n const diagnostics = failure.diagnostics?.diagnostics ?? [];\n return diagnostics.map((diagnostic) => {\n const location =\n diagnostic.sourceId && diagnostic.span\n ? ` (${diagnostic.sourceId}:${diagnostic.span.start.line}:${diagnostic.span.start.column})`\n : diagnostic.sourceId\n ? ` (${diagnostic.sourceId})`\n : '';\n return {\n kind: diagnostic.code,\n message: `${diagnostic.message}${location}`,\n };\n });\n}\n\n/**\n * Maps an EmitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapEmitFailure(\n failure: EmitFailure,\n context?: { readonly configPath?: string },\n): CliStructuredError {\n if (failure.code === 'CONTRACT_SOURCE_INVALID') {\n const issues = mapDiagnosticsToIssues(failure);\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Contract source provider failed',\n fix: 'Check your contract source provider in prisma-next.config.ts and ensure it returns Result<Contract, Diagnostics>',\n ...(issues.length > 0 ? { meta: { issues } } : {}),\n });\n }\n\n if (failure.code === 'CONTRACT_VALIDATION_FAILED') {\n return errorContractValidationFailed(\n failure.why ?? 'Contract validation failed while emitting',\n context?.configPath ? { where: { path: context.configPath } } : undefined,\n );\n }\n\n if (failure.code === 'EMIT_FAILED') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Failed to emit contract',\n fix: 'Check your contract configuration and ensure the source is valid',\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled EmitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the contract emit command and returns a structured Result.\n */\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n // Load config\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(options.config);\n } catch (error) {\n // Convert thrown CliStructuredError to Result\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 configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n // Resolve contract from config\n if (!config.contract) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n // Contract config is already normalized by defineConfig() with defaults applied\n const contractConfig = config.contract;\n\n // Resolve artifact paths from config (already normalized by defineConfig() with defaults)\n if (!contractConfig.output) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n }),\n );\n }\n if (!contractConfig.output.endsWith('.json')) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config output path must end with .json (e.g., \"src/prisma/contract.json\")',\n }),\n );\n }\n const configDir = options.config ? dirname(resolve(options.config)) : process.cwd();\n const outputJsonPath = isAbsolute(contractConfig.output)\n ? contractConfig.output\n : join(configDir, contractConfig.output);\n // Colocate .d.ts with .json (contract.json → contract.d.ts)\n const outputDtsPath = `${outputJsonPath.slice(0, -5)}.d.ts`;\n\n // Output header to stderr (decoration)\n if (!flags.json && !flags.quiet) {\n const contractPath = relative(process.cwd(), outputJsonPath);\n const typesPath = relative(process.cwd(), outputDtsPath);\n const header = formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'types', value: typesPath },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n // Create control client (no driver needed for emit)\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Call emit with progress callback\n const result = await client.emit({\n contractConfig: {\n sourceProvider: contractConfig.source,\n output: outputJsonPath,\n },\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapEmitFailure(result.failure, { configPath }));\n }\n\n // Create directories if needed\n mkdirSync(dirname(outputJsonPath), { recursive: true });\n mkdirSync(dirname(outputDtsPath), { recursive: true });\n\n // Write the results to files\n writeFileSync(outputJsonPath, result.value.contractJson, 'utf-8');\n writeFileSync(outputDtsPath, result.value.contractDts, 'utf-8');\n\n // Validate that contract.d.ts type imports are resolvable\n const { validateContractDeps } = await import('../utils/validate-contract-deps');\n const depsValidation = validateContractDeps(result.value.contractDts, dirname(outputDtsPath));\n if (depsValidation.warning) {\n ui.warn(depsValidation.warning);\n }\n\n // Convert success result to CLI output format\n const emitResult: EmitContractResult = {\n storageHash: result.value.storageHash,\n ...(result.value.executionHash ? { executionHash: result.value.executionHash } : {}),\n profileHash: result.value.profileHash,\n outDir: dirname(outputJsonPath),\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n timings: { total: Date.now() - startTime },\n };\n\n return ok(emitResult);\n } catch (error) {\n // Use static type guard to work across module boundaries\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n } finally {\n await client.close();\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 ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n // Handle result - formats output and returns exit code\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
|
+
{"version":3,"file":"contract-emit-Ctn6mH9H.mjs","names":["lines: string[]","exhaustive: never","config: Awaited<ReturnType<typeof loadConfig>>","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 { mkdirSync, writeFileSync } from 'node:fs';\nimport { errorContractConfigMissing } from '@prisma-next/errors/control';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, isAbsolute, join, relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { EmitFailure } from '../control-api/types';\nimport {\n CliStructuredError,\n errorContractValidationFailed,\n errorRuntime,\n errorUnexpected,\n} 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, parseGlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\n\ninterface ContractEmitOptions extends CommonCommandOptions {\n readonly config?: string;\n}\n\nfunction mapDiagnosticsToIssues(\n failure: EmitFailure,\n): ReadonlyArray<{ kind: string; message: string }> {\n const diagnostics = failure.diagnostics?.diagnostics ?? [];\n return diagnostics.map((diagnostic) => {\n const location =\n diagnostic.sourceId && diagnostic.span\n ? ` (${diagnostic.sourceId}:${diagnostic.span.start.line}:${diagnostic.span.start.column})`\n : diagnostic.sourceId\n ? ` (${diagnostic.sourceId})`\n : '';\n return {\n kind: diagnostic.code,\n message: `${diagnostic.message}${location}`,\n };\n });\n}\n\n/**\n * Maps an EmitFailure to a CliStructuredError for consistent error handling.\n */\nfunction mapEmitFailure(\n failure: EmitFailure,\n context?: { readonly configPath?: string },\n): CliStructuredError {\n if (failure.code === 'CONTRACT_SOURCE_INVALID') {\n const issues = mapDiagnosticsToIssues(failure);\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Contract source provider failed',\n fix: 'Check your contract source provider in prisma-next.config.ts and ensure it returns Result<Contract, Diagnostics>',\n ...(issues.length > 0 ? { meta: { issues } } : {}),\n });\n }\n\n if (failure.code === 'CONTRACT_VALIDATION_FAILED') {\n return errorContractValidationFailed(\n failure.why ?? 'Contract validation failed while emitting',\n context?.configPath ? { where: { path: context.configPath } } : undefined,\n );\n }\n\n if (failure.code === 'EMIT_FAILED') {\n return errorRuntime(failure.summary, {\n why: failure.why ?? 'Failed to emit contract',\n fix: 'Check your contract configuration and ensure the source is valid',\n });\n }\n\n // Exhaustive check - TypeScript will error if a new code is added but not handled\n const exhaustive: never = failure.code;\n throw new Error(`Unhandled EmitFailure code: ${exhaustive}`);\n}\n\n/**\n * Executes the contract emit command and returns a structured Result.\n */\nasync function executeContractEmitCommand(\n options: ContractEmitOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<EmitContractResult, CliStructuredError>> {\n // Load config\n let config: Awaited<ReturnType<typeof loadConfig>>;\n try {\n config = await loadConfig(options.config);\n } catch (error) {\n // Convert thrown CliStructuredError to Result\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 configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n // Resolve contract from config\n if (!config.contract) {\n return notOk(\n errorContractConfigMissing({\n why: 'Config.contract is required for emit. Define it in your config: contract: { source: ..., output: ... }',\n }),\n );\n }\n\n // Contract config is already normalized by defineConfig() with defaults applied\n const contractConfig = config.contract;\n\n // Resolve artifact paths from config (already normalized by defineConfig() with defaults)\n if (!contractConfig.output) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config must have output path. This should not happen if defineConfig() was used.',\n }),\n );\n }\n if (!contractConfig.output.endsWith('.json')) {\n return notOk(\n errorContractConfigMissing({\n why: 'Contract config output path must end with .json (e.g., \"src/prisma/contract.json\")',\n }),\n );\n }\n const configDir = options.config ? dirname(resolve(options.config)) : process.cwd();\n const outputJsonPath = isAbsolute(contractConfig.output)\n ? contractConfig.output\n : join(configDir, contractConfig.output);\n // Colocate .d.ts with .json (contract.json → contract.d.ts)\n const outputDtsPath = `${outputJsonPath.slice(0, -5)}.d.ts`;\n\n // Output header to stderr (decoration)\n if (!flags.json && !flags.quiet) {\n const contractPath = relative(process.cwd(), outputJsonPath);\n const typesPath = relative(process.cwd(), outputDtsPath);\n const header = formatStyledHeader({\n command: 'contract emit',\n description: 'Emit your contract artifacts',\n url: 'https://pris.ly/contract-emit',\n details: [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n { label: 'types', value: typesPath },\n ],\n flags,\n });\n ui.stderr(header);\n }\n\n // Create control client (no driver needed for emit)\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n // Call emit with progress callback\n const result = await client.emit({\n contractConfig: {\n sourceProvider: contractConfig.source,\n output: outputJsonPath,\n },\n onProgress,\n });\n\n // Handle failures by mapping to CLI structured error\n if (!result.ok) {\n return notOk(mapEmitFailure(result.failure, { configPath }));\n }\n\n // Create directories if needed\n mkdirSync(dirname(outputJsonPath), { recursive: true });\n mkdirSync(dirname(outputDtsPath), { recursive: true });\n\n // Write the results to files\n writeFileSync(outputJsonPath, result.value.contractJson, 'utf-8');\n writeFileSync(outputDtsPath, result.value.contractDts, 'utf-8');\n\n // Validate that contract.d.ts type imports are resolvable\n const { validateContractDeps } = await import('../utils/validate-contract-deps');\n const depsValidation = validateContractDeps(result.value.contractDts, dirname(outputDtsPath));\n if (depsValidation.warning) {\n ui.warn(depsValidation.warning);\n }\n\n // Convert success result to CLI output format\n const emitResult: EmitContractResult = {\n storageHash: result.value.storageHash,\n ...(result.value.executionHash ? { executionHash: result.value.executionHash } : {}),\n profileHash: result.value.profileHash,\n outDir: dirname(outputJsonPath),\n files: {\n json: outputJsonPath,\n dts: outputDtsPath,\n },\n timings: { total: Date.now() - startTime },\n };\n\n return ok(emitResult);\n } catch (error) {\n // Use static type guard to work across module boundaries\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n // Wrap unexpected errors\n return notOk(\n errorUnexpected('Unexpected error during contract emit', {\n why: error instanceof Error ? error.message : String(error),\n }),\n );\n } finally {\n await client.close();\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 ]);\n addGlobalOptions(command)\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .action(async (options: ContractEmitOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const startTime = Date.now();\n\n const result = await executeContractEmitCommand(options, flags, ui, startTime);\n\n // Handle result - formats output and returns exit code\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,6 +1,6 @@
|
|
|
1
1
|
import { d as setCommandExamples, m as parseGlobalFlags, n as addGlobalOptions, t as handleResult, u as setCommandDescriptions } from "./result-handler-oK_vA-Fn.mjs";
|
|
2
2
|
import { t as TerminalUI } from "./terminal-ui-C5k88MmW.mjs";
|
|
3
|
-
import { t as inspectLiveSchema } from "./inspect-live-schema-
|
|
3
|
+
import { t as inspectLiveSchema } from "./inspect-live-schema-gYQiWfpl.mjs";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -87,4 +87,4 @@ function createContractInferCommand() {
|
|
|
87
87
|
|
|
88
88
|
//#endregion
|
|
89
89
|
export { createContractInferCommand as t };
|
|
90
|
-
//# sourceMappingURL=contract-infer-
|
|
90
|
+
//# sourceMappingURL=contract-infer-Ba1SE57Q.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract-infer-
|
|
1
|
+
{"version":3,"file":"contract-infer-Ba1SE57Q.mjs","names":[],"sources":["../src/commands/contract-infer-paths.ts","../src/commands/contract-infer.ts"],"sourcesContent":["import { dirname, resolve } from 'pathe';\n\ninterface ContractInferPathOptions {\n readonly output?: string;\n readonly config?: string;\n}\n\n/**\n * Resolves the output path for the inferred PSL contract.\n *\n * Priority:\n * 1. --output <path> flag (resolved relative to cwd)\n * 2. contract.prisma next to config.contract.output\n * 3. Canonical default: contract.prisma in the config directory\n */\nexport function resolveContractInferOutputPath(\n options: ContractInferPathOptions,\n contractOutput: string | undefined,\n): string {\n const configDir = options.config\n ? dirname(resolve(process.cwd(), options.config))\n : process.cwd();\n\n if (options.output) {\n return resolve(process.cwd(), options.output);\n }\n if (contractOutput) {\n const contractPath = resolve(configDir, contractOutput);\n return resolve(dirname(contractPath), 'contract.prisma');\n }\n return resolve(configDir, 'contract.prisma');\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { errorRuntime } from '@prisma-next/errors/execution';\nimport { printPsl, validatePrintableSqlSchemaIR } from '@prisma-next/psl-printer';\nimport {\n createPostgresDefaultMapping,\n createPostgresTypeMap,\n extractEnumInfo,\n parseRawDefault,\n} from '@prisma-next/psl-printer/postgres';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { Command } from 'commander';\nimport { dirname, relative } from 'pathe';\nimport type { CliStructuredError } from '../utils/cli-errors';\nimport {\n addGlobalOptions,\n setCommandDescriptions,\n setCommandExamples,\n} from '../utils/command-helpers';\nimport { parseGlobalFlags } from '../utils/global-flags';\nimport { handleResult } from '../utils/result-handler';\nimport { TerminalUI } from '../utils/terminal-ui';\nimport { resolveContractInferOutputPath } from './contract-infer-paths';\nimport {\n type InspectLiveSchemaOptions,\n type InspectLiveSchemaResult,\n inspectLiveSchema,\n} from './inspect-live-schema';\n\ninterface ContractInferOptions extends InspectLiveSchemaOptions {\n readonly output?: string;\n}\n\ninterface ContractInferSuccessResult {\n readonly ok: true;\n readonly summary: string;\n readonly target: InspectLiveSchemaResult['target'];\n readonly psl: {\n readonly path: string;\n };\n readonly meta: InspectLiveSchemaResult['meta'];\n readonly timings: {\n readonly total: number;\n };\n}\n\nasync function executeContractInferCommand(\n options: ContractInferOptions,\n ui: TerminalUI,\n startTime: number,\n): Promise<Result<ContractInferSuccessResult, CliStructuredError>> {\n const flags = parseGlobalFlags(options);\n const inspectResult = await inspectLiveSchema(options, flags, ui, startTime, {\n commandName: 'contract infer',\n description: 'Infer a PSL contract from the live database schema',\n url: 'https://pris.ly/contract-infer',\n });\n\n if (!inspectResult.ok) {\n return inspectResult;\n }\n\n const { config, target, meta } = inspectResult.value;\n\n if (target.familyId !== 'sql') {\n return notOk(\n errorRuntime(`contract infer is not supported for family \"${target.familyId}\"`, {\n why: 'contract infer currently supports SQL targets only',\n fix: 'Use an SQL target (e.g. Postgres) with this command',\n }),\n );\n }\n\n const schema = validatePrintableSqlSchemaIR(inspectResult.value.schema);\n const outputPath = resolveContractInferOutputPath(options, config.contract?.output);\n const enumInfo = extractEnumInfo(schema.annotations);\n const pslContent = printPsl(schema, {\n defaultMapping: createPostgresDefaultMapping(),\n typeMap: createPostgresTypeMap(enumInfo.typeNames),\n enumInfo,\n parseRawDefault,\n });\n\n if (existsSync(outputPath) && !flags.json && !flags.quiet) {\n ui.stderr(`\\u26A0 Overwriting existing file: ${relative(process.cwd(), outputPath)}`);\n }\n\n mkdirSync(dirname(outputPath), { recursive: true });\n writeFileSync(outputPath, pslContent, 'utf-8');\n\n const pslPath = relative(process.cwd(), outputPath);\n if (!flags.json && !flags.quiet) {\n ui.stderr(`\\u2714 Contract written to ${pslPath}`);\n }\n\n return ok({\n ok: true,\n summary: 'Contract inferred successfully',\n target,\n psl: {\n path: pslPath,\n },\n meta,\n timings: {\n total: Date.now() - startTime,\n },\n });\n}\n\nexport function createContractInferCommand(): Command {\n const command = new Command('infer');\n setCommandDescriptions(\n command,\n 'Infer a PSL contract from the live database schema',\n 'Reads the live database schema and writes an inferred PSL contract to disk.\\n' +\n 'This command stops at `contract.prisma`; follow it with `contract emit` and\\n' +\n '`db sign` as separate steps.',\n );\n setCommandExamples(command, [\n 'prisma-next contract infer --db $DATABASE_URL',\n 'prisma-next contract infer --db $DATABASE_URL --output ./prisma/contract.prisma',\n 'prisma-next contract infer --db $DATABASE_URL --json',\n ]);\n addGlobalOptions(command)\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--output <path>', 'Write the inferred PSL contract to the specified path')\n .action(async (options: ContractInferOptions) => {\n const flags = parseGlobalFlags(options);\n const ui = new TerminalUI({ color: flags.color, interactive: flags.interactive });\n const startTime = Date.now();\n\n const result = await executeContractInferCommand(options, ui, startTime);\n const exitCode = handleResult(result, flags, ui, (value) => {\n if (flags.json) {\n ui.output(JSON.stringify(value, null, 2));\n }\n });\n\n process.exit(exitCode);\n });\n\n return command;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAeA,SAAgB,+BACd,SACA,gBACQ;CACR,MAAM,YAAY,QAAQ,SACtB,QAAQ,QAAQ,QAAQ,KAAK,EAAE,QAAQ,OAAO,CAAC,GAC/C,QAAQ,KAAK;AAEjB,KAAI,QAAQ,OACV,QAAO,QAAQ,QAAQ,KAAK,EAAE,QAAQ,OAAO;AAE/C,KAAI,eAEF,QAAO,QAAQ,QADM,QAAQ,WAAW,eAAe,CACnB,EAAE,kBAAkB;AAE1D,QAAO,QAAQ,WAAW,kBAAkB;;;;;ACe9C,eAAe,4BACb,SACA,IACA,WACiE;CACjE,MAAM,QAAQ,iBAAiB,QAAQ;CACvC,MAAM,gBAAgB,MAAM,kBAAkB,SAAS,OAAO,IAAI,WAAW;EAC3E,aAAa;EACb,aAAa;EACb,KAAK;EACN,CAAC;AAEF,KAAI,CAAC,cAAc,GACjB,QAAO;CAGT,MAAM,EAAE,QAAQ,QAAQ,SAAS,cAAc;AAE/C,KAAI,OAAO,aAAa,MACtB,QAAO,MACL,aAAa,+CAA+C,OAAO,SAAS,IAAI;EAC9E,KAAK;EACL,KAAK;EACN,CAAC,CACH;CAGH,MAAM,SAAS,6BAA6B,cAAc,MAAM,OAAO;CACvE,MAAM,aAAa,+BAA+B,SAAS,OAAO,UAAU,OAAO;CACnF,MAAM,WAAW,gBAAgB,OAAO,YAAY;CACpD,MAAM,aAAa,SAAS,QAAQ;EAClC,gBAAgB,8BAA8B;EAC9C,SAAS,sBAAsB,SAAS,UAAU;EAClD;EACA;EACD,CAAC;AAEF,KAAI,WAAW,WAAW,IAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,MAClD,IAAG,OAAO,qCAAqC,SAAS,QAAQ,KAAK,EAAE,WAAW,GAAG;AAGvF,WAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,eAAc,YAAY,YAAY,QAAQ;CAE9C,MAAM,UAAU,SAAS,QAAQ,KAAK,EAAE,WAAW;AACnD,KAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,MACxB,IAAG,OAAO,8BAA8B,UAAU;AAGpD,QAAO,GAAG;EACR,IAAI;EACJ,SAAS;EACT;EACA,KAAK,EACH,MAAM,SACP;EACD;EACA,SAAS,EACP,OAAO,KAAK,KAAK,GAAG,WACrB;EACF,CAAC;;AAGJ,SAAgB,6BAAsC;CACpD,MAAM,UAAU,IAAI,QAAQ,QAAQ;AACpC,wBACE,SACA,sDACA,yLAGD;AACD,oBAAmB,SAAS;EAC1B;EACA;EACA;EACD,CAAC;AACF,kBAAiB,QAAQ,CACtB,OAAO,cAAc,6BAA6B,CAClD,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,mBAAmB,wDAAwD,CAClF,OAAO,OAAO,YAAkC;EAC/C,MAAM,QAAQ,iBAAiB,QAAQ;EACvC,MAAM,KAAK,IAAI,WAAW;GAAE,OAAO,MAAM;GAAO,aAAa,MAAM;GAAa,CAAC;EAIjF,MAAM,WAAW,aADF,MAAM,4BAA4B,SAAS,IAFxC,KAAK,KAAK,CAE4C,EAClC,OAAO,KAAK,UAAU;AAC1D,OAAI,MAAM,KACR,IAAG,OAAO,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;IAE3C;AAEF,UAAQ,KAAK,SAAS;GACtB;AAEJ,QAAO"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import "../config-loader-C4VXKl8f.mjs";
|
|
2
|
-
import "../cli-errors-BDCYR5ap.mjs";
|
|
3
|
-
import "../framework-components-BAsliT4V.mjs";
|
|
4
2
|
import { t as enrichContract } from "../contract-enrichment-CGW6mm-E.mjs";
|
|
5
|
-
import { t as createControlClient } from "../client-
|
|
6
|
-
import { t as executeContractEmit } from "../contract-emit-
|
|
3
|
+
import { t as createControlClient } from "../client-tdnbk0OR.mjs";
|
|
4
|
+
import { t as executeContractEmit } from "../contract-emit-CRoS1nx5.mjs";
|
|
7
5
|
|
|
8
6
|
export { createControlClient, enrichContract, executeContractEmit };
|
package/dist/exports/index.mjs
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import "../config-loader-C4VXKl8f.mjs";
|
|
2
|
-
import "../
|
|
3
|
-
import "../framework-components-BAsliT4V.mjs";
|
|
4
|
-
import "../client-DiUkJAeN.mjs";
|
|
5
|
-
import "../result-handler-oK_vA-Fn.mjs";
|
|
6
|
-
import { t as createContractEmitCommand } from "../contract-emit-D2wDXfyo.mjs";
|
|
7
|
-
import "../terminal-ui-C5k88MmW.mjs";
|
|
2
|
+
import { t as createContractEmitCommand } from "../contract-emit-Ctn6mH9H.mjs";
|
|
8
3
|
import { existsSync, unlinkSync, writeFileSync } from "node:fs";
|
|
9
4
|
import { join } from "pathe";
|
|
10
5
|
import { tmpdir } from "node:os";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["value","disallowedImports: string[]","contract: unknown"],"sources":["../../src/load-ts-contract.ts"],"sourcesContent":["import { existsSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { pathToFileURL } from 'node:url';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { Plugin } from 'esbuild';\nimport { build } from 'esbuild';\nimport { join } from 'pathe';\n\nexport interface LoadTsContractOptions {\n readonly allowlist?: ReadonlyArray<string>;\n}\n\nconst DEFAULT_ALLOWLIST = ['@prisma-next/*', 'node:crypto'];\n\nfunction isAllowedImport(importPath: string, allowlist: ReadonlyArray<string>): boolean {\n for (const pattern of allowlist) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n if (importPath === prefix || importPath.startsWith(`${prefix}/`)) {\n return true;\n }\n } else if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1);\n if (importPath.startsWith(prefix)) {\n return true;\n }\n } else if (importPath === pattern) {\n return true;\n }\n }\n return false;\n}\n\nfunction validatePurity(value: unknown): void {\n if (typeof value !== 'object' || value === null) {\n return;\n }\n\n const path = new WeakSet();\n\n function check(value: unknown): void {\n if (value === null || typeof value !== 'object') {\n return;\n }\n\n if (path.has(value)) {\n throw new Error('Contract export contains circular references');\n }\n path.add(value);\n\n try {\n for (const key in value) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor && (descriptor.get || descriptor.set)) {\n throw new Error(`Contract export contains getter/setter at key \"${key}\"`);\n }\n if (descriptor && typeof descriptor.value === 'function') {\n throw new Error(`Contract export contains function at key \"${key}\"`);\n }\n check((value as Record<string, unknown>)[key]);\n }\n } finally {\n path.delete(value);\n }\n }\n\n try {\n check(value);\n JSON.stringify(value);\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('getter') || error.message.includes('circular')) {\n throw error;\n }\n throw new Error(`Contract export is not JSON-serializable: ${error.message}`);\n }\n throw new Error('Contract export is not JSON-serializable');\n }\n}\n\nfunction createImportAllowlistPlugin(allowlist: ReadonlyArray<string>, entryPath: string): Plugin {\n return {\n name: 'import-allowlist',\n setup(build) {\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind === 'entry-point') {\n return undefined;\n }\n if (args.path.startsWith('.') || args.path.startsWith('/')) {\n return undefined;\n }\n const isFromEntryPoint = args.importer === entryPath || args.importer === '<stdin>';\n if (isFromEntryPoint && !isAllowedImport(args.path, allowlist)) {\n return {\n path: args.path,\n external: true,\n };\n }\n return undefined;\n });\n },\n };\n}\n\n/**\n * Loads a contract from a TypeScript file and returns it as Contract.\n *\n * **Responsibility: Parsing Only**\n * This function loads and parses a TypeScript contract file. It does NOT normalize the contract.\n * The contract should already be normalized if it was built using the contract builder.\n *\n * Normalization must happen in the contract builder when the contract is created.\n * This function only validates that the contract is JSON-serializable and returns it as-is.\n *\n * @param entryPath - Path to the TypeScript contract file\n * @param options - Optional configuration (import allowlist)\n * @returns The contract as Contract (should already be normalized)\n * @throws Error if the contract cannot be loaded or is not JSON-serializable\n */\nexport async function loadContractFromTs(\n entryPath: string,\n options?: LoadTsContractOptions,\n): Promise<Contract> {\n const allowlist = options?.allowlist ?? DEFAULT_ALLOWLIST;\n\n if (!existsSync(entryPath)) {\n throw new Error(`Contract file not found: ${entryPath}`);\n }\n\n const tempFile = join(\n tmpdir(),\n `prisma-next-contract-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`,\n );\n\n try {\n const result = await build({\n entryPoints: [entryPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'es2022',\n outfile: tempFile,\n write: false,\n metafile: true,\n plugins: [createImportAllowlistPlugin(allowlist, entryPath)],\n logLevel: 'error',\n });\n\n if (result.errors.length > 0) {\n const errorMessages = result.errors.map((e: { text: string }) => e.text).join('\\n');\n throw new Error(`Failed to bundle contract file: ${errorMessages}`);\n }\n\n if (!result.outputFiles || result.outputFiles.length === 0) {\n throw new Error('No output files generated from bundling');\n }\n\n const disallowedImports: string[] = [];\n if (result.metafile) {\n const inputs = result.metafile.inputs;\n for (const [, inputData] of Object.entries(inputs)) {\n const imports =\n (inputData as { imports?: Array<{ path: string; external?: boolean }> }).imports || [];\n for (const imp of imports) {\n if (\n imp.external &&\n !imp.path.startsWith('.') &&\n !imp.path.startsWith('/') &&\n !isAllowedImport(imp.path, allowlist)\n ) {\n disallowedImports.push(imp.path);\n }\n }\n }\n }\n\n if (disallowedImports.length > 0) {\n throw new Error(\n `Disallowed imports detected. Only imports matching the allowlist are permitted:\\n Allowlist: ${allowlist.join(', ')}\\n Disallowed imports: ${disallowedImports.join(', ')}\\n\\nOnly @prisma-next/* packages are allowed in contract files.`,\n );\n }\n\n const bundleContent = result.outputFiles[0]?.text;\n if (bundleContent === undefined) {\n throw new Error('Bundle content is undefined');\n }\n writeFileSync(tempFile, bundleContent, 'utf-8');\n\n const module = (await import(/* @vite-ignore */ pathToFileURL(tempFile).href)) as {\n default?: unknown;\n contract?: unknown;\n };\n unlinkSync(tempFile);\n\n let contract: unknown;\n\n if (module.default !== undefined) {\n contract = module.default;\n } else if (module.contract !== undefined) {\n contract = module.contract;\n } else {\n throw new Error(\n `Contract file must export a contract as default export or named export 'contract'. Found exports: ${Object.keys(module as Record<string, unknown>).join(', ') || 'none'}`,\n );\n }\n\n if (typeof contract !== 'object' || contract === null) {\n throw new Error(`Contract export must be an object, got ${typeof contract}`);\n }\n\n validatePurity(contract);\n\n return contract as Contract;\n } catch (error) {\n try {\n if (tempFile) {\n unlinkSync(tempFile);\n }\n } catch {\n // Ignore cleanup errors\n }\n\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Failed to load contract from ${entryPath}: ${String(error)}`);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["value","disallowedImports: string[]","contract: unknown"],"sources":["../../src/load-ts-contract.ts"],"sourcesContent":["import { existsSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { pathToFileURL } from 'node:url';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { Plugin } from 'esbuild';\nimport { build } from 'esbuild';\nimport { join } from 'pathe';\n\nexport interface LoadTsContractOptions {\n readonly allowlist?: ReadonlyArray<string>;\n}\n\nconst DEFAULT_ALLOWLIST = ['@prisma-next/*', 'node:crypto'];\n\nfunction isAllowedImport(importPath: string, allowlist: ReadonlyArray<string>): boolean {\n for (const pattern of allowlist) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n if (importPath === prefix || importPath.startsWith(`${prefix}/`)) {\n return true;\n }\n } else if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1);\n if (importPath.startsWith(prefix)) {\n return true;\n }\n } else if (importPath === pattern) {\n return true;\n }\n }\n return false;\n}\n\nfunction validatePurity(value: unknown): void {\n if (typeof value !== 'object' || value === null) {\n return;\n }\n\n const path = new WeakSet();\n\n function check(value: unknown): void {\n if (value === null || typeof value !== 'object') {\n return;\n }\n\n if (path.has(value)) {\n throw new Error('Contract export contains circular references');\n }\n path.add(value);\n\n try {\n for (const key in value) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor && (descriptor.get || descriptor.set)) {\n throw new Error(`Contract export contains getter/setter at key \"${key}\"`);\n }\n if (descriptor && typeof descriptor.value === 'function') {\n throw new Error(`Contract export contains function at key \"${key}\"`);\n }\n check((value as Record<string, unknown>)[key]);\n }\n } finally {\n path.delete(value);\n }\n }\n\n try {\n check(value);\n JSON.stringify(value);\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('getter') || error.message.includes('circular')) {\n throw error;\n }\n throw new Error(`Contract export is not JSON-serializable: ${error.message}`);\n }\n throw new Error('Contract export is not JSON-serializable');\n }\n}\n\nfunction createImportAllowlistPlugin(allowlist: ReadonlyArray<string>, entryPath: string): Plugin {\n return {\n name: 'import-allowlist',\n setup(build) {\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind === 'entry-point') {\n return undefined;\n }\n if (args.path.startsWith('.') || args.path.startsWith('/')) {\n return undefined;\n }\n const isFromEntryPoint = args.importer === entryPath || args.importer === '<stdin>';\n if (isFromEntryPoint && !isAllowedImport(args.path, allowlist)) {\n return {\n path: args.path,\n external: true,\n };\n }\n return undefined;\n });\n },\n };\n}\n\n/**\n * Loads a contract from a TypeScript file and returns it as Contract.\n *\n * **Responsibility: Parsing Only**\n * This function loads and parses a TypeScript contract file. It does NOT normalize the contract.\n * The contract should already be normalized if it was built using the contract builder.\n *\n * Normalization must happen in the contract builder when the contract is created.\n * This function only validates that the contract is JSON-serializable and returns it as-is.\n *\n * @param entryPath - Path to the TypeScript contract file\n * @param options - Optional configuration (import allowlist)\n * @returns The contract as Contract (should already be normalized)\n * @throws Error if the contract cannot be loaded or is not JSON-serializable\n */\nexport async function loadContractFromTs(\n entryPath: string,\n options?: LoadTsContractOptions,\n): Promise<Contract> {\n const allowlist = options?.allowlist ?? DEFAULT_ALLOWLIST;\n\n if (!existsSync(entryPath)) {\n throw new Error(`Contract file not found: ${entryPath}`);\n }\n\n const tempFile = join(\n tmpdir(),\n `prisma-next-contract-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`,\n );\n\n try {\n const result = await build({\n entryPoints: [entryPath],\n bundle: true,\n format: 'esm',\n platform: 'node',\n target: 'es2022',\n outfile: tempFile,\n write: false,\n metafile: true,\n plugins: [createImportAllowlistPlugin(allowlist, entryPath)],\n logLevel: 'error',\n });\n\n if (result.errors.length > 0) {\n const errorMessages = result.errors.map((e: { text: string }) => e.text).join('\\n');\n throw new Error(`Failed to bundle contract file: ${errorMessages}`);\n }\n\n if (!result.outputFiles || result.outputFiles.length === 0) {\n throw new Error('No output files generated from bundling');\n }\n\n const disallowedImports: string[] = [];\n if (result.metafile) {\n const inputs = result.metafile.inputs;\n for (const [, inputData] of Object.entries(inputs)) {\n const imports =\n (inputData as { imports?: Array<{ path: string; external?: boolean }> }).imports || [];\n for (const imp of imports) {\n if (\n imp.external &&\n !imp.path.startsWith('.') &&\n !imp.path.startsWith('/') &&\n !isAllowedImport(imp.path, allowlist)\n ) {\n disallowedImports.push(imp.path);\n }\n }\n }\n }\n\n if (disallowedImports.length > 0) {\n throw new Error(\n `Disallowed imports detected. Only imports matching the allowlist are permitted:\\n Allowlist: ${allowlist.join(', ')}\\n Disallowed imports: ${disallowedImports.join(', ')}\\n\\nOnly @prisma-next/* packages are allowed in contract files.`,\n );\n }\n\n const bundleContent = result.outputFiles[0]?.text;\n if (bundleContent === undefined) {\n throw new Error('Bundle content is undefined');\n }\n writeFileSync(tempFile, bundleContent, 'utf-8');\n\n const module = (await import(/* @vite-ignore */ pathToFileURL(tempFile).href)) as {\n default?: unknown;\n contract?: unknown;\n };\n unlinkSync(tempFile);\n\n let contract: unknown;\n\n if (module.default !== undefined) {\n contract = module.default;\n } else if (module.contract !== undefined) {\n contract = module.contract;\n } else {\n throw new Error(\n `Contract file must export a contract as default export or named export 'contract'. Found exports: ${Object.keys(module as Record<string, unknown>).join(', ') || 'none'}`,\n );\n }\n\n if (typeof contract !== 'object' || contract === null) {\n throw new Error(`Contract export must be an object, got ${typeof contract}`);\n }\n\n validatePurity(contract);\n\n return contract as Contract;\n } catch (error) {\n try {\n if (tempFile) {\n unlinkSync(tempFile);\n }\n } catch {\n // Ignore cleanup errors\n }\n\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Failed to load contract from ${entryPath}: ${String(error)}`);\n }\n}\n"],"mappings":"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"}
|
|
@@ -382,7 +382,7 @@ async function runInit(baseDir, options) {
|
|
|
382
382
|
"",
|
|
383
383
|
" 1. Install dependencies:",
|
|
384
384
|
` ${pm} ${formatAddArgs(pm, [pkg, "dotenv"]).join(" ")}`,
|
|
385
|
-
` ${pm} ${formatAddDevArgs(pm, ["
|
|
385
|
+
` ${pm} ${formatAddDevArgs(pm, ["prisma-next"]).join(" ")}`,
|
|
386
386
|
"",
|
|
387
387
|
" 2. Emit the contract:",
|
|
388
388
|
` ${emitCommand}`
|
|
@@ -392,11 +392,11 @@ async function runInit(baseDir, options) {
|
|
|
392
392
|
const spinner = ui.spinner();
|
|
393
393
|
let installSucceeded = false;
|
|
394
394
|
const exec = promisify(execFile);
|
|
395
|
-
spinner.start(`Installing ${pkg}, dotenv, and
|
|
395
|
+
spinner.start(`Installing ${pkg}, dotenv, and prisma-next...`);
|
|
396
396
|
try {
|
|
397
397
|
await exec(pm, formatAddArgs(pm, [pkg, "dotenv"]), { cwd: baseDir });
|
|
398
|
-
await exec(pm, formatAddDevArgs(pm, ["
|
|
399
|
-
spinner.stop(`Installed ${pkg}, dotenv, and
|
|
398
|
+
await exec(pm, formatAddDevArgs(pm, ["prisma-next"]), { cwd: baseDir });
|
|
399
|
+
spinner.stop(`Installed ${pkg}, dotenv, and prisma-next`);
|
|
400
400
|
installSucceeded = true;
|
|
401
401
|
} catch (err) {
|
|
402
402
|
spinner.stop("Installation failed");
|
|
@@ -407,13 +407,13 @@ async function runInit(baseDir, options) {
|
|
|
407
407
|
"",
|
|
408
408
|
"Run manually:",
|
|
409
409
|
` ${pm} ${formatAddArgs(pm, [pkg, "dotenv"]).join(" ")}`,
|
|
410
|
-
` ${pm} ${formatAddDevArgs(pm, ["
|
|
410
|
+
` ${pm} ${formatAddDevArgs(pm, ["prisma-next"]).join(" ")}`
|
|
411
411
|
].join("\n"));
|
|
412
412
|
}
|
|
413
413
|
if (installSucceeded) {
|
|
414
414
|
spinner.start("Emitting contract...");
|
|
415
415
|
try {
|
|
416
|
-
const { executeContractEmit } = await import("./contract-emit-
|
|
416
|
+
const { executeContractEmit } = await import("./contract-emit-CGpb33vs.mjs");
|
|
417
417
|
await executeContractEmit({ configPath: join(baseDir, "prisma-next.config.ts") });
|
|
418
418
|
spinner.stop("Contract emitted");
|
|
419
419
|
} catch {
|
|
@@ -427,4 +427,4 @@ async function runInit(baseDir, options) {
|
|
|
427
427
|
|
|
428
428
|
//#endregion
|
|
429
429
|
export { runInit };
|
|
430
|
-
//# sourceMappingURL=init-
|
|
430
|
+
//# sourceMappingURL=init-Dx5uJ-6Q.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-6Pvm_esG.mjs","names":["KNOWN: ReadonlySet<string>","variables","vars: TemplateVars","vars: TemplateVars","REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean>","files: FileEntry[]"],"sources":["../src/commands/init/detect-package-manager.ts","../src/commands/init/templates/render.ts","../src/commands/init/templates/agent-skill.ts","../src/commands/init/templates/code-templates.ts","../src/commands/init/templates/quick-reference.ts","../src/commands/init/templates/tsconfig.ts","../src/commands/init/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { detect } from 'package-manager-detector/detect';\nimport { join } from 'pathe';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun' | 'deno';\n\nconst KNOWN: ReadonlySet<string> = new Set<PackageManager>(['pnpm', 'npm', 'yarn', 'bun', 'deno']);\n\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n const result = await detect({ cwd });\n if (result && KNOWN.has(result.name)) {\n return result.name as PackageManager;\n }\n return 'npm';\n}\n\nexport function hasProjectManifest(cwd: string): boolean {\n return (\n existsSync(join(cwd, 'package.json')) ||\n existsSync(join(cwd, 'deno.json')) ||\n existsSync(join(cwd, 'deno.jsonc'))\n );\n}\n\nexport function formatRunCommand(pm: PackageManager, bin: string, args: string): string {\n if (pm === 'npm') {\n return `npx ${bin} ${args}`;\n }\n if (pm === 'deno') {\n return `deno run npm:${bin} ${args}`;\n }\n return `${pm} ${bin} ${args}`;\n}\n\nexport function formatAddArgs(pm: PackageManager, packages: string[]): string[] {\n if (pm === 'deno') {\n return ['add', ...packages.map((p) => `npm:${p}`)];\n }\n return ['add', ...packages];\n}\n\nexport function formatAddDevArgs(pm: PackageManager, packages: string[]): string[] {\n if (pm === 'deno') {\n return ['add', '--dev', ...packages.map((p) => `npm:${p}`)];\n }\n return ['add', '-D', ...packages];\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'pathe';\n\nexport function renderTemplate(\n templateFile: string,\n variableNames: readonly string[],\n vars: Record<string, string>,\n): string {\n const templatePath = join(import.meta.dirname, templateFile);\n const raw = readFileSync(templatePath, 'utf-8');\n let result = raw;\n for (const key of variableNames) {\n const value = vars[key];\n if (value === undefined) {\n throw new Error(`Template variable '${key}' is not defined`);\n }\n result = result.replaceAll(`{{${key}}}`, value);\n }\n return result;\n}\n","import { dirname } from 'pathe';\nimport type { TargetId } from './code-templates';\nimport { renderTemplate } from './render';\n\nexport const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;\n\ntype TemplateVars = Record<(typeof variables)[number], string>;\n\nexport function agentSkillMd(target: TargetId, schemaPath: string, pkgRun: string): string {\n const schemaDir = dirname(schemaPath);\n const vars: TemplateVars = {\n schemaPath,\n schemaDir,\n dbImportPath: `./${schemaDir}/db`,\n pkgRun,\n };\n const templateFile = `agent-skill-${target}.md`;\n return renderTemplate(templateFile, variables, vars);\n}\n","export type TargetId = 'postgres' | 'mongo';\nexport type AuthoringId = 'psl' | 'typescript';\n\nexport function targetPackageName(target: TargetId): string {\n return target === 'postgres' ? '@prisma-next/postgres' : '@prisma-next/mongo';\n}\n\nexport function targetLabel(target: TargetId): string {\n return target === 'postgres' ? 'PostgreSQL' : 'MongoDB';\n}\n\nexport function defaultSchemaPath(authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return 'prisma/contract.ts';\n }\n return 'prisma/contract.prisma';\n}\n\nexport function starterSchema(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? starterSchemaTsMongo() : starterSchemaTsPostgres();\n }\n return target === 'mongo' ? starterSchemaPslMongo() : starterSchemaPslPostgres();\n}\n\nfunction starterSchemaPslPostgres(): string {\n return `model User {\n id Int @id @default(autoincrement())\n email String @unique\n name String?\n posts Post[]\n createdAt DateTime @default(now())\n}\n\nmodel Post {\n id Int @id @default(autoincrement())\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId Int\n createdAt DateTime @default(now())\n}\n`;\n}\n\nfunction starterSchemaPslMongo(): string {\n return `model User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n name String?\n posts Post[]\n @@map(\"users\")\n}\n\nmodel Post {\n id ObjectId @id @map(\"_id\")\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId ObjectId\n @@map(\"posts\")\n}\n`;\n}\n\nfunction starterSchemaTsPostgres(): string {\n return `import sqlFamily from '@prisma-next/family-sql/pack';\nimport { defineContract } from '@prisma-next/sql-contract-ts/contract-builder';\nimport postgresPack from '@prisma-next/target-postgres/pack';\n\nexport const contract = defineContract(\n { family: sqlFamily, target: postgresPack },\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n name: field.text().optional(),\n createdAt: field.createdAt(),\n },\n }).relations({\n posts: rel.hasMany('Post', { by: 'authorId' }),\n }),\n\n Post: model('Post', {\n fields: {\n id: field.id.uuidv7(),\n title: field.text(),\n content: field.text().optional(),\n authorId: field.uuid(),\n createdAt: field.createdAt(),\n },\n }).relations({\n author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),\n }),\n },\n }),\n);\n`;\n}\n\nfunction starterSchemaTsMongo(): string {\n return `import mongoFamily from '@prisma-next/family-mongo/pack';\nimport { defineContract, field, model, rel } from '@prisma-next/mongo-contract-ts/contract-builder';\nimport mongoTarget from '@prisma-next/target-mongo/pack';\n\nconst User = model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n name: field.string().optional(),\n },\n});\n\nconst Post = model('Post', {\n collection: 'posts',\n fields: {\n _id: field.objectId(),\n title: field.string(),\n content: field.string().optional(),\n authorId: field.objectId(),\n },\n relations: {\n author: rel.belongsTo(User, { from: 'authorId', to: User.ref('_id') }),\n },\n});\n\nexport const contract = defineContract({\n family: mongoFamily,\n target: mongoTarget,\n models: { User, Post },\n});\n`;\n}\n\nexport function configFile(target: TargetId, contractPath: string): string {\n const pkg = targetPackageName(target);\n return `import 'dotenv/config';\nimport { defineConfig } from '${pkg}/config';\n\nexport default defineConfig({\n contract: ${JSON.stringify(contractPath)},\n db: {\n connection: process.env['DATABASE_URL']!,\n },\n});\n`;\n}\n\nexport function dbFile(target: TargetId): string {\n if (target === 'postgres') {\n return `import postgres from '@prisma-next/postgres/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = postgres<Contract>({ contractJson });\n`;\n }\n\n return `import mongo from '@prisma-next/mongo/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = mongo<Contract>({ contractJson });\n`;\n}\n","import { dirname } from 'pathe';\nimport type { TargetId } from './code-templates';\nimport { renderTemplate } from './render';\n\nexport const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;\n\ntype TemplateVars = Record<(typeof variables)[number], string>;\n\nexport function quickReferenceMd(target: TargetId, schemaPath: string, pkgRun: string): string {\n const schemaDir = dirname(schemaPath);\n const vars: TemplateVars = {\n schemaPath,\n schemaDir,\n dbImportPath: `./${schemaDir}/db`,\n pkgRun,\n };\n const templateFile = `quick-reference-${target}.md`;\n return renderTemplate(templateFile, variables, vars);\n}\n","export const REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean> = {\n module: 'preserve',\n moduleResolution: 'bundler',\n resolveJsonModule: true,\n};\n\nexport function defaultTsConfig(): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n ...REQUIRED_COMPILER_OPTIONS,\n strict: true,\n skipLibCheck: true,\n esModuleInterop: true,\n outDir: 'dist',\n },\n include: ['**/*.ts'],\n },\n null,\n 2,\n );\n}\n\nexport function mergeTsConfig(existing: string): string {\n const config = JSON.parse(existing) as Record<string, unknown>;\n const compilerOptions = (config['compilerOptions'] ?? {}) as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) {\n compilerOptions[key] = value;\n }\n\n config['compilerOptions'] = compilerOptions;\n return JSON.stringify(config, null, 2);\n}\n","import { execFile } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { promisify } from 'node:util';\nimport * as clack from '@clack/prompts';\nimport { dirname, extname, isAbsolute, join, normalize } from 'pathe';\nimport { TerminalUI } from '../../utils/terminal-ui';\nimport {\n detectPackageManager,\n formatAddArgs,\n formatAddDevArgs,\n formatRunCommand,\n hasProjectManifest,\n} from './detect-package-manager';\nimport { agentSkillMd } from './templates/agent-skill';\nimport {\n type AuthoringId,\n configFile,\n dbFile,\n defaultSchemaPath,\n starterSchema,\n type TargetId,\n targetPackageName,\n} from './templates/code-templates';\nimport { quickReferenceMd } from './templates/quick-reference';\nimport { defaultTsConfig, mergeTsConfig } from './templates/tsconfig';\n\nexport interface InitOptions {\n readonly noInstall?: boolean;\n}\n\ninterface FileEntry {\n readonly path: string;\n readonly content: string;\n}\n\nexport async function runInit(baseDir: string, options: InitOptions): Promise<void> {\n const ui = new TerminalUI();\n\n clack.intro('prisma-next init', { output: process.stderr });\n\n if (!hasProjectManifest(baseDir)) {\n ui.error(\n 'No package.json or deno.json found. Initialize your project first (e.g. npm init or deno init), then re-run prisma-next init.',\n );\n process.exit(1);\n }\n\n const pm = await detectPackageManager(baseDir);\n const pkgRun = formatRunCommand(pm, 'prisma-next', '').trimEnd();\n\n if (existsSync(join(baseDir, 'prisma-next.config.ts'))) {\n const reinit = await clack.confirm({\n message:\n 'This project is already initialized. Re-initialize? This will overwrite all generated files.',\n initialValue: false,\n output: process.stderr,\n });\n if (clack.isCancel(reinit) || !reinit) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n }\n\n const targetResult = await clack.select({\n message: 'What database are you using?',\n options: [\n { value: 'postgres' as TargetId, label: 'PostgreSQL' },\n { value: 'mongo' as TargetId, label: 'MongoDB' },\n ],\n output: process.stderr,\n });\n if (clack.isCancel(targetResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const target = targetResult as TargetId;\n\n const authoringResult = await clack.select({\n message: 'How do you want to write your schema?',\n options: [\n { value: 'psl' as AuthoringId, label: 'Prisma Schema Language (.prisma)' },\n { value: 'typescript' as AuthoringId, label: 'TypeScript (.ts)' },\n ],\n output: process.stderr,\n });\n if (clack.isCancel(authoringResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const authoring = authoringResult as AuthoringId;\n\n const schemaPathResult = await clack.text({\n message: 'Where should the schema file go?',\n initialValue: defaultSchemaPath(authoring),\n validate(value = '') {\n const trimmed = value.trim();\n if (trimmed.length === 0) return 'Path cannot be empty';\n if (trimmed.endsWith('/') || trimmed.endsWith('\\\\'))\n return 'Path must be a file, not a directory';\n if (!extname(trimmed)) return 'Path must include a file extension (e.g. .prisma or .ts)';\n return undefined;\n },\n output: process.stderr,\n });\n if (clack.isCancel(schemaPathResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const schemaPath = normalize((schemaPathResult as string).trim());\n\n const schemaDir = dirname(schemaPath);\n const configPath = isAbsolute(schemaPath) ? schemaPath : `./${schemaPath}`;\n\n const files: FileEntry[] = [\n { path: schemaPath, content: starterSchema(target, authoring) },\n { path: 'prisma-next.config.ts', content: configFile(target, configPath) },\n { path: join(schemaDir, 'db.ts'), content: dbFile(target) },\n { path: 'prisma-next.md', content: quickReferenceMd(target, schemaPath, pkgRun) },\n {\n path: '.agents/skills/prisma-next/SKILL.md',\n content: agentSkillMd(target, schemaPath, pkgRun),\n },\n ];\n\n for (const file of files) {\n const fullPath = join(baseDir, file.path);\n mkdirSync(dirname(fullPath), { recursive: true });\n writeFileSync(fullPath, file.content, 'utf-8');\n }\n\n const tsconfigPath = join(baseDir, 'tsconfig.json');\n if (existsSync(tsconfigPath)) {\n const existing = readFileSync(tsconfigPath, 'utf-8');\n writeFileSync(tsconfigPath, mergeTsConfig(existing), 'utf-8');\n ui.log('Updated tsconfig.json with required compiler options.');\n } else {\n writeFileSync(tsconfigPath, defaultTsConfig(), 'utf-8');\n }\n\n const emitCommand = formatRunCommand(pm, 'prisma-next', 'contract emit');\n\n if (options.noInstall) {\n const pkg = targetPackageName(target);\n ui.note(\n [\n 'Run the following commands to complete setup:',\n '',\n ' 1. Install dependencies:',\n ` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,\n ` ${pm} ${formatAddDevArgs(pm, ['@prisma-next/cli']).join(' ')}`,\n '',\n ' 2. Emit the contract:',\n ` ${emitCommand}`,\n ].join('\\n'),\n 'Manual steps',\n );\n } else {\n const pkg = targetPackageName(target);\n const spinner = ui.spinner();\n let installSucceeded = false;\n\n const exec = promisify(execFile);\n\n spinner.start(`Installing ${pkg}, dotenv, and @prisma-next/cli...`);\n try {\n await exec(pm, formatAddArgs(pm, [pkg, 'dotenv']), { cwd: baseDir });\n await exec(pm, formatAddDevArgs(pm, ['@prisma-next/cli']), { cwd: baseDir });\n spinner.stop(`Installed ${pkg}, dotenv, and @prisma-next/cli`);\n installSucceeded = true;\n } catch (err) {\n spinner.stop('Installation failed');\n const stderr =\n err instanceof Error && 'stderr' in err ? (err as { stderr: string }).stderr : '';\n ui.warn(\n [\n 'Could not install dependencies automatically.',\n ...(stderr ? [` ${stderr.trim()}`] : []),\n '',\n 'Run manually:',\n ` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,\n ` ${pm} ${formatAddDevArgs(pm, ['@prisma-next/cli']).join(' ')}`,\n ].join('\\n'),\n );\n }\n\n if (installSucceeded) {\n spinner.start('Emitting contract...');\n try {\n const { executeContractEmit } = await import('../../control-api/operations/contract-emit');\n const configFilePath = join(baseDir, 'prisma-next.config.ts');\n await executeContractEmit({ configPath: configFilePath });\n spinner.stop('Contract emitted');\n } catch {\n spinner.stop('Contract emission failed');\n ui.warn(\n ['Could not emit contract automatically. Run manually:', ` ${emitCommand}`].join('\\n'),\n );\n }\n }\n }\n\n clack.outro('Done! Open prisma-next.md to get started.', { output: process.stderr });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init-Dx5uJ-6Q.mjs","names":["KNOWN: ReadonlySet<string>","variables","vars: TemplateVars","vars: TemplateVars","REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean>","files: FileEntry[]"],"sources":["../src/commands/init/detect-package-manager.ts","../src/commands/init/templates/render.ts","../src/commands/init/templates/agent-skill.ts","../src/commands/init/templates/code-templates.ts","../src/commands/init/templates/quick-reference.ts","../src/commands/init/templates/tsconfig.ts","../src/commands/init/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { detect } from 'package-manager-detector/detect';\nimport { join } from 'pathe';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun' | 'deno';\n\nconst KNOWN: ReadonlySet<string> = new Set<PackageManager>(['pnpm', 'npm', 'yarn', 'bun', 'deno']);\n\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n const result = await detect({ cwd });\n if (result && KNOWN.has(result.name)) {\n return result.name as PackageManager;\n }\n return 'npm';\n}\n\nexport function hasProjectManifest(cwd: string): boolean {\n return (\n existsSync(join(cwd, 'package.json')) ||\n existsSync(join(cwd, 'deno.json')) ||\n existsSync(join(cwd, 'deno.jsonc'))\n );\n}\n\nexport function formatRunCommand(pm: PackageManager, bin: string, args: string): string {\n if (pm === 'npm') {\n return `npx ${bin} ${args}`;\n }\n if (pm === 'deno') {\n return `deno run npm:${bin} ${args}`;\n }\n return `${pm} ${bin} ${args}`;\n}\n\nexport function formatAddArgs(pm: PackageManager, packages: string[]): string[] {\n if (pm === 'deno') {\n return ['add', ...packages.map((p) => `npm:${p}`)];\n }\n return ['add', ...packages];\n}\n\nexport function formatAddDevArgs(pm: PackageManager, packages: string[]): string[] {\n if (pm === 'deno') {\n return ['add', '--dev', ...packages.map((p) => `npm:${p}`)];\n }\n return ['add', '-D', ...packages];\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'pathe';\n\nexport function renderTemplate(\n templateFile: string,\n variableNames: readonly string[],\n vars: Record<string, string>,\n): string {\n const templatePath = join(import.meta.dirname, templateFile);\n const raw = readFileSync(templatePath, 'utf-8');\n let result = raw;\n for (const key of variableNames) {\n const value = vars[key];\n if (value === undefined) {\n throw new Error(`Template variable '${key}' is not defined`);\n }\n result = result.replaceAll(`{{${key}}}`, value);\n }\n return result;\n}\n","import { dirname } from 'pathe';\nimport type { TargetId } from './code-templates';\nimport { renderTemplate } from './render';\n\nexport const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;\n\ntype TemplateVars = Record<(typeof variables)[number], string>;\n\nexport function agentSkillMd(target: TargetId, schemaPath: string, pkgRun: string): string {\n const schemaDir = dirname(schemaPath);\n const vars: TemplateVars = {\n schemaPath,\n schemaDir,\n dbImportPath: `./${schemaDir}/db`,\n pkgRun,\n };\n const templateFile = `agent-skill-${target}.md`;\n return renderTemplate(templateFile, variables, vars);\n}\n","export type TargetId = 'postgres' | 'mongo';\nexport type AuthoringId = 'psl' | 'typescript';\n\nexport function targetPackageName(target: TargetId): string {\n return target === 'postgres' ? '@prisma-next/postgres' : '@prisma-next/mongo';\n}\n\nexport function targetLabel(target: TargetId): string {\n return target === 'postgres' ? 'PostgreSQL' : 'MongoDB';\n}\n\nexport function defaultSchemaPath(authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return 'prisma/contract.ts';\n }\n return 'prisma/contract.prisma';\n}\n\nexport function starterSchema(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? starterSchemaTsMongo() : starterSchemaTsPostgres();\n }\n return target === 'mongo' ? starterSchemaPslMongo() : starterSchemaPslPostgres();\n}\n\nfunction starterSchemaPslPostgres(): string {\n return `model User {\n id Int @id @default(autoincrement())\n email String @unique\n name String?\n posts Post[]\n createdAt DateTime @default(now())\n}\n\nmodel Post {\n id Int @id @default(autoincrement())\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId Int\n createdAt DateTime @default(now())\n}\n`;\n}\n\nfunction starterSchemaPslMongo(): string {\n return `model User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n name String?\n posts Post[]\n @@map(\"users\")\n}\n\nmodel Post {\n id ObjectId @id @map(\"_id\")\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId ObjectId\n @@map(\"posts\")\n}\n`;\n}\n\nfunction starterSchemaTsPostgres(): string {\n return `import sqlFamily from '@prisma-next/family-sql/pack';\nimport { defineContract } from '@prisma-next/sql-contract-ts/contract-builder';\nimport postgresPack from '@prisma-next/target-postgres/pack';\n\nexport const contract = defineContract(\n { family: sqlFamily, target: postgresPack },\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n name: field.text().optional(),\n createdAt: field.createdAt(),\n },\n }).relations({\n posts: rel.hasMany('Post', { by: 'authorId' }),\n }),\n\n Post: model('Post', {\n fields: {\n id: field.id.uuidv7(),\n title: field.text(),\n content: field.text().optional(),\n authorId: field.uuid(),\n createdAt: field.createdAt(),\n },\n }).relations({\n author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),\n }),\n },\n }),\n);\n`;\n}\n\nfunction starterSchemaTsMongo(): string {\n return `import mongoFamily from '@prisma-next/family-mongo/pack';\nimport { defineContract, field, model, rel } from '@prisma-next/mongo-contract-ts/contract-builder';\nimport mongoTarget from '@prisma-next/target-mongo/pack';\n\nconst User = model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n name: field.string().optional(),\n },\n});\n\nconst Post = model('Post', {\n collection: 'posts',\n fields: {\n _id: field.objectId(),\n title: field.string(),\n content: field.string().optional(),\n authorId: field.objectId(),\n },\n relations: {\n author: rel.belongsTo(User, { from: 'authorId', to: User.ref('_id') }),\n },\n});\n\nexport const contract = defineContract({\n family: mongoFamily,\n target: mongoTarget,\n models: { User, Post },\n});\n`;\n}\n\nexport function configFile(target: TargetId, contractPath: string): string {\n const pkg = targetPackageName(target);\n return `import 'dotenv/config';\nimport { defineConfig } from '${pkg}/config';\n\nexport default defineConfig({\n contract: ${JSON.stringify(contractPath)},\n db: {\n connection: process.env['DATABASE_URL']!,\n },\n});\n`;\n}\n\nexport function dbFile(target: TargetId): string {\n if (target === 'postgres') {\n return `import postgres from '@prisma-next/postgres/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = postgres<Contract>({ contractJson });\n`;\n }\n\n return `import mongo from '@prisma-next/mongo/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = mongo<Contract>({ contractJson });\n`;\n}\n","import { dirname } from 'pathe';\nimport type { TargetId } from './code-templates';\nimport { renderTemplate } from './render';\n\nexport const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;\n\ntype TemplateVars = Record<(typeof variables)[number], string>;\n\nexport function quickReferenceMd(target: TargetId, schemaPath: string, pkgRun: string): string {\n const schemaDir = dirname(schemaPath);\n const vars: TemplateVars = {\n schemaPath,\n schemaDir,\n dbImportPath: `./${schemaDir}/db`,\n pkgRun,\n };\n const templateFile = `quick-reference-${target}.md`;\n return renderTemplate(templateFile, variables, vars);\n}\n","export const REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean> = {\n module: 'preserve',\n moduleResolution: 'bundler',\n resolveJsonModule: true,\n};\n\nexport function defaultTsConfig(): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n ...REQUIRED_COMPILER_OPTIONS,\n strict: true,\n skipLibCheck: true,\n esModuleInterop: true,\n outDir: 'dist',\n },\n include: ['**/*.ts'],\n },\n null,\n 2,\n );\n}\n\nexport function mergeTsConfig(existing: string): string {\n const config = JSON.parse(existing) as Record<string, unknown>;\n const compilerOptions = (config['compilerOptions'] ?? {}) as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) {\n compilerOptions[key] = value;\n }\n\n config['compilerOptions'] = compilerOptions;\n return JSON.stringify(config, null, 2);\n}\n","import { execFile } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { promisify } from 'node:util';\nimport * as clack from '@clack/prompts';\nimport { dirname, extname, isAbsolute, join, normalize } from 'pathe';\nimport { TerminalUI } from '../../utils/terminal-ui';\nimport {\n detectPackageManager,\n formatAddArgs,\n formatAddDevArgs,\n formatRunCommand,\n hasProjectManifest,\n} from './detect-package-manager';\nimport { agentSkillMd } from './templates/agent-skill';\nimport {\n type AuthoringId,\n configFile,\n dbFile,\n defaultSchemaPath,\n starterSchema,\n type TargetId,\n targetPackageName,\n} from './templates/code-templates';\nimport { quickReferenceMd } from './templates/quick-reference';\nimport { defaultTsConfig, mergeTsConfig } from './templates/tsconfig';\n\nexport interface InitOptions {\n readonly noInstall?: boolean;\n}\n\ninterface FileEntry {\n readonly path: string;\n readonly content: string;\n}\n\nexport async function runInit(baseDir: string, options: InitOptions): Promise<void> {\n const ui = new TerminalUI();\n\n clack.intro('prisma-next init', { output: process.stderr });\n\n if (!hasProjectManifest(baseDir)) {\n ui.error(\n 'No package.json or deno.json found. Initialize your project first (e.g. npm init or deno init), then re-run prisma-next init.',\n );\n process.exit(1);\n }\n\n const pm = await detectPackageManager(baseDir);\n const pkgRun = formatRunCommand(pm, 'prisma-next', '').trimEnd();\n\n if (existsSync(join(baseDir, 'prisma-next.config.ts'))) {\n const reinit = await clack.confirm({\n message:\n 'This project is already initialized. Re-initialize? This will overwrite all generated files.',\n initialValue: false,\n output: process.stderr,\n });\n if (clack.isCancel(reinit) || !reinit) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n }\n\n const targetResult = await clack.select({\n message: 'What database are you using?',\n options: [\n { value: 'postgres' as TargetId, label: 'PostgreSQL' },\n { value: 'mongo' as TargetId, label: 'MongoDB' },\n ],\n output: process.stderr,\n });\n if (clack.isCancel(targetResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const target = targetResult as TargetId;\n\n const authoringResult = await clack.select({\n message: 'How do you want to write your schema?',\n options: [\n { value: 'psl' as AuthoringId, label: 'Prisma Schema Language (.prisma)' },\n { value: 'typescript' as AuthoringId, label: 'TypeScript (.ts)' },\n ],\n output: process.stderr,\n });\n if (clack.isCancel(authoringResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const authoring = authoringResult as AuthoringId;\n\n const schemaPathResult = await clack.text({\n message: 'Where should the schema file go?',\n initialValue: defaultSchemaPath(authoring),\n validate(value = '') {\n const trimmed = value.trim();\n if (trimmed.length === 0) return 'Path cannot be empty';\n if (trimmed.endsWith('/') || trimmed.endsWith('\\\\'))\n return 'Path must be a file, not a directory';\n if (!extname(trimmed)) return 'Path must include a file extension (e.g. .prisma or .ts)';\n return undefined;\n },\n output: process.stderr,\n });\n if (clack.isCancel(schemaPathResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const schemaPath = normalize((schemaPathResult as string).trim());\n\n const schemaDir = dirname(schemaPath);\n const configPath = isAbsolute(schemaPath) ? schemaPath : `./${schemaPath}`;\n\n const files: FileEntry[] = [\n { path: schemaPath, content: starterSchema(target, authoring) },\n { path: 'prisma-next.config.ts', content: configFile(target, configPath) },\n { path: join(schemaDir, 'db.ts'), content: dbFile(target) },\n { path: 'prisma-next.md', content: quickReferenceMd(target, schemaPath, pkgRun) },\n {\n path: '.agents/skills/prisma-next/SKILL.md',\n content: agentSkillMd(target, schemaPath, pkgRun),\n },\n ];\n\n for (const file of files) {\n const fullPath = join(baseDir, file.path);\n mkdirSync(dirname(fullPath), { recursive: true });\n writeFileSync(fullPath, file.content, 'utf-8');\n }\n\n const tsconfigPath = join(baseDir, 'tsconfig.json');\n if (existsSync(tsconfigPath)) {\n const existing = readFileSync(tsconfigPath, 'utf-8');\n writeFileSync(tsconfigPath, mergeTsConfig(existing), 'utf-8');\n ui.log('Updated tsconfig.json with required compiler options.');\n } else {\n writeFileSync(tsconfigPath, defaultTsConfig(), 'utf-8');\n }\n\n const emitCommand = formatRunCommand(pm, 'prisma-next', 'contract emit');\n\n if (options.noInstall) {\n const pkg = targetPackageName(target);\n ui.note(\n [\n 'Run the following commands to complete setup:',\n '',\n ' 1. Install dependencies:',\n ` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,\n ` ${pm} ${formatAddDevArgs(pm, ['prisma-next']).join(' ')}`,\n '',\n ' 2. Emit the contract:',\n ` ${emitCommand}`,\n ].join('\\n'),\n 'Manual steps',\n );\n } else {\n const pkg = targetPackageName(target);\n const spinner = ui.spinner();\n let installSucceeded = false;\n\n const exec = promisify(execFile);\n\n spinner.start(`Installing ${pkg}, dotenv, and prisma-next...`);\n try {\n await exec(pm, formatAddArgs(pm, [pkg, 'dotenv']), { cwd: baseDir });\n await exec(pm, formatAddDevArgs(pm, ['prisma-next']), { cwd: baseDir });\n spinner.stop(`Installed ${pkg}, dotenv, and prisma-next`);\n installSucceeded = true;\n } catch (err) {\n spinner.stop('Installation failed');\n const stderr =\n err instanceof Error && 'stderr' in err ? (err as { stderr: string }).stderr : '';\n ui.warn(\n [\n 'Could not install dependencies automatically.',\n ...(stderr ? [` ${stderr.trim()}`] : []),\n '',\n 'Run manually:',\n ` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,\n ` ${pm} ${formatAddDevArgs(pm, ['prisma-next']).join(' ')}`,\n ].join('\\n'),\n );\n }\n\n if (installSucceeded) {\n spinner.start('Emitting contract...');\n try {\n const { executeContractEmit } = await import('../../control-api/operations/contract-emit');\n const configFilePath = join(baseDir, 'prisma-next.config.ts');\n await executeContractEmit({ configPath: configFilePath });\n spinner.stop('Contract emitted');\n } catch {\n spinner.stop('Contract emission failed');\n ui.warn(\n ['Could not emit contract automatically. Run manually:', ` ${emitCommand}`].join('\\n'),\n );\n }\n }\n }\n\n clack.outro('Done! Open prisma-next.md to get started.', { output: process.stderr });\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-C4VXKl8f.mjs";
|
|
2
2
|
import { _ as errorUnexpected, c as errorDriverRequired, o as errorDatabaseConnectionRequired, t as CliStructuredError } from "./cli-errors-BDCYR5ap.mjs";
|
|
3
|
-
import { t as createControlClient } from "./client-
|
|
3
|
+
import { t as createControlClient } from "./client-tdnbk0OR.mjs";
|
|
4
4
|
import { _ as formatStyledHeader, a as maskConnectionUrl, l as sanitizeErrorMessage } from "./result-handler-oK_vA-Fn.mjs";
|
|
5
5
|
import { t as createProgressAdapter } from "./progress-adapter-B-YvmcDu.mjs";
|
|
6
6
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -88,4 +88,4 @@ async function inspectLiveSchema(options, flags, ui, startTime, context) {
|
|
|
88
88
|
|
|
89
89
|
//#endregion
|
|
90
90
|
export { inspectLiveSchema as t };
|
|
91
|
-
//# sourceMappingURL=inspect-live-schema-
|
|
91
|
+
//# sourceMappingURL=inspect-live-schema-gYQiWfpl.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect-live-schema-
|
|
1
|
+
{"version":3,"file":"inspect-live-schema-gYQiWfpl.mjs","names":["config: LoadedCliConfig","details: Array<{ label: string; value: string }>"],"sources":["../src/commands/inspect-live-schema.ts"],"sourcesContent":["import type { CoreSchemaView } from '@prisma-next/framework-components/control';\nimport { validatePrintableSqlSchemaIR } from '@prisma-next/psl-printer';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { relative, resolve } from 'pathe';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport {\n CliStructuredError,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorUnexpected,\n} from '../utils/cli-errors';\nimport { maskConnectionUrl, sanitizeErrorMessage } from '../utils/command-helpers';\nimport { formatStyledHeader } from '../utils/formatters/styled';\nimport type { CommonCommandOptions, GlobalFlags } from '../utils/global-flags';\nimport { createProgressAdapter } from '../utils/progress-adapter';\nimport type { TerminalUI } from '../utils/terminal-ui';\n\nexport interface InspectLiveSchemaOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n}\n\ninterface InspectLiveSchemaContext {\n readonly commandName: string;\n readonly description: string;\n readonly url: string;\n}\n\ntype LoadedCliConfig = Awaited<ReturnType<typeof loadConfig>>;\n\nexport interface InspectLiveSchemaResult {\n readonly config: LoadedCliConfig;\n readonly schema: unknown;\n readonly schemaView: CoreSchemaView | undefined;\n readonly target: {\n readonly familyId: string;\n readonly id: string;\n };\n readonly meta: {\n readonly configPath?: string;\n readonly dbUrl?: string;\n };\n readonly timings: {\n readonly total: number;\n };\n}\n\nexport async function inspectLiveSchema(\n options: InspectLiveSchemaOptions,\n flags: GlobalFlags,\n ui: TerminalUI,\n startTime: number,\n context: InspectLiveSchemaContext,\n): Promise<Result<InspectLiveSchemaResult, CliStructuredError>> {\n let config: LoadedCliConfig;\n try {\n config = await loadConfig(options.config);\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\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 configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n ];\n\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n } else if (config.db?.connection && typeof config.db.connection === 'string') {\n details.push({ label: 'database', value: maskConnectionUrl(config.db.connection) });\n }\n\n ui.stderr(\n formatStyledHeader({\n command: context.commandName,\n description: context.description,\n url: context.url,\n details,\n flags,\n }),\n );\n }\n\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for ${context.commandName} (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: context.commandName,\n }),\n );\n }\n\n if (!config.driver) {\n return notOk(\n errorDriverRequired({\n why: `Config.driver is required for ${context.commandName}`,\n }),\n );\n }\n\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n const onProgress = createProgressAdapter({ ui, flags });\n\n try {\n const schemaIR = await client.introspect({\n connection: dbConnection,\n onProgress,\n });\n // TODO(TML-2251): Remove SQL-specific branching — SQL should use the same family-agnostic path as Mongo.\n const schema =\n config.family.familyId === 'sql' ? validatePrintableSqlSchemaIR(schemaIR) : schemaIR;\n const schemaView = client.toSchemaView(schema);\n\n const dbUrl = typeof dbConnection === 'string' ? maskConnectionUrl(dbConnection) : undefined;\n\n return ok({\n config,\n schema,\n schemaView,\n target: {\n familyId: config.family.familyId,\n id: config.target.targetId,\n },\n meta: {\n configPath,\n ...(dbUrl ? { dbUrl } : {}),\n },\n timings: {\n total: Date.now() - startTime,\n },\n });\n } catch (error) {\n if (CliStructuredError.is(error)) {\n return notOk(error);\n }\n\n const rawMessage = error instanceof Error ? error.message : String(error);\n const safeMessage = sanitizeErrorMessage(\n rawMessage,\n typeof dbConnection === 'string' ? dbConnection : undefined,\n );\n return notOk(\n errorUnexpected(safeMessage, {\n why: `Unexpected error during ${context.commandName}: ${safeMessage}`,\n }),\n );\n } finally {\n await client.close();\n }\n}\n"],"mappings":";;;;;;;;;;AAgDA,eAAsB,kBACpB,SACA,OACA,IACA,WACA,SAC8D;CAC9D,IAAIA;AACJ,KAAI;AACF,WAAS,MAAM,WAAW,QAAQ,OAAO;UAClC,OAAO;AACd,MAAI,mBAAmB,GAAG,MAAM,CAC9B,QAAO,MAAM,MAAM;AAGrB,SAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,yBACN,CAAC,CACH;;CAGH,MAAM,aAAa,QAAQ,SACvB,SAAS,QAAQ,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,GAChD;AAEJ,KAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAMC,UAAmD,CACvD;GAAE,OAAO;GAAU,OAAO;GAAY,CACvC;AAED,MAAI,QAAQ,GACV,SAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,QAAQ,GAAG;GAAE,CAAC;WAChE,OAAO,IAAI,cAAc,OAAO,OAAO,GAAG,eAAe,SAClE,SAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,OAAO,GAAG,WAAW;GAAE,CAAC;AAGrF,KAAG,OACD,mBAAmB;GACjB,SAAS,QAAQ;GACjB,aAAa,QAAQ;GACrB,KAAK,QAAQ;GACb;GACA;GACD,CAAC,CACH;;CAGH,MAAM,eAAe,QAAQ,MAAM,OAAO,IAAI;AAC9C,KAAI,CAAC,aACH,QAAO,MACL,gCAAgC;EAC9B,KAAK,uCAAuC,QAAQ,YAAY,yBAAyB,WAAW;EACpG,aAAa,QAAQ;EACtB,CAAC,CACH;AAGH,KAAI,CAAC,OAAO,OACV,QAAO,MACL,oBAAoB,EAClB,KAAK,iCAAiC,QAAQ,eAC/C,CAAC,CACH;CAGH,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,gBAAgB,OAAO,kBAAkB,EAAE;EAC5C,CAAC;CACF,MAAM,aAAa,sBAAsB;EAAE;EAAI;EAAO,CAAC;AAEvD,KAAI;EACF,MAAM,WAAW,MAAM,OAAO,WAAW;GACvC,YAAY;GACZ;GACD,CAAC;EAEF,MAAM,SACJ,OAAO,OAAO,aAAa,QAAQ,6BAA6B,SAAS,GAAG;EAC9E,MAAM,aAAa,OAAO,aAAa,OAAO;EAE9C,MAAM,QAAQ,OAAO,iBAAiB,WAAW,kBAAkB,aAAa,GAAG;AAEnF,SAAO,GAAG;GACR;GACA;GACA;GACA,QAAQ;IACN,UAAU,OAAO,OAAO;IACxB,IAAI,OAAO,OAAO;IACnB;GACD,MAAM;IACJ;IACA,GAAI,QAAQ,EAAE,OAAO,GAAG,EAAE;IAC3B;GACD,SAAS,EACP,OAAO,KAAK,KAAK,GAAG,WACrB;GACF,CAAC;UACK,OAAO;AACd,MAAI,mBAAmB,GAAG,MAAM,CAC9B,QAAO,MAAM,MAAM;EAIrB,MAAM,cAAc,qBADD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAGvE,OAAO,iBAAiB,WAAW,eAAe,OACnD;AACD,SAAO,MACL,gBAAgB,aAAa,EAC3B,KAAK,2BAA2B,QAAQ,YAAY,IAAI,eACzD,CAAC,CACH;WACO;AACR,QAAM,OAAO,OAAO"}
|
package/dist/{migration-command-scaffold-CntCcntR.mjs → migration-command-scaffold-x4n_ZhAh.mjs}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-C4VXKl8f.mjs";
|
|
2
2
|
import { _ as errorUnexpected, a as errorContractValidationFailed, c as errorDriverRequired, h as errorTargetMigrationNotSupported, l as errorFileNotFound, o as errorDatabaseConnectionRequired } from "./cli-errors-BDCYR5ap.mjs";
|
|
3
|
-
import { t as createControlClient } from "./client-
|
|
3
|
+
import { t as createControlClient } from "./client-tdnbk0OR.mjs";
|
|
4
4
|
import { _ as formatStyledHeader, a as maskConnectionUrl, n as addGlobalOptions, s as resolveContractPath } from "./result-handler-oK_vA-Fn.mjs";
|
|
5
5
|
import { t as createProgressAdapter } from "./progress-adapter-B-YvmcDu.mjs";
|
|
6
6
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
@@ -102,4 +102,4 @@ function addMigrationCommandOptions(command) {
|
|
|
102
102
|
|
|
103
103
|
//#endregion
|
|
104
104
|
export { prepareMigrationContext as n, addMigrationCommandOptions as t };
|
|
105
|
-
//# sourceMappingURL=migration-command-scaffold-
|
|
105
|
+
//# sourceMappingURL=migration-command-scaffold-x4n_ZhAh.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-command-scaffold-
|
|
1
|
+
{"version":3,"file":"migration-command-scaffold-x4n_ZhAh.mjs","names":["details: Array<{ label: string; value: string }>","contractJsonContent: string","contractJson: Record<string, unknown>"],"sources":["../src/utils/migration-command-scaffold.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { hasMigrations } from '@prisma-next/framework-components/control';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport type { Command } from 'commander';\nimport { loadConfig } from '../config-loader';\nimport { createControlClient } from '../control-api/client';\nimport type { ControlClient } from '../control-api/types';\nimport {\n type CliStructuredError,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFileNotFound,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from './cli-errors';\nimport { addGlobalOptions, maskConnectionUrl, resolveContractPath } from './command-helpers';\nimport { formatStyledHeader } from './formatters/styled';\nimport type { GlobalFlags } from './global-flags';\nimport { createProgressAdapter } from './progress-adapter';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Resolved context for a migration command.\n * Contains everything needed to invoke a control-api operation.\n */\nexport interface MigrationContext {\n readonly client: ControlClient;\n readonly contractJson: Record<string, unknown>;\n readonly dbConnection: unknown;\n readonly onProgress: ReturnType<typeof createProgressAdapter>;\n readonly configPath: string;\n readonly contractPath: string;\n readonly contractPathAbsolute: string;\n readonly config: Awaited<ReturnType<typeof loadConfig>>;\n}\n\n/**\n * Command-specific configuration for the shared scaffold.\n */\nexport interface MigrationCommandDescriptor {\n readonly commandName: string;\n readonly description: string;\n readonly url: string;\n}\n\n/**\n * Prepares the shared context for migration commands (db init, db update).\n *\n * Handles: config loading, contract file reading, JSON parsing, connection resolution,\n * driver/migration-support validation, client creation, and header output.\n *\n * Returns a Result with either the resolved context or a structured error.\n */\nexport async function prepareMigrationContext(\n options: { readonly db?: string; readonly config?: string; readonly dryRun?: boolean },\n flags: GlobalFlags,\n ui: TerminalUI,\n descriptor: MigrationCommandDescriptor,\n): Promise<Result<MigrationContext, CliStructuredError>> {\n // Load config\n const config = await loadConfig(options.config);\n const configPath = options.config\n ? relative(process.cwd(), resolve(options.config))\n : 'prisma-next.config.ts';\n const contractPathAbsolute = resolveContractPath(config);\n const contractPath = relative(process.cwd(), contractPathAbsolute);\n\n // Output header to stderr (decoration)\n if (!flags.json && !flags.quiet) {\n const details: Array<{ label: string; value: string }> = [\n { label: 'config', value: configPath },\n { label: 'contract', value: contractPath },\n ];\n if (options.db) {\n details.push({ label: 'database', value: maskConnectionUrl(options.db) });\n }\n if (options.dryRun) {\n details.push({ label: 'mode', value: 'dry run' });\n }\n const header = formatStyledHeader({\n command: descriptor.commandName,\n description: descriptor.description,\n url: descriptor.url,\n details,\n flags,\n });\n ui.stderr(header);\n }\n\n // Load contract file\n let contractJsonContent: string;\n try {\n contractJsonContent = await readFile(contractPathAbsolute, 'utf-8');\n } catch (error) {\n if (error instanceof Error && (error as { code?: string }).code === 'ENOENT') {\n return notOk(\n errorFileNotFound(contractPathAbsolute, {\n why: `Contract file not found at ${contractPathAbsolute}`,\n fix: `Run \\`prisma-next contract emit\\` to generate ${contractPath}, or update \\`config.contract.output\\` in ${configPath}`,\n }),\n );\n }\n return notOk(\n errorUnexpected(error instanceof Error ? error.message : String(error), {\n why: `Failed to read contract file: ${error instanceof Error ? error.message : String(error)}`,\n }),\n );\n }\n\n // Parse contract JSON\n let contractJson: Record<string, unknown>;\n try {\n contractJson = JSON.parse(contractJsonContent) as Record<string, unknown>;\n } catch (error) {\n return notOk(\n errorContractValidationFailed(\n `Contract JSON is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { where: { path: contractPathAbsolute } },\n ),\n );\n }\n\n // Resolve database connection (--db flag or config.db.connection)\n const dbConnection = options.db ?? config.db?.connection;\n if (!dbConnection) {\n return notOk(\n errorDatabaseConnectionRequired({\n why: `Database connection is required for ${descriptor.commandName} (set db.connection in ${configPath}, or pass --db <url>)`,\n commandName: descriptor.commandName,\n }),\n );\n }\n\n // Check for driver\n if (!config.driver) {\n return notOk(\n errorDriverRequired({ why: `Config.driver is required for ${descriptor.commandName}` }),\n );\n }\n\n if (!hasMigrations(config.target)) {\n return notOk(\n errorTargetMigrationNotSupported({\n why: `Target \"${config.target.id}\" does not support migrations`,\n }),\n );\n }\n\n // Create control client\n const client = createControlClient({\n family: config.family,\n target: config.target,\n adapter: config.adapter,\n driver: config.driver,\n extensionPacks: config.extensionPacks ?? [],\n });\n\n // Create progress adapter\n const onProgress = createProgressAdapter({ ui, flags });\n\n return ok({\n client,\n contractJson,\n dbConnection,\n onProgress,\n configPath,\n contractPath,\n contractPathAbsolute,\n config,\n });\n}\n\n/**\n * Registers the shared CLI options for migration commands (db init, db update).\n */\nexport function addMigrationCommandOptions(command: Command): Command {\n addGlobalOptions(command);\n return command\n .option('--db <url>', 'Database connection string')\n .option('--config <path>', 'Path to prisma-next.config.ts')\n .option('--dry-run', 'Preview planned operations without applying', false);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAuDA,eAAsB,wBACpB,SACA,OACA,IACA,YACuD;CAEvD,MAAM,SAAS,MAAM,WAAW,QAAQ,OAAO;CAC/C,MAAM,aAAa,QAAQ,SACvB,SAAS,QAAQ,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC,GAChD;CACJ,MAAM,uBAAuB,oBAAoB,OAAO;CACxD,MAAM,eAAe,SAAS,QAAQ,KAAK,EAAE,qBAAqB;AAGlE,KAAI,CAAC,MAAM,QAAQ,CAAC,MAAM,OAAO;EAC/B,MAAMA,UAAmD,CACvD;GAAE,OAAO;GAAU,OAAO;GAAY,EACtC;GAAE,OAAO;GAAY,OAAO;GAAc,CAC3C;AACD,MAAI,QAAQ,GACV,SAAQ,KAAK;GAAE,OAAO;GAAY,OAAO,kBAAkB,QAAQ,GAAG;GAAE,CAAC;AAE3E,MAAI,QAAQ,OACV,SAAQ,KAAK;GAAE,OAAO;GAAQ,OAAO;GAAW,CAAC;EAEnD,MAAM,SAAS,mBAAmB;GAChC,SAAS,WAAW;GACpB,aAAa,WAAW;GACxB,KAAK,WAAW;GAChB;GACA;GACD,CAAC;AACF,KAAG,OAAO,OAAO;;CAInB,IAAIC;AACJ,KAAI;AACF,wBAAsB,MAAM,SAAS,sBAAsB,QAAQ;UAC5D,OAAO;AACd,MAAI,iBAAiB,SAAU,MAA4B,SAAS,SAClE,QAAO,MACL,kBAAkB,sBAAsB;GACtC,KAAK,8BAA8B;GACnC,KAAK,iDAAiD,aAAa,4CAA4C;GAChH,CAAC,CACH;AAEH,SAAO,MACL,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAAE,EACtE,KAAK,iCAAiC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IAC7F,CAAC,CACH;;CAIH,IAAIC;AACJ,KAAI;AACF,iBAAe,KAAK,MAAM,oBAAoB;UACvC,OAAO;AACd,SAAO,MACL,8BACE,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,IACnF,EAAE,OAAO,EAAE,MAAM,sBAAsB,EAAE,CAC1C,CACF;;CAIH,MAAM,eAAe,QAAQ,MAAM,OAAO,IAAI;AAC9C,KAAI,CAAC,aACH,QAAO,MACL,gCAAgC;EAC9B,KAAK,uCAAuC,WAAW,YAAY,yBAAyB,WAAW;EACvG,aAAa,WAAW;EACzB,CAAC,CACH;AAIH,KAAI,CAAC,OAAO,OACV,QAAO,MACL,oBAAoB,EAAE,KAAK,iCAAiC,WAAW,eAAe,CAAC,CACxF;AAGH,KAAI,CAAC,cAAc,OAAO,OAAO,CAC/B,QAAO,MACL,iCAAiC,EAC/B,KAAK,WAAW,OAAO,OAAO,GAAG,gCAClC,CAAC,CACH;CAIH,MAAM,SAAS,oBAAoB;EACjC,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,gBAAgB,OAAO,kBAAkB,EAAE;EAC5C,CAAC;CAGF,MAAM,aAAa,sBAAsB;EAAE;EAAI;EAAO,CAAC;AAEvD,QAAO,GAAG;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;;;;;AAMJ,SAAgB,2BAA2B,SAA2B;AACpE,kBAAiB,QAAQ;AACzB,QAAO,QACJ,OAAO,cAAc,6BAA6B,CAClD,OAAO,mBAAmB,gCAAgC,CAC1D,OAAO,aAAa,+CAA+C,MAAM"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as loadConfig } from "./config-loader-C4VXKl8f.mjs";
|
|
2
2
|
import { _ as errorUnexpected, m as errorRuntime } from "./cli-errors-BDCYR5ap.mjs";
|
|
3
|
-
import { t as createControlClient } from "./client-
|
|
3
|
+
import { t as createControlClient } from "./client-tdnbk0OR.mjs";
|
|
4
4
|
import { _ as formatStyledHeader, a as maskConnectionUrl, c as resolveMigrationPaths, d as setCommandExamples, i as loadAllBundles, m as parseGlobalFlags, n as addGlobalOptions, o as readContractEnvelope, p as toPathDecisionResult, t as handleResult, u as setCommandDescriptions } from "./result-handler-oK_vA-Fn.mjs";
|
|
5
5
|
import { t as TerminalUI } from "./terminal-ui-C5k88MmW.mjs";
|
|
6
6
|
import { Command } from "commander";
|
|
@@ -1580,4 +1580,4 @@ function summarizeRefDistance(graph, markerHash, refHash, refName) {
|
|
|
1580
1580
|
|
|
1581
1581
|
//#endregion
|
|
1582
1582
|
export { deriveEdgeStatuses as n, createMigrationStatusCommand as t };
|
|
1583
|
-
//# sourceMappingURL=migration-status-
|
|
1583
|
+
//# sourceMappingURL=migration-status-DyVDf5NI.mjs.map
|