🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@prisma-next/config

Package Overview
Dependencies
Maintainers
4
Versions
617
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@prisma-next/config - npm Package Compare versions

Comparing version
0.16.0-dev.19
to
0.16.0-dev.21
+158
dist/config-types-B1QRy_5L.d.mts
import { AssembledAuthoringContributions, ControlAdapterDescriptor, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyDescriptor, ControlMutationDefaults, ControlTargetDescriptor } from "@prisma-next/framework-components/control";
import { Contract } from "@prisma-next/contract/types";
import { CodecLookup } from "@prisma-next/framework-components/codec";
import { CapabilityMatrix } from "@prisma-next/framework-components/components";
import { Result } from "@prisma-next/utils/result";
//#region src/contract-source-types.d.ts
interface ContractSourceDiagnosticPosition {
readonly offset: number;
readonly line: number;
readonly column: number;
}
interface ContractSourceDiagnosticSpan {
readonly start: ContractSourceDiagnosticPosition;
readonly end: ContractSourceDiagnosticPosition;
}
interface ContractSourceDiagnostic {
readonly code: string;
readonly message: string;
readonly sourceId?: string;
readonly span?: ContractSourceDiagnosticSpan;
/**
* Optional structured payload for machine-readable consumers (agents,
* IDE extensions, CLI auto-fix). Human-readable prose lives in `message`;
* `data` carries the extracted facts (e.g. `{ namespace: 'pgvector' }`).
*/
readonly data?: Readonly<Record<string, unknown>>;
}
interface ContractSourceDiagnostics {
readonly summary: string;
readonly diagnostics: readonly ContractSourceDiagnostic[];
readonly meta?: Record<string, unknown>;
}
interface ContractSourceContext {
readonly composedExtensions: readonly string[];
/** Extension contracts keyed by space ID, required for cross-space FK resolution. */
readonly composedExtensionContracts: ReadonlyMap<string, Contract>;
readonly authoringContributions: AssembledAuthoringContributions;
readonly codecLookup: CodecLookup;
readonly controlMutationDefaults: ControlMutationDefaults;
readonly resolvedInputs: readonly string[];
readonly capabilities: CapabilityMatrix;
}
/** Lets format-aware tooling avoid file-extension sniffing and opaque loader introspection. */
type ContractSourceFormat = 'psl' | 'typescript';
interface ContractSourceProviderBase {
readonly inputs?: readonly string[];
readonly load: (context: ContractSourceContext) => Promise<Result<Contract, ContractSourceDiagnostics>>;
}
interface PslContractSourceProvider extends ContractSourceProviderBase {
readonly format: 'psl';
}
interface TypeScriptContractSourceProvider extends ContractSourceProviderBase {
readonly format: 'typescript';
}
/**
* Third-party or unspecified source formats. Absent (or unrecognized)
* `format` means format-aware tooling must leave the source untouched.
* Narrowing to a known format flows only through capability guards owned by
* the authoring layer.
*/
interface OpaqueContractSourceProvider extends ContractSourceProviderBase {
readonly format?: string;
}
type ContractSourceProvider = PslContractSourceProvider | TypeScriptContractSourceProvider | OpaqueContractSourceProvider;
//#endregion
//#region src/config-types.d.ts
/**
* Contract configuration specifying source and artifact locations.
*/
interface ContractConfig {
/**
* Contract source provider. The provider is always async and must return
* a Result containing either a Contract or structured diagnostics.
*/
readonly source: ContractSourceProvider;
/**
* Path to contract.json artifact. Providers that know an input path (PSL,
* `typescriptContractFromPath`) derive an output colocated with that input
* so this rarely needs to be set explicitly. The `.d.ts` types file is
* always emitted next to the JSON (e.g., `contract.json` → `contract.d.ts`).
*/
readonly output?: string;
}
interface FormatterConfig {
readonly indent?: number | 'tab';
readonly newline?: 'LF' | 'CRLF';
}
/**
* Default *source* directory for the contract file the user authors at `init`
* time. Output artefacts colocate with source per the same rule path-bearing
* providers apply.
*/
declare const DEFAULT_CONTRACT_SOURCE_DIR = "src/prisma";
declare function normalizeContractConfig(contract: ContractConfig): ContractConfig & {
readonly output: string;
};
/**
* Configuration for Prisma Next CLI.
* Uses Control*Descriptor types for type-safe wiring with compile-time compatibility checks.
*
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
* @template TConnection - The driver connection input type (defaults to `unknown` for config flexibility)
*/
interface PrismaNextConfig<TFamilyId extends string = string, TTargetId extends string = string, TConnection = unknown> {
readonly family: ControlFamilyDescriptor<TFamilyId>;
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
/**
* Driver descriptor for DB-connected CLI commands.
* Required for DB-connected commands (e.g., db verify).
* Optional for commands that don't need database access (e.g., emit).
* The driver's connection type matches the TConnection config parameter.
*/
readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId, ControlDriverInstance<TFamilyId, TTargetId>, TConnection>;
/**
* Database connection configuration.
* The connection type is driver-specific (e.g., URL string for Postgres).
*/
readonly db?: {
/**
* Driver-specific connection input.
* For Postgres: a connection string (URL).
* For other drivers: may be a structured object.
*/
readonly connection?: TConnection;
};
/**
* Contract configuration. Specifies source and artifact locations.
* Required for emit command; optional for other commands that only read artifacts.
*/
readonly contract?: ContractConfig;
/**
* Migration configuration. Controls where on-disk migration packages are stored.
*/
readonly migrations?: {
/** Directory for migration packages, relative to config file. Defaults to 'migrations'. */
readonly dir?: string;
};
readonly formatter?: FormatterConfig;
}
/**
* Helper function to define a Prisma Next config.
* Validates and normalizes the config using Arktype, then returns the normalized IR.
*
* Normalization:
* - contract.output defaults to a path colocated with DEFAULT_CONTRACT_SOURCE_DIR
* when missing (in-memory-only providers)
*
* @param config - Raw config input from user
* @returns Normalized config IR with defaults applied
* @throws Error if config structure is invalid
*/
declare function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(config: PrismaNextConfig<TFamilyId, TTargetId>): PrismaNextConfig<TFamilyId, TTargetId>;
//#endregion
export { TypeScriptContractSourceProvider as _, defineConfig as a, ContractSourceDiagnostic as c, ContractSourceDiagnostics as d, ContractSourceFormat as f, PslContractSourceProvider as g, OpaqueContractSourceProvider as h, PrismaNextConfig as i, ContractSourceDiagnosticPosition as l, ContractSourceProviderBase as m, DEFAULT_CONTRACT_SOURCE_DIR as n, normalizeContractConfig as o, ContractSourceProvider as p, FormatterConfig as r, ContractSourceContext as s, ContractConfig as t, ContractSourceDiagnosticSpan as u };
//# sourceMappingURL=config-types-B1QRy_5L.d.mts.map
{"version":3,"file":"config-types-B1QRy_5L.d.mts","names":[],"sources":["../src/contract-source-types.ts","../src/config-types.ts"],"mappings":";;;;;;UASiB;WACN;WACA;WACA;;UAGM;WACN,OAAO;WACP,KAAK;;UAGC;WACN;WACA;WACA;WACA,OAAO;;;;;;WAMP,OAAO,SAAS;;UAGV;WACN;WACA,sBAAsB;WACtB,OAAO;;UAGD;WACN;;WAEA,4BAA4B,oBAAoB;WAChD,wBAAwB;WACxB,aAAa;WACb,yBAAyB;WACzB;WACA,cAAc;;;KAIb;UAEK;WACN;WACA,OACP,SAAS,0BACN,QAAQ,OAAO,UAAU;;UAGf,kCAAkC;WACxC;;UAGM,yCAAyC;WAC/C;;;;;;;;UASM,qCAAqC;WAC3C;;KAGC,yBACR,4BACA,mCACA;;;;;;UC7Da;;;;;WAKN,QAAQ;;;;;;;WAOR;;UAGM;WACN;WACA;;;;;;;cAQE;iBAEG,wBACd,UAAU,iBACT;WAA4B;;;;;;;;;;UAmBd,iBACf,mCACA,mCACA;WAES,QAAQ,wBAAwB;WAChC,QAAQ,wBAAwB,WAAW;WAC3C,SAAS,yBAAyB,WAAW;WAC7C,sBAAsB,2BAA2B,WAAW;;;;;;;WAO5D,SAAS,wBAChB,WACA,WACA,sBAAsB,WAAW,YACjC;;;;;WAMO;;;;;;aAME,aAAa;;;;;;WAMf,WAAW;;;;WAIX;;aAEE;;WAEF,YAAY;;;;;;;;;;;;;;iBAuDP,aAAa,mCAAmC,mCAC9D,QAAQ,iBAAiB,WAAW,aACnC,iBAAiB,WAAW"}
+1
-1

@@ -1,2 +0,2 @@

import { _ as TypeScriptContractSourceProvider, a as defineConfig, c as ContractSourceDiagnostic, d as ContractSourceDiagnostics, f as ContractSourceFormat, g as PslContractSourceProvider, h as OpaqueContractSourceProvider, i as PrismaNextConfig, l as ContractSourceDiagnosticPosition, m as ContractSourceProviderBase, n as DEFAULT_CONTRACT_SOURCE_DIR, o as normalizeContractConfig, p as ContractSourceProvider, r as FormatterConfig, s as ContractSourceContext, t as ContractConfig, u as ContractSourceDiagnosticSpan } from "./config-types-DtsiIT_O.mjs";
import { _ as TypeScriptContractSourceProvider, a as defineConfig, c as ContractSourceDiagnostic, d as ContractSourceDiagnostics, f as ContractSourceFormat, g as PslContractSourceProvider, h as OpaqueContractSourceProvider, i as PrismaNextConfig, l as ContractSourceDiagnosticPosition, m as ContractSourceProviderBase, n as DEFAULT_CONTRACT_SOURCE_DIR, o as normalizeContractConfig, p as ContractSourceProvider, r as FormatterConfig, s as ContractSourceContext, t as ContractConfig, u as ContractSourceDiagnosticSpan } from "./config-types-B1QRy_5L.mjs";
export { type ContractConfig, type ContractSourceContext, type ContractSourceDiagnostic, type ContractSourceDiagnosticPosition, type ContractSourceDiagnosticSpan, type ContractSourceDiagnostics, type ContractSourceFormat, type ContractSourceProvider, type ContractSourceProviderBase, DEFAULT_CONTRACT_SOURCE_DIR, type FormatterConfig, type OpaqueContractSourceProvider, type PrismaNextConfig, type PslContractSourceProvider, type TypeScriptContractSourceProvider, defineConfig, normalizeContractConfig };

@@ -20,3 +20,3 @@ import { type } from "arktype";

adapter: "unknown",
"extensionPacks?": "unknown[]",
"extensions?": "unknown[]",
"driver?": "unknown",

@@ -26,3 +26,3 @@ "db?": "unknown",

source: type({
"sourceFormat?": "string",
"format?": "string",
"inputs?": type("string").array(),

@@ -29,0 +29,0 @@ load: "Function"

@@ -1,1 +0,1 @@

{"version":3,"file":"config-types.mjs","names":[],"sources":["../src/config-types.ts"],"sourcesContent":["import type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from '@prisma-next/framework-components/control';\nimport { type } from 'arktype';\nimport type { ContractSourceProvider } from './contract-source-types';\n\n/**\n * Type alias for CLI driver instances.\n * Uses string for both family and target IDs for maximum flexibility.\n */\nexport type CliDriver = ControlDriverInstance<string, string>;\n\n/**\n * Contract configuration specifying source and artifact locations.\n */\nexport interface ContractConfig {\n /**\n * Contract source provider. The provider is always async and must return\n * a Result containing either a Contract or structured diagnostics.\n */\n readonly source: ContractSourceProvider;\n /**\n * Path to contract.json artifact. Providers that know an input path (PSL,\n * `typescriptContractFromPath`) derive an output colocated with that input\n * so this rarely needs to be set explicitly. The `.d.ts` types file is\n * always emitted next to the JSON (e.g., `contract.json` → `contract.d.ts`).\n */\n readonly output?: string;\n}\n\nexport interface FormatterConfig {\n readonly indent?: number | 'tab';\n readonly newline?: 'LF' | 'CRLF';\n}\n\n/**\n * Default *source* directory for the contract file the user authors at `init`\n * time. Output artefacts colocate with source per the same rule path-bearing\n * providers apply.\n */\nexport const DEFAULT_CONTRACT_SOURCE_DIR = 'src/prisma';\n\nexport function normalizeContractConfig(\n contract: ContractConfig,\n): ContractConfig & { readonly output: string } {\n // In-memory-only fallback: `typescriptContract(contract)` has no source path\n // to anchor on, so normalization supplies a default output colocated with\n // the default source directory.\n const inMemoryFallbackOutput = `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.json`;\n return {\n source: contract.source,\n output: contract.output ?? inMemoryFallbackOutput,\n };\n}\n\n/**\n * Configuration for Prisma Next CLI.\n * Uses Control*Descriptor types for type-safe wiring with compile-time compatibility checks.\n *\n * @template TFamilyId - The family ID (e.g., 'sql', 'document')\n * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')\n * @template TConnection - The driver connection input type (defaults to `unknown` for config flexibility)\n */\nexport interface PrismaNextConfig<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n TConnection = unknown,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;\n readonly extensionPacks?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];\n /**\n * Driver descriptor for DB-connected CLI commands.\n * Required for DB-connected commands (e.g., db verify).\n * Optional for commands that don't need database access (e.g., emit).\n * The driver's connection type matches the TConnection config parameter.\n */\n readonly driver?: ControlDriverDescriptor<\n TFamilyId,\n TTargetId,\n ControlDriverInstance<TFamilyId, TTargetId>,\n TConnection\n >;\n /**\n * Database connection configuration.\n * The connection type is driver-specific (e.g., URL string for Postgres).\n */\n readonly db?: {\n /**\n * Driver-specific connection input.\n * For Postgres: a connection string (URL).\n * For other drivers: may be a structured object.\n */\n readonly connection?: TConnection;\n };\n /**\n * Contract configuration. Specifies source and artifact locations.\n * Required for emit command; optional for other commands that only read artifacts.\n */\n readonly contract?: ContractConfig;\n /**\n * Migration configuration. Controls where on-disk migration packages are stored.\n */\n readonly migrations?: {\n /** Directory for migration packages, relative to config file. Defaults to 'migrations'. */\n readonly dir?: string;\n };\n readonly formatter?: FormatterConfig;\n}\n\nconst ContractSourceInputSchema = type('string');\n\nexport const ContractSourceProviderSchema = type({\n 'sourceFormat?': 'string',\n 'inputs?': ContractSourceInputSchema.array(),\n load: 'Function',\n});\n\nexport const ContractConfigSchema = type({\n source: ContractSourceProviderSchema,\n 'output?': 'string',\n});\n\n/**\n * Arktype schema for PrismaNextConfig validation.\n * Note: This validates structure only. Descriptor objects (family, target, adapter) are validated separately.\n */\nconst MigrationsConfigSchema = type({\n 'dir?': 'string',\n});\n\nconst FormatterIndentSchema = type('number.integer >= 1').or(\"'tab'\");\n\nexport const FormatterConfigSchema = type({\n 'indent?': FormatterIndentSchema,\n 'newline?': \"'LF' | 'CRLF'\",\n});\n\nconst PrismaNextConfigSchema = type({\n family: 'unknown', // ControlFamilyDescriptor - validated separately\n target: 'unknown', // ControlTargetDescriptor - validated separately\n adapter: 'unknown', // ControlAdapterDescriptor - validated separately\n 'extensionPacks?': 'unknown[]',\n 'driver?': 'unknown', // ControlDriverDescriptor - validated separately (optional)\n 'db?': 'unknown',\n 'contract?': ContractConfigSchema,\n 'migrations?': MigrationsConfigSchema,\n 'formatter?': FormatterConfigSchema,\n});\n\n/**\n * Helper function to define a Prisma Next config.\n * Validates and normalizes the config using Arktype, then returns the normalized IR.\n *\n * Normalization:\n * - contract.output defaults to a path colocated with DEFAULT_CONTRACT_SOURCE_DIR\n * when missing (in-memory-only providers)\n *\n * @param config - Raw config input from user\n * @returns Normalized config IR with defaults applied\n * @throws Error if config structure is invalid\n */\nexport function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(\n config: PrismaNextConfig<TFamilyId, TTargetId>,\n): PrismaNextConfig<TFamilyId, TTargetId> {\n // Validate structure using Arktype\n const validated = PrismaNextConfigSchema(config);\n if (validated instanceof type.errors) {\n const messages = validated.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Config validation failed: ${messages}`);\n }\n\n // Normalize contract config if present\n if (config.contract) {\n // Return normalized config\n return {\n ...config,\n contract: normalizeContractConfig(config.contract),\n };\n }\n\n // Return config as-is if no contract (preserve literal types)\n return config;\n}\n"],"mappings":";;;;;;;AA6CA,MAAa,8BAA8B;AAE3C,SAAgB,wBACd,UAC8C;CAI9C,MAAM,yBAAyB,GAAG,4BAA4B;CAC9D,OAAO;EACL,QAAQ,SAAS;EACjB,QAAQ,SAAS,UAAU;CAC7B;AACF;AAsFA,MAAM,yBAAyB,KAAK;CAClC,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,mBAAmB;CACnB,WAAW;CACX,OAAO;CACP,aA3BkC,KAAK;EACvC,QAP0C,KAAK;GAC/C,iBAAiB;GACjB,WAJgC,KAAK,QAI1B,CAAA,CAA0B,MAAM;GAC3C,MAAM;EACR,CAGU;EACR,WAAW;CACb,CAwBe;CACb,eAnB6B,KAAK,EAClC,QAAQ,SACV,CAiBiB;CACf,cAdmC,KAAK;EACxC,WAH4B,KAAK,qBAAqB,CAAC,CAAC,GAAG,OAGhD;EACX,YAAY;CACd,CAWgB;AAChB,CAAC;;;;;;;;;;;;;AAcD,SAAgB,aACd,QACwC;CAExC,MAAM,YAAY,uBAAuB,MAAM;CAC/C,IAAI,qBAAqB,KAAK,QAAQ;EACpC,MAAM,WAAW,UAAU,KAAK,MAA2B,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI;EAC/E,MAAM,IAAI,MAAM,6BAA6B,UAAU;CACzD;CAGA,IAAI,OAAO,UAET,OAAO;EACL,GAAG;EACH,UAAU,wBAAwB,OAAO,QAAQ;CACnD;CAIF,OAAO;AACT"}
{"version":3,"file":"config-types.mjs","names":[],"sources":["../src/config-types.ts"],"sourcesContent":["import type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from '@prisma-next/framework-components/control';\nimport { type } from 'arktype';\nimport type { ContractSourceProvider } from './contract-source-types';\n\n/**\n * Type alias for CLI driver instances.\n * Uses string for both family and target IDs for maximum flexibility.\n */\nexport type CliDriver = ControlDriverInstance<string, string>;\n\n/**\n * Contract configuration specifying source and artifact locations.\n */\nexport interface ContractConfig {\n /**\n * Contract source provider. The provider is always async and must return\n * a Result containing either a Contract or structured diagnostics.\n */\n readonly source: ContractSourceProvider;\n /**\n * Path to contract.json artifact. Providers that know an input path (PSL,\n * `typescriptContractFromPath`) derive an output colocated with that input\n * so this rarely needs to be set explicitly. The `.d.ts` types file is\n * always emitted next to the JSON (e.g., `contract.json` → `contract.d.ts`).\n */\n readonly output?: string;\n}\n\nexport interface FormatterConfig {\n readonly indent?: number | 'tab';\n readonly newline?: 'LF' | 'CRLF';\n}\n\n/**\n * Default *source* directory for the contract file the user authors at `init`\n * time. Output artefacts colocate with source per the same rule path-bearing\n * providers apply.\n */\nexport const DEFAULT_CONTRACT_SOURCE_DIR = 'src/prisma';\n\nexport function normalizeContractConfig(\n contract: ContractConfig,\n): ContractConfig & { readonly output: string } {\n // In-memory-only fallback: `typescriptContract(contract)` has no source path\n // to anchor on, so normalization supplies a default output colocated with\n // the default source directory.\n const inMemoryFallbackOutput = `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.json`;\n return {\n source: contract.source,\n output: contract.output ?? inMemoryFallbackOutput,\n };\n}\n\n/**\n * Configuration for Prisma Next CLI.\n * Uses Control*Descriptor types for type-safe wiring with compile-time compatibility checks.\n *\n * @template TFamilyId - The family ID (e.g., 'sql', 'document')\n * @template TTargetId - The target ID (e.g., 'postgres', 'mysql')\n * @template TConnection - The driver connection input type (defaults to `unknown` for config flexibility)\n */\nexport interface PrismaNextConfig<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n TConnection = unknown,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;\n readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];\n /**\n * Driver descriptor for DB-connected CLI commands.\n * Required for DB-connected commands (e.g., db verify).\n * Optional for commands that don't need database access (e.g., emit).\n * The driver's connection type matches the TConnection config parameter.\n */\n readonly driver?: ControlDriverDescriptor<\n TFamilyId,\n TTargetId,\n ControlDriverInstance<TFamilyId, TTargetId>,\n TConnection\n >;\n /**\n * Database connection configuration.\n * The connection type is driver-specific (e.g., URL string for Postgres).\n */\n readonly db?: {\n /**\n * Driver-specific connection input.\n * For Postgres: a connection string (URL).\n * For other drivers: may be a structured object.\n */\n readonly connection?: TConnection;\n };\n /**\n * Contract configuration. Specifies source and artifact locations.\n * Required for emit command; optional for other commands that only read artifacts.\n */\n readonly contract?: ContractConfig;\n /**\n * Migration configuration. Controls where on-disk migration packages are stored.\n */\n readonly migrations?: {\n /** Directory for migration packages, relative to config file. Defaults to 'migrations'. */\n readonly dir?: string;\n };\n readonly formatter?: FormatterConfig;\n}\n\nconst ContractSourceInputSchema = type('string');\n\nexport const ContractSourceProviderSchema = type({\n 'format?': 'string',\n 'inputs?': ContractSourceInputSchema.array(),\n load: 'Function',\n});\n\nexport const ContractConfigSchema = type({\n source: ContractSourceProviderSchema,\n 'output?': 'string',\n});\n\n/**\n * Arktype schema for PrismaNextConfig validation.\n * Note: This validates structure only. Descriptor objects (family, target, adapter) are validated separately.\n */\nconst MigrationsConfigSchema = type({\n 'dir?': 'string',\n});\n\nconst FormatterIndentSchema = type('number.integer >= 1').or(\"'tab'\");\n\nexport const FormatterConfigSchema = type({\n 'indent?': FormatterIndentSchema,\n 'newline?': \"'LF' | 'CRLF'\",\n});\n\nconst PrismaNextConfigSchema = type({\n family: 'unknown', // ControlFamilyDescriptor - validated separately\n target: 'unknown', // ControlTargetDescriptor - validated separately\n adapter: 'unknown', // ControlAdapterDescriptor - validated separately\n 'extensions?': 'unknown[]',\n 'driver?': 'unknown', // ControlDriverDescriptor - validated separately (optional)\n 'db?': 'unknown',\n 'contract?': ContractConfigSchema,\n 'migrations?': MigrationsConfigSchema,\n 'formatter?': FormatterConfigSchema,\n});\n\n/**\n * Helper function to define a Prisma Next config.\n * Validates and normalizes the config using Arktype, then returns the normalized IR.\n *\n * Normalization:\n * - contract.output defaults to a path colocated with DEFAULT_CONTRACT_SOURCE_DIR\n * when missing (in-memory-only providers)\n *\n * @param config - Raw config input from user\n * @returns Normalized config IR with defaults applied\n * @throws Error if config structure is invalid\n */\nexport function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(\n config: PrismaNextConfig<TFamilyId, TTargetId>,\n): PrismaNextConfig<TFamilyId, TTargetId> {\n // Validate structure using Arktype\n const validated = PrismaNextConfigSchema(config);\n if (validated instanceof type.errors) {\n const messages = validated.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Config validation failed: ${messages}`);\n }\n\n // Normalize contract config if present\n if (config.contract) {\n // Return normalized config\n return {\n ...config,\n contract: normalizeContractConfig(config.contract),\n };\n }\n\n // Return config as-is if no contract (preserve literal types)\n return config;\n}\n"],"mappings":";;;;;;;AA6CA,MAAa,8BAA8B;AAE3C,SAAgB,wBACd,UAC8C;CAI9C,MAAM,yBAAyB,GAAG,4BAA4B;CAC9D,OAAO;EACL,QAAQ,SAAS;EACjB,QAAQ,SAAS,UAAU;CAC7B;AACF;AAsFA,MAAM,yBAAyB,KAAK;CAClC,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,eAAe;CACf,WAAW;CACX,OAAO;CACP,aA3BkC,KAAK;EACvC,QAP0C,KAAK;GAC/C,WAAW;GACX,WAJgC,KAAK,QAI1B,CAAA,CAA0B,MAAM;GAC3C,MAAM;EACR,CAGU;EACR,WAAW;CACb,CAwBe;CACb,eAnB6B,KAAK,EAClC,QAAQ,SACV,CAiBiB;CACf,cAdmC,KAAK;EACxC,WAH4B,KAAK,qBAAqB,CAAC,CAAC,GAAG,OAGhD;EACX,YAAY;CACd,CAWgB;AAChB,CAAC;;;;;;;;;;;;;AAcD,SAAgB,aACd,QACwC;CAExC,MAAM,YAAY,uBAAuB,MAAM;CAC/C,IAAI,qBAAqB,KAAK,QAAQ;EACpC,MAAM,WAAW,UAAU,KAAK,MAA2B,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI;EAC/E,MAAM,IAAI,MAAM,6BAA6B,UAAU;CACzD;CAGA,IAAI,OAAO,UAET,OAAO;EACL,GAAG;EACH,UAAU,wBAAwB,OAAO,QAAQ;CACnD;CAIF,OAAO;AACT"}

@@ -1,2 +0,2 @@

import { i as PrismaNextConfig } from "./config-types-DtsiIT_O.mjs";
import { i as PrismaNextConfig } from "./config-types-B1QRy_5L.mjs";
//#region src/config-validation.d.ts

@@ -3,0 +3,0 @@ /**

@@ -70,16 +70,16 @@ //#region src/errors.ts

if (typeof adapter["create"] !== "function") throwValidation("adapter.create", "Config.adapter must have create: function");
if (configObj["extensions"] !== void 0) throwValidation("extensions", "Config.extensions is not supported; use Config.extensionPacks");
if (configObj["extensionPacks"] !== void 0) {
if (!Array.isArray(configObj["extensionPacks"])) throwValidation("extensionPacks", "Config.extensionPacks must be an array");
for (const ext of configObj["extensionPacks"]) {
if (!ext || typeof ext !== "object") throwValidation("extensionPacks[]", "Config.extensionPacks must contain ControlExtensionDescriptor objects");
if (configObj["extensionPacks"] !== void 0) throwValidation("extensionPacks", "Config.extensionPacks is no longer supported; rename it to Config.extensions");
if (configObj["extensions"] !== void 0) {
if (!Array.isArray(configObj["extensions"])) throwValidation("extensions", "Config.extensions must be an array");
for (const ext of configObj["extensions"]) {
if (!ext || typeof ext !== "object") throwValidation("extensions[]", "Config.extensions must contain ControlExtensionDescriptor objects");
const extObj = ext;
if (extObj["kind"] !== "extension") throwValidation("extensionPacks[].kind", "Config.extensionPacks items must have kind: \"extension\"");
if (typeof extObj["id"] !== "string") throwValidation("extensionPacks[].id", "Config.extensionPacks items must have id: string");
if (typeof extObj["familyId"] !== "string") throwValidation("extensionPacks[].familyId", "Config.extensionPacks items must have familyId: string");
if (typeof extObj["version"] !== "string") throwValidation("extensionPacks[].version", "Config.extensionPacks items must have version: string");
if (extObj["familyId"] !== familyId) throwValidation("extensionPacks[].familyId", `Config.extensionPacks[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj["familyId"]})`);
if (typeof extObj["targetId"] !== "string") throwValidation("extensionPacks[].targetId", "Config.extensionPacks items must have targetId: string");
if (extObj["targetId"] !== expectedTargetId) throwValidation("extensionPacks[].targetId", `Config.extensionPacks[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj["targetId"]})`);
if (typeof extObj["create"] !== "function") throwValidation("extensionPacks[].create", "Config.extensionPacks items must have create: function");
if (extObj["kind"] !== "extension") throwValidation("extensions[].kind", "Config.extensions items must have kind: \"extension\"");
if (typeof extObj["id"] !== "string") throwValidation("extensions[].id", "Config.extensions items must have id: string");
if (typeof extObj["familyId"] !== "string") throwValidation("extensions[].familyId", "Config.extensions items must have familyId: string");
if (typeof extObj["version"] !== "string") throwValidation("extensions[].version", "Config.extensions items must have version: string");
if (extObj["familyId"] !== familyId) throwValidation("extensions[].familyId", `Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj["familyId"]})`);
if (typeof extObj["targetId"] !== "string") throwValidation("extensions[].targetId", "Config.extensions items must have targetId: string");
if (extObj["targetId"] !== expectedTargetId) throwValidation("extensions[].targetId", `Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj["targetId"]})`);
if (typeof extObj["create"] !== "function") throwValidation("extensions[].create", "Config.extensions items must have create: function");
}

@@ -86,0 +86,0 @@ }

@@ -1,1 +0,1 @@

{"version":3,"file":"config-validation.mjs","names":[],"sources":["../src/errors.ts","../src/config-validation.ts"],"sourcesContent":["export class ConfigValidationError extends Error {\n readonly field: string;\n readonly why: string;\n\n constructor(field: string, why?: string) {\n super(why ?? `Config must have a \"${field}\" field`);\n this.name = 'ConfigValidationError';\n this.field = field;\n this.why = why ?? `Config must have a \"${field}\" field`;\n }\n}\n","import type { PrismaNextConfig } from './config-types';\nimport { ConfigValidationError } from './errors';\n\nfunction throwValidation(field: string, why?: string): never {\n throw new ConfigValidationError(field, why);\n}\n\nfunction validateContractConfig(contract: Record<string, unknown>): void {\n if (!Object.hasOwn(contract, 'source')) {\n throwValidation(\n 'contract.source',\n 'Config.contract.source is required when contract is provided',\n );\n }\n\n const source = contract['source'];\n if (!source || typeof source !== 'object') {\n throwValidation('contract.source', 'Config.contract.source must be a provider object');\n }\n\n const sourceConfig = source as Record<string, unknown>;\n const inputs = Object.hasOwn(sourceConfig, 'inputs') ? sourceConfig['inputs'] : undefined;\n\n if (inputs !== undefined) {\n if (!Array.isArray(inputs)) {\n throwValidation(\n 'contract.source.inputs',\n 'Config.contract.source.inputs must be an array of strings when provided',\n );\n }\n\n for (const input of inputs) {\n if (typeof input !== 'string') {\n throwValidation(\n 'contract.source.inputs[]',\n 'Config.contract.source.inputs must contain only strings',\n );\n }\n }\n }\n\n if (!Object.hasOwn(sourceConfig, 'load') || typeof sourceConfig['load'] !== 'function') {\n throwValidation('contract.source.load', 'Config.contract.source.load must be a function');\n }\n\n const output = Object.hasOwn(contract, 'output') ? contract['output'] : undefined;\n if (output !== undefined && typeof output !== 'string') {\n throwValidation('contract.output', 'Config.contract.output must be a string when provided');\n }\n}\n\n/**\n * Validates that the config has the required structure.\n * This is pure validation logic with no file I/O or CLI awareness.\n *\n * @param config - Config object to validate\n * @throws ConfigValidationError if config structure is invalid\n */\nexport function validateConfig(config: unknown): asserts config is PrismaNextConfig {\n if (!config || typeof config !== 'object') {\n throwValidation('object', 'Config must be an object');\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj['family']) {\n throwValidation('family');\n }\n\n if (!configObj['target']) {\n throwValidation('target');\n }\n\n if (!configObj['adapter']) {\n throwValidation('adapter');\n }\n\n // Validate family descriptor\n const family = configObj['family'] as Record<string, unknown>;\n if (family['kind'] !== 'family') {\n throwValidation('family.kind', 'Config.family must have kind: \"family\"');\n }\n if (typeof family['id'] !== 'string') {\n throwValidation('family.id', 'Config.family must have id: string');\n }\n if (typeof family['familyId'] !== 'string') {\n throwValidation('family.familyId', 'Config.family must have familyId: string');\n }\n if (typeof family['version'] !== 'string') {\n throwValidation('family.version', 'Config.family must have version: string');\n }\n if (!family['emission'] || typeof family['emission'] !== 'object') {\n throwValidation('family.emission', 'Config.family must have emission: EmissionSpi');\n }\n if (typeof family['create'] !== 'function') {\n throwValidation('family.create', 'Config.family must have create: function');\n }\n\n const familyId = family['familyId'] as string;\n\n // Validate target descriptor\n const target = configObj['target'] as Record<string, unknown>;\n if (target['kind'] !== 'target') {\n throwValidation('target.kind', 'Config.target must have kind: \"target\"');\n }\n if (typeof target['id'] !== 'string') {\n throwValidation('target.id', 'Config.target must have id: string');\n }\n if (typeof target['familyId'] !== 'string') {\n throwValidation('target.familyId', 'Config.target must have familyId: string');\n }\n if (typeof target['version'] !== 'string') {\n throwValidation('target.version', 'Config.target must have version: string');\n }\n if (target['familyId'] !== familyId) {\n throwValidation(\n 'target.familyId',\n `Config.target.familyId must match Config.family.familyId (expected: ${familyId}, got: ${target['familyId']})`,\n );\n }\n if (typeof target['targetId'] !== 'string') {\n throwValidation('target.targetId', 'Config.target must have targetId: string');\n }\n if (typeof target['create'] !== 'function') {\n throwValidation('target.create', 'Config.target must have create: function');\n }\n const expectedTargetId = target['targetId'] as string;\n\n // Validate adapter descriptor\n const adapter = configObj['adapter'] as Record<string, unknown>;\n if (adapter['kind'] !== 'adapter') {\n throwValidation('adapter.kind', 'Config.adapter must have kind: \"adapter\"');\n }\n if (typeof adapter['id'] !== 'string') {\n throwValidation('adapter.id', 'Config.adapter must have id: string');\n }\n if (typeof adapter['familyId'] !== 'string') {\n throwValidation('adapter.familyId', 'Config.adapter must have familyId: string');\n }\n if (typeof adapter['version'] !== 'string') {\n throwValidation('adapter.version', 'Config.adapter must have version: string');\n }\n if (adapter['familyId'] !== familyId) {\n throwValidation(\n 'adapter.familyId',\n `Config.adapter.familyId must match Config.family.familyId (expected: ${familyId}, got: ${adapter['familyId']})`,\n );\n }\n if (typeof adapter['targetId'] !== 'string') {\n throwValidation('adapter.targetId', 'Config.adapter must have targetId: string');\n }\n if (adapter['targetId'] !== expectedTargetId) {\n throwValidation(\n 'adapter.targetId',\n `Config.adapter.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${adapter['targetId']})`,\n );\n }\n if (typeof adapter['create'] !== 'function') {\n throwValidation('adapter.create', 'Config.adapter must have create: function');\n }\n\n if (configObj['extensions'] !== undefined) {\n throwValidation('extensions', 'Config.extensions is not supported; use Config.extensionPacks');\n }\n\n // Validate extensionPacks array if present\n if (configObj['extensionPacks'] !== undefined) {\n if (!Array.isArray(configObj['extensionPacks'])) {\n throwValidation('extensionPacks', 'Config.extensionPacks must be an array');\n }\n for (const ext of configObj['extensionPacks']) {\n if (!ext || typeof ext !== 'object') {\n throwValidation(\n 'extensionPacks[]',\n 'Config.extensionPacks must contain ControlExtensionDescriptor objects',\n );\n }\n const extObj = ext as Record<string, unknown>;\n if (extObj['kind'] !== 'extension') {\n throwValidation(\n 'extensionPacks[].kind',\n 'Config.extensionPacks items must have kind: \"extension\"',\n );\n }\n if (typeof extObj['id'] !== 'string') {\n throwValidation('extensionPacks[].id', 'Config.extensionPacks items must have id: string');\n }\n if (typeof extObj['familyId'] !== 'string') {\n throwValidation(\n 'extensionPacks[].familyId',\n 'Config.extensionPacks items must have familyId: string',\n );\n }\n if (typeof extObj['version'] !== 'string') {\n throwValidation(\n 'extensionPacks[].version',\n 'Config.extensionPacks items must have version: string',\n );\n }\n if (extObj['familyId'] !== familyId) {\n throwValidation(\n 'extensionPacks[].familyId',\n `Config.extensionPacks[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,\n );\n }\n if (typeof extObj['targetId'] !== 'string') {\n throwValidation(\n 'extensionPacks[].targetId',\n 'Config.extensionPacks items must have targetId: string',\n );\n }\n if (extObj['targetId'] !== expectedTargetId) {\n throwValidation(\n 'extensionPacks[].targetId',\n `Config.extensionPacks[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,\n );\n }\n if (typeof extObj['create'] !== 'function') {\n throwValidation(\n 'extensionPacks[].create',\n 'Config.extensionPacks items must have create: function',\n );\n }\n }\n }\n\n // Validate driver descriptor if present\n if (configObj['driver'] !== undefined) {\n const driver = configObj['driver'] as Record<string, unknown>;\n if (driver['kind'] !== 'driver') {\n throwValidation('driver.kind', 'Config.driver must have kind: \"driver\"');\n }\n if (typeof driver['id'] !== 'string') {\n throwValidation('driver.id', 'Config.driver must have id: string');\n }\n if (typeof driver['version'] !== 'string') {\n throwValidation('driver.version', 'Config.driver must have version: string');\n }\n if (typeof driver['familyId'] !== 'string') {\n throwValidation('driver.familyId', 'Config.driver must have familyId: string');\n }\n if (driver['familyId'] !== familyId) {\n throwValidation(\n 'driver.familyId',\n `Config.driver.familyId must match Config.family.familyId (expected: ${familyId}, got: ${driver['familyId']})`,\n );\n }\n if (typeof driver['targetId'] !== 'string') {\n throwValidation('driver.targetId', 'Config.driver must have targetId: string');\n }\n if (driver['targetId'] !== expectedTargetId) {\n throwValidation(\n 'driver.targetId',\n `Config.driver.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${driver['targetId']})`,\n );\n }\n if (typeof driver['create'] !== 'function') {\n throwValidation('driver.create', 'Config.driver must have create: function');\n }\n }\n\n // Validate contract config if present (structure validation - defineConfig() handles normalization)\n if (configObj['contract'] !== undefined) {\n const contract = configObj['contract'] as Record<string, unknown>;\n if (!contract || typeof contract !== 'object') {\n throwValidation('contract', 'Config.contract must be an object');\n }\n validateContractConfig(contract);\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"config-validation.mjs","names":[],"sources":["../src/errors.ts","../src/config-validation.ts"],"sourcesContent":["export class ConfigValidationError extends Error {\n readonly field: string;\n readonly why: string;\n\n constructor(field: string, why?: string) {\n super(why ?? `Config must have a \"${field}\" field`);\n this.name = 'ConfigValidationError';\n this.field = field;\n this.why = why ?? `Config must have a \"${field}\" field`;\n }\n}\n","import type { PrismaNextConfig } from './config-types';\nimport { ConfigValidationError } from './errors';\n\nfunction throwValidation(field: string, why?: string): never {\n throw new ConfigValidationError(field, why);\n}\n\nfunction validateContractConfig(contract: Record<string, unknown>): void {\n if (!Object.hasOwn(contract, 'source')) {\n throwValidation(\n 'contract.source',\n 'Config.contract.source is required when contract is provided',\n );\n }\n\n const source = contract['source'];\n if (!source || typeof source !== 'object') {\n throwValidation('contract.source', 'Config.contract.source must be a provider object');\n }\n\n const sourceConfig = source as Record<string, unknown>;\n const inputs = Object.hasOwn(sourceConfig, 'inputs') ? sourceConfig['inputs'] : undefined;\n\n if (inputs !== undefined) {\n if (!Array.isArray(inputs)) {\n throwValidation(\n 'contract.source.inputs',\n 'Config.contract.source.inputs must be an array of strings when provided',\n );\n }\n\n for (const input of inputs) {\n if (typeof input !== 'string') {\n throwValidation(\n 'contract.source.inputs[]',\n 'Config.contract.source.inputs must contain only strings',\n );\n }\n }\n }\n\n if (!Object.hasOwn(sourceConfig, 'load') || typeof sourceConfig['load'] !== 'function') {\n throwValidation('contract.source.load', 'Config.contract.source.load must be a function');\n }\n\n const output = Object.hasOwn(contract, 'output') ? contract['output'] : undefined;\n if (output !== undefined && typeof output !== 'string') {\n throwValidation('contract.output', 'Config.contract.output must be a string when provided');\n }\n}\n\n/**\n * Validates that the config has the required structure.\n * This is pure validation logic with no file I/O or CLI awareness.\n *\n * @param config - Config object to validate\n * @throws ConfigValidationError if config structure is invalid\n */\nexport function validateConfig(config: unknown): asserts config is PrismaNextConfig {\n if (!config || typeof config !== 'object') {\n throwValidation('object', 'Config must be an object');\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj['family']) {\n throwValidation('family');\n }\n\n if (!configObj['target']) {\n throwValidation('target');\n }\n\n if (!configObj['adapter']) {\n throwValidation('adapter');\n }\n\n // Validate family descriptor\n const family = configObj['family'] as Record<string, unknown>;\n if (family['kind'] !== 'family') {\n throwValidation('family.kind', 'Config.family must have kind: \"family\"');\n }\n if (typeof family['id'] !== 'string') {\n throwValidation('family.id', 'Config.family must have id: string');\n }\n if (typeof family['familyId'] !== 'string') {\n throwValidation('family.familyId', 'Config.family must have familyId: string');\n }\n if (typeof family['version'] !== 'string') {\n throwValidation('family.version', 'Config.family must have version: string');\n }\n if (!family['emission'] || typeof family['emission'] !== 'object') {\n throwValidation('family.emission', 'Config.family must have emission: EmissionSpi');\n }\n if (typeof family['create'] !== 'function') {\n throwValidation('family.create', 'Config.family must have create: function');\n }\n\n const familyId = family['familyId'] as string;\n\n // Validate target descriptor\n const target = configObj['target'] as Record<string, unknown>;\n if (target['kind'] !== 'target') {\n throwValidation('target.kind', 'Config.target must have kind: \"target\"');\n }\n if (typeof target['id'] !== 'string') {\n throwValidation('target.id', 'Config.target must have id: string');\n }\n if (typeof target['familyId'] !== 'string') {\n throwValidation('target.familyId', 'Config.target must have familyId: string');\n }\n if (typeof target['version'] !== 'string') {\n throwValidation('target.version', 'Config.target must have version: string');\n }\n if (target['familyId'] !== familyId) {\n throwValidation(\n 'target.familyId',\n `Config.target.familyId must match Config.family.familyId (expected: ${familyId}, got: ${target['familyId']})`,\n );\n }\n if (typeof target['targetId'] !== 'string') {\n throwValidation('target.targetId', 'Config.target must have targetId: string');\n }\n if (typeof target['create'] !== 'function') {\n throwValidation('target.create', 'Config.target must have create: function');\n }\n const expectedTargetId = target['targetId'] as string;\n\n // Validate adapter descriptor\n const adapter = configObj['adapter'] as Record<string, unknown>;\n if (adapter['kind'] !== 'adapter') {\n throwValidation('adapter.kind', 'Config.adapter must have kind: \"adapter\"');\n }\n if (typeof adapter['id'] !== 'string') {\n throwValidation('adapter.id', 'Config.adapter must have id: string');\n }\n if (typeof adapter['familyId'] !== 'string') {\n throwValidation('adapter.familyId', 'Config.adapter must have familyId: string');\n }\n if (typeof adapter['version'] !== 'string') {\n throwValidation('adapter.version', 'Config.adapter must have version: string');\n }\n if (adapter['familyId'] !== familyId) {\n throwValidation(\n 'adapter.familyId',\n `Config.adapter.familyId must match Config.family.familyId (expected: ${familyId}, got: ${adapter['familyId']})`,\n );\n }\n if (typeof adapter['targetId'] !== 'string') {\n throwValidation('adapter.targetId', 'Config.adapter must have targetId: string');\n }\n if (adapter['targetId'] !== expectedTargetId) {\n throwValidation(\n 'adapter.targetId',\n `Config.adapter.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${adapter['targetId']})`,\n );\n }\n if (typeof adapter['create'] !== 'function') {\n throwValidation('adapter.create', 'Config.adapter must have create: function');\n }\n\n if (configObj['extensionPacks'] !== undefined) {\n throwValidation(\n 'extensionPacks',\n 'Config.extensionPacks is no longer supported; rename it to Config.extensions',\n );\n }\n\n // Validate extensions array if present\n if (configObj['extensions'] !== undefined) {\n if (!Array.isArray(configObj['extensions'])) {\n throwValidation('extensions', 'Config.extensions must be an array');\n }\n for (const ext of configObj['extensions']) {\n if (!ext || typeof ext !== 'object') {\n throwValidation(\n 'extensions[]',\n 'Config.extensions must contain ControlExtensionDescriptor objects',\n );\n }\n const extObj = ext as Record<string, unknown>;\n if (extObj['kind'] !== 'extension') {\n throwValidation('extensions[].kind', 'Config.extensions items must have kind: \"extension\"');\n }\n if (typeof extObj['id'] !== 'string') {\n throwValidation('extensions[].id', 'Config.extensions items must have id: string');\n }\n if (typeof extObj['familyId'] !== 'string') {\n throwValidation(\n 'extensions[].familyId',\n 'Config.extensions items must have familyId: string',\n );\n }\n if (typeof extObj['version'] !== 'string') {\n throwValidation(\n 'extensions[].version',\n 'Config.extensions items must have version: string',\n );\n }\n if (extObj['familyId'] !== familyId) {\n throwValidation(\n 'extensions[].familyId',\n `Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,\n );\n }\n if (typeof extObj['targetId'] !== 'string') {\n throwValidation(\n 'extensions[].targetId',\n 'Config.extensions items must have targetId: string',\n );\n }\n if (extObj['targetId'] !== expectedTargetId) {\n throwValidation(\n 'extensions[].targetId',\n `Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,\n );\n }\n if (typeof extObj['create'] !== 'function') {\n throwValidation(\n 'extensions[].create',\n 'Config.extensions items must have create: function',\n );\n }\n }\n }\n\n // Validate driver descriptor if present\n if (configObj['driver'] !== undefined) {\n const driver = configObj['driver'] as Record<string, unknown>;\n if (driver['kind'] !== 'driver') {\n throwValidation('driver.kind', 'Config.driver must have kind: \"driver\"');\n }\n if (typeof driver['id'] !== 'string') {\n throwValidation('driver.id', 'Config.driver must have id: string');\n }\n if (typeof driver['version'] !== 'string') {\n throwValidation('driver.version', 'Config.driver must have version: string');\n }\n if (typeof driver['familyId'] !== 'string') {\n throwValidation('driver.familyId', 'Config.driver must have familyId: string');\n }\n if (driver['familyId'] !== familyId) {\n throwValidation(\n 'driver.familyId',\n `Config.driver.familyId must match Config.family.familyId (expected: ${familyId}, got: ${driver['familyId']})`,\n );\n }\n if (typeof driver['targetId'] !== 'string') {\n throwValidation('driver.targetId', 'Config.driver must have targetId: string');\n }\n if (driver['targetId'] !== expectedTargetId) {\n throwValidation(\n 'driver.targetId',\n `Config.driver.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${driver['targetId']})`,\n );\n }\n if (typeof driver['create'] !== 'function') {\n throwValidation('driver.create', 'Config.driver must have create: function');\n }\n }\n\n // Validate contract config if present (structure validation - defineConfig() handles normalization)\n if (configObj['contract'] !== undefined) {\n const contract = configObj['contract'] as Record<string, unknown>;\n if (!contract || typeof contract !== 'object') {\n throwValidation('contract', 'Config.contract must be an object');\n }\n validateContractConfig(contract);\n }\n}\n"],"mappings":"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"}
{
"name": "@prisma-next/config",
"version": "0.16.0-dev.19",
"version": "0.16.0-dev.21",
"license": "Apache-2.0",

@@ -9,5 +9,5 @@ "type": "module",

"dependencies": {
"@prisma-next/contract": "0.16.0-dev.19",
"@prisma-next/framework-components": "0.16.0-dev.19",
"@prisma-next/utils": "0.16.0-dev.19",
"@prisma-next/contract": "0.16.0-dev.21",
"@prisma-next/framework-components": "0.16.0-dev.21",
"@prisma-next/utils": "0.16.0-dev.21",
"arktype": "^2.2.2",

@@ -17,4 +17,4 @@ "pathe": "^2.0.3"

"devDependencies": {
"@prisma-next/tsconfig": "0.16.0-dev.19",
"@prisma-next/tsdown": "0.16.0-dev.19",
"@prisma-next/tsconfig": "0.16.0-dev.21",
"@prisma-next/tsdown": "0.16.0-dev.21",
"tsdown": "0.22.8",

@@ -21,0 +21,0 @@ "typescript": "5.9.3",

@@ -21,3 +21,3 @@ # @prisma-next/config

- Type-safe config composition for `family`, `target`, `adapter`, optional `driver`, and optional `extensionPacks` (`extensions` is rejected at runtime)
- Type-safe config composition for `family`, `target`, `adapter`, optional `driver`, and optional `extensions` (`extensions` is rejected at runtime)
- Contract source provider protocol (`contract.source`) and diagnostics shape

@@ -24,0 +24,0 @@ - Tool-agnostic provider input metadata for build integrations via `contract.source.inputs`

@@ -77,3 +77,3 @@ import type {

readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
readonly extensionPacks?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
/**

@@ -121,3 +121,3 @@ * Driver descriptor for DB-connected CLI commands.

export const ContractSourceProviderSchema = type({
'sourceFormat?': 'string',
'format?': 'string',
'inputs?': ContractSourceInputSchema.array(),

@@ -151,3 +151,3 @@ load: 'Function',

adapter: 'unknown', // ControlAdapterDescriptor - validated separately
'extensionPacks?': 'unknown[]',
'extensions?': 'unknown[]',
'driver?': 'unknown', // ControlDriverDescriptor - validated separately (optional)

@@ -154,0 +154,0 @@ 'db?': 'unknown',

@@ -162,16 +162,19 @@ import type { PrismaNextConfig } from './config-types';

if (configObj['extensions'] !== undefined) {
throwValidation('extensions', 'Config.extensions is not supported; use Config.extensionPacks');
if (configObj['extensionPacks'] !== undefined) {
throwValidation(
'extensionPacks',
'Config.extensionPacks is no longer supported; rename it to Config.extensions',
);
}
// Validate extensionPacks array if present
if (configObj['extensionPacks'] !== undefined) {
if (!Array.isArray(configObj['extensionPacks'])) {
throwValidation('extensionPacks', 'Config.extensionPacks must be an array');
// Validate extensions array if present
if (configObj['extensions'] !== undefined) {
if (!Array.isArray(configObj['extensions'])) {
throwValidation('extensions', 'Config.extensions must be an array');
}
for (const ext of configObj['extensionPacks']) {
for (const ext of configObj['extensions']) {
if (!ext || typeof ext !== 'object') {
throwValidation(
'extensionPacks[]',
'Config.extensionPacks must contain ControlExtensionDescriptor objects',
'extensions[]',
'Config.extensions must contain ControlExtensionDescriptor objects',
);

@@ -181,14 +184,11 @@ }

if (extObj['kind'] !== 'extension') {
throwValidation(
'extensionPacks[].kind',
'Config.extensionPacks items must have kind: "extension"',
);
throwValidation('extensions[].kind', 'Config.extensions items must have kind: "extension"');
}
if (typeof extObj['id'] !== 'string') {
throwValidation('extensionPacks[].id', 'Config.extensionPacks items must have id: string');
throwValidation('extensions[].id', 'Config.extensions items must have id: string');
}
if (typeof extObj['familyId'] !== 'string') {
throwValidation(
'extensionPacks[].familyId',
'Config.extensionPacks items must have familyId: string',
'extensions[].familyId',
'Config.extensions items must have familyId: string',
);

@@ -198,4 +198,4 @@ }

throwValidation(
'extensionPacks[].version',
'Config.extensionPacks items must have version: string',
'extensions[].version',
'Config.extensions items must have version: string',
);

@@ -205,4 +205,4 @@ }

throwValidation(
'extensionPacks[].familyId',
`Config.extensionPacks[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,
'extensions[].familyId',
`Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,
);

@@ -212,4 +212,4 @@ }

throwValidation(
'extensionPacks[].targetId',
'Config.extensionPacks items must have targetId: string',
'extensions[].targetId',
'Config.extensions items must have targetId: string',
);

@@ -219,4 +219,4 @@ }

throwValidation(
'extensionPacks[].targetId',
`Config.extensionPacks[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,
'extensions[].targetId',
`Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,
);

@@ -226,4 +226,4 @@ }

throwValidation(
'extensionPacks[].create',
'Config.extensionPacks items must have create: function',
'extensions[].create',
'Config.extensions items must have create: function',
);

@@ -230,0 +230,0 @@ }

@@ -41,3 +41,3 @@ import type { Contract } from '@prisma-next/contract/types';

export interface ContractSourceContext {
readonly composedExtensionPacks: readonly string[];
readonly composedExtensions: readonly string[];
/** Extension contracts keyed by space ID, required for cross-space FK resolution. */

@@ -63,7 +63,7 @@ readonly composedExtensionContracts: ReadonlyMap<string, Contract>;

export interface PslContractSourceProvider extends ContractSourceProviderBase {
readonly sourceFormat: 'psl';
readonly format: 'psl';
}
export interface TypeScriptContractSourceProvider extends ContractSourceProviderBase {
readonly sourceFormat: 'typescript';
readonly format: 'typescript';
}

@@ -73,3 +73,3 @@

* Third-party or unspecified source formats. Absent (or unrecognized)
* `sourceFormat` means format-aware tooling must leave the source untouched.
* `format` means format-aware tooling must leave the source untouched.
* Narrowing to a known format flows only through capability guards owned by

@@ -79,3 +79,3 @@ * the authoring layer.

export interface OpaqueContractSourceProvider extends ContractSourceProviderBase {
readonly sourceFormat?: string;
readonly format?: string;
}

@@ -82,0 +82,0 @@

import { AssembledAuthoringContributions, ControlAdapterDescriptor, ControlDriverDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyDescriptor, ControlMutationDefaults, ControlTargetDescriptor } from "@prisma-next/framework-components/control";
import { Contract } from "@prisma-next/contract/types";
import { CodecLookup } from "@prisma-next/framework-components/codec";
import { CapabilityMatrix } from "@prisma-next/framework-components/components";
import { Result } from "@prisma-next/utils/result";
//#region src/contract-source-types.d.ts
interface ContractSourceDiagnosticPosition {
readonly offset: number;
readonly line: number;
readonly column: number;
}
interface ContractSourceDiagnosticSpan {
readonly start: ContractSourceDiagnosticPosition;
readonly end: ContractSourceDiagnosticPosition;
}
interface ContractSourceDiagnostic {
readonly code: string;
readonly message: string;
readonly sourceId?: string;
readonly span?: ContractSourceDiagnosticSpan;
/**
* Optional structured payload for machine-readable consumers (agents,
* IDE extensions, CLI auto-fix). Human-readable prose lives in `message`;
* `data` carries the extracted facts (e.g. `{ namespace: 'pgvector' }`).
*/
readonly data?: Readonly<Record<string, unknown>>;
}
interface ContractSourceDiagnostics {
readonly summary: string;
readonly diagnostics: readonly ContractSourceDiagnostic[];
readonly meta?: Record<string, unknown>;
}
interface ContractSourceContext {
readonly composedExtensionPacks: readonly string[];
/** Extension contracts keyed by space ID, required for cross-space FK resolution. */
readonly composedExtensionContracts: ReadonlyMap<string, Contract>;
readonly authoringContributions: AssembledAuthoringContributions;
readonly codecLookup: CodecLookup;
readonly controlMutationDefaults: ControlMutationDefaults;
readonly resolvedInputs: readonly string[];
readonly capabilities: CapabilityMatrix;
}
/** Lets format-aware tooling avoid file-extension sniffing and opaque loader introspection. */
type ContractSourceFormat = 'psl' | 'typescript';
interface ContractSourceProviderBase {
readonly inputs?: readonly string[];
readonly load: (context: ContractSourceContext) => Promise<Result<Contract, ContractSourceDiagnostics>>;
}
interface PslContractSourceProvider extends ContractSourceProviderBase {
readonly sourceFormat: 'psl';
}
interface TypeScriptContractSourceProvider extends ContractSourceProviderBase {
readonly sourceFormat: 'typescript';
}
/**
* Third-party or unspecified source formats. Absent (or unrecognized)
* `sourceFormat` means format-aware tooling must leave the source untouched.
* Narrowing to a known format flows only through capability guards owned by
* the authoring layer.
*/
interface OpaqueContractSourceProvider extends ContractSourceProviderBase {
readonly sourceFormat?: string;
}
type ContractSourceProvider = PslContractSourceProvider | TypeScriptContractSourceProvider | OpaqueContractSourceProvider;
//#endregion
//#region src/config-types.d.ts
/**
* Contract configuration specifying source and artifact locations.
*/
interface ContractConfig {
/**
* Contract source provider. The provider is always async and must return
* a Result containing either a Contract or structured diagnostics.
*/
readonly source: ContractSourceProvider;
/**
* Path to contract.json artifact. Providers that know an input path (PSL,
* `typescriptContractFromPath`) derive an output colocated with that input
* so this rarely needs to be set explicitly. The `.d.ts` types file is
* always emitted next to the JSON (e.g., `contract.json` → `contract.d.ts`).
*/
readonly output?: string;
}
interface FormatterConfig {
readonly indent?: number | 'tab';
readonly newline?: 'LF' | 'CRLF';
}
/**
* Default *source* directory for the contract file the user authors at `init`
* time. Output artefacts colocate with source per the same rule path-bearing
* providers apply.
*/
declare const DEFAULT_CONTRACT_SOURCE_DIR = "src/prisma";
declare function normalizeContractConfig(contract: ContractConfig): ContractConfig & {
readonly output: string;
};
/**
* Configuration for Prisma Next CLI.
* Uses Control*Descriptor types for type-safe wiring with compile-time compatibility checks.
*
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
* @template TConnection - The driver connection input type (defaults to `unknown` for config flexibility)
*/
interface PrismaNextConfig<TFamilyId extends string = string, TTargetId extends string = string, TConnection = unknown> {
readonly family: ControlFamilyDescriptor<TFamilyId>;
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
readonly extensionPacks?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
/**
* Driver descriptor for DB-connected CLI commands.
* Required for DB-connected commands (e.g., db verify).
* Optional for commands that don't need database access (e.g., emit).
* The driver's connection type matches the TConnection config parameter.
*/
readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId, ControlDriverInstance<TFamilyId, TTargetId>, TConnection>;
/**
* Database connection configuration.
* The connection type is driver-specific (e.g., URL string for Postgres).
*/
readonly db?: {
/**
* Driver-specific connection input.
* For Postgres: a connection string (URL).
* For other drivers: may be a structured object.
*/
readonly connection?: TConnection;
};
/**
* Contract configuration. Specifies source and artifact locations.
* Required for emit command; optional for other commands that only read artifacts.
*/
readonly contract?: ContractConfig;
/**
* Migration configuration. Controls where on-disk migration packages are stored.
*/
readonly migrations?: {
/** Directory for migration packages, relative to config file. Defaults to 'migrations'. */
readonly dir?: string;
};
readonly formatter?: FormatterConfig;
}
/**
* Helper function to define a Prisma Next config.
* Validates and normalizes the config using Arktype, then returns the normalized IR.
*
* Normalization:
* - contract.output defaults to a path colocated with DEFAULT_CONTRACT_SOURCE_DIR
* when missing (in-memory-only providers)
*
* @param config - Raw config input from user
* @returns Normalized config IR with defaults applied
* @throws Error if config structure is invalid
*/
declare function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(config: PrismaNextConfig<TFamilyId, TTargetId>): PrismaNextConfig<TFamilyId, TTargetId>;
//#endregion
export { TypeScriptContractSourceProvider as _, defineConfig as a, ContractSourceDiagnostic as c, ContractSourceDiagnostics as d, ContractSourceFormat as f, PslContractSourceProvider as g, OpaqueContractSourceProvider as h, PrismaNextConfig as i, ContractSourceDiagnosticPosition as l, ContractSourceProviderBase as m, DEFAULT_CONTRACT_SOURCE_DIR as n, normalizeContractConfig as o, ContractSourceProvider as p, FormatterConfig as r, ContractSourceContext as s, ContractConfig as t, ContractSourceDiagnosticSpan as u };
//# sourceMappingURL=config-types-DtsiIT_O.d.mts.map
{"version":3,"file":"config-types-DtsiIT_O.d.mts","names":[],"sources":["../src/contract-source-types.ts","../src/config-types.ts"],"mappings":";;;;;;UASiB;WACN;WACA;WACA;;UAGM;WACN,OAAO;WACP,KAAK;;UAGC;WACN;WACA;WACA;WACA,OAAO;;;;;;WAMP,OAAO,SAAS;;UAGV;WACN;WACA,sBAAsB;WACtB,OAAO;;UAGD;WACN;;WAEA,4BAA4B,oBAAoB;WAChD,wBAAwB;WACxB,aAAa;WACb,yBAAyB;WACzB;WACA,cAAc;;;KAIb;UAEK;WACN;WACA,OACP,SAAS,0BACN,QAAQ,OAAO,UAAU;;UAGf,kCAAkC;WACxC;;UAGM,yCAAyC;WAC/C;;;;;;;;UASM,qCAAqC;WAC3C;;KAGC,yBACR,4BACA,mCACA;;;;;;UC7Da;;;;;WAKN,QAAQ;;;;;;;WAOR;;UAGM;WACN;WACA;;;;;;;cAQE;iBAEG,wBACd,UAAU,iBACT;WAA4B;;;;;;;;;;UAmBd,iBACf,mCACA,mCACA;WAES,QAAQ,wBAAwB;WAChC,QAAQ,wBAAwB,WAAW;WAC3C,SAAS,yBAAyB,WAAW;WAC7C,0BAA0B,2BAA2B,WAAW;;;;;;;WAOhE,SAAS,wBAChB,WACA,WACA,sBAAsB,WAAW,YACjC;;;;;WAMO;;;;;;aAME,aAAa;;;;;;WAMf,WAAW;;;;WAIX;;aAEE;;WAEF,YAAY;;;;;;;;;;;;;;iBAuDP,aAAa,mCAAmC,mCAC9D,QAAQ,iBAAiB,WAAW,aACnC,iBAAiB,WAAW"}