@prisma-next/core-control-plane 0.3.0-dev.34 → 0.3.0-dev.36
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/dist/{config-types-h9ifypQ0.d.mts → config-types-fYE9X8bc.d.mts} +3 -10
- package/dist/config-types-fYE9X8bc.d.mts.map +1 -0
- package/dist/config-types.d.mts +1 -1
- package/dist/config-types.mjs +2 -7
- package/dist/config-types.mjs.map +1 -1
- package/dist/config-validation.d.mts +1 -1
- package/dist/config-validation.mjs +0 -1
- package/dist/config-validation.mjs.map +1 -1
- package/dist/emission.d.mts +8 -4
- package/dist/emission.d.mts.map +1 -1
- package/dist/emission.mjs +53 -17
- package/dist/emission.mjs.map +1 -1
- package/dist/stack.d.mts +1 -1
- package/dist/{types-CsaU_uQP.d.mts → types-yiR2kXAj.d.mts} +14 -12
- package/dist/{types-CsaU_uQP.d.mts.map → types-yiR2kXAj.d.mts.map} +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +10 -5
- package/src/config-types.ts +1 -16
- package/src/config-validation.ts +0 -5
- package/src/emission/canonicalization.ts +34 -11
- package/src/emission/emit.ts +19 -5
- package/src/emission/hashing.ts +29 -9
- package/src/emission/types.ts +2 -1
- package/src/exports/emission.ts +1 -1
- package/src/migrations.ts +1 -1
- package/src/types.ts +16 -10
- package/dist/config-types-h9ifypQ0.d.mts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ControlExtensionDescriptor, i as ControlDriverInstance, r as ControlDriverDescriptor, s as ControlFamilyDescriptor, t as ControlAdapterDescriptor, u as ControlTargetDescriptor } from "./types-
|
|
1
|
+
import { a as ControlExtensionDescriptor, i as ControlDriverInstance, r as ControlDriverDescriptor, s as ControlFamilyDescriptor, t as ControlAdapterDescriptor, u as ControlTargetDescriptor } from "./types-yiR2kXAj.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/config-types.d.ts
|
|
4
4
|
|
|
@@ -13,15 +13,9 @@ interface ContractConfig {
|
|
|
13
13
|
readonly source: unknown | (() => unknown | Promise<unknown>);
|
|
14
14
|
/**
|
|
15
15
|
* Path to contract.json artifact. Defaults to 'src/prisma/contract.json'.
|
|
16
|
-
*
|
|
16
|
+
* The .d.ts types file will be colocated (e.g., contract.json → contract.d.ts).
|
|
17
17
|
*/
|
|
18
18
|
readonly output?: string;
|
|
19
|
-
/**
|
|
20
|
-
* Path to contract.d.ts artifact. Defaults to output with .d.ts extension.
|
|
21
|
-
* If output ends with .json, replaces .json with .d.ts.
|
|
22
|
-
* Otherwise, appends .d.ts to the directory containing output.
|
|
23
|
-
*/
|
|
24
|
-
readonly types?: string;
|
|
25
19
|
}
|
|
26
20
|
/**
|
|
27
21
|
* Configuration for Prisma Next CLI.
|
|
@@ -67,7 +61,6 @@ interface PrismaNextConfig<TFamilyId extends string = string, TTargetId extends
|
|
|
67
61
|
*
|
|
68
62
|
* Normalization:
|
|
69
63
|
* - contract.output defaults to 'src/prisma/contract.json' if missing
|
|
70
|
-
* - contract.types defaults to output with .d.ts extension if missing
|
|
71
64
|
*
|
|
72
65
|
* @param config - Raw config input from user
|
|
73
66
|
* @returns Normalized config IR with defaults applied
|
|
@@ -76,4 +69,4 @@ interface PrismaNextConfig<TFamilyId extends string = string, TTargetId extends
|
|
|
76
69
|
declare function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(config: PrismaNextConfig<TFamilyId, TTargetId>): PrismaNextConfig<TFamilyId, TTargetId>;
|
|
77
70
|
//#endregion
|
|
78
71
|
export { PrismaNextConfig as n, defineConfig as r, ContractConfig as t };
|
|
79
|
-
//# sourceMappingURL=config-types-
|
|
72
|
+
//# sourceMappingURL=config-types-fYE9X8bc.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-types-fYE9X8bc.d.mts","names":[],"sources":["../src/config-types.ts"],"sourcesContent":[],"mappings":";;;;;;;AA8CmB,UA3BF,cAAA,CA2BE;EAC0B;;;;EAC8B,SAAA,MAAA,EAAA,OAAA,GAAA,CAAA,GAAA,GAAA,OAAA,GAxB7B,OAwB6B,CAAA,OAAA,CAAA,CAAA;EAAtC;;;;EAUA,SAAA,MAAA,CAAA,EAAA,MAAA;;;;;;;AAwDrC;;;AACU,UA3EO,gBA2EP,CAAA,kBAAA,MAAA,GAAA,MAAA,EAAA,kBAAA,MAAA,GAAA,MAAA,EAAA,cAAA,OAAA,CAAA,CAAA;EACU,SAAA,MAAA,EAvED,uBAuEC,CAvEuB,SAuEvB,CAAA;EAAW,SAAA,MAAA,EAtEZ,uBAsEY,CAtEY,SAsEZ,EAtEuB,SAsEvB,CAAA;EAA5B,SAAA,OAAA,EArEiB,wBAqEjB,CArE0C,SAqE1C,EArEqD,SAqErD,CAAA;EAAgB,SAAA,cAAA,CAAA,EAAA,SApEkB,0BAoElB,CApE6C,SAoE7C,EApEwD,SAoExD,CAAA,EAAA;;;;;;;oBA7DC,wBAChB,WACA,WACA,sBAAsB,WAAW,YACjC;;;;;;;;;;;0BAYsB;;;;;;sBAMJ;;;;;;;;;;;;;iBAqCN,2FACN,iBAAiB,WAAW,aACnC,iBAAiB,WAAW"}
|
package/dist/config-types.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as PrismaNextConfig, r as defineConfig, t as ContractConfig } from "./config-types-
|
|
1
|
+
import { n as PrismaNextConfig, r as defineConfig, t as ContractConfig } from "./config-types-fYE9X8bc.mjs";
|
|
2
2
|
export { type ContractConfig, type PrismaNextConfig, defineConfig };
|
package/dist/config-types.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { dirname, join } from "node:path";
|
|
2
1
|
import { type } from "arktype";
|
|
3
2
|
|
|
4
3
|
//#region src/config-types.ts
|
|
@@ -8,8 +7,7 @@ import { type } from "arktype";
|
|
|
8
7
|
*/
|
|
9
8
|
const ContractConfigSchema = type({
|
|
10
9
|
source: "unknown",
|
|
11
|
-
"output?": "string"
|
|
12
|
-
"types?": "string"
|
|
10
|
+
"output?": "string"
|
|
13
11
|
});
|
|
14
12
|
/**
|
|
15
13
|
* Arktype schema for PrismaNextConfig validation.
|
|
@@ -30,7 +28,6 @@ const PrismaNextConfigSchema = type({
|
|
|
30
28
|
*
|
|
31
29
|
* Normalization:
|
|
32
30
|
* - contract.output defaults to 'src/prisma/contract.json' if missing
|
|
33
|
-
* - contract.types defaults to output with .d.ts extension if missing
|
|
34
31
|
*
|
|
35
32
|
* @param config - Raw config input from user
|
|
36
33
|
* @returns Normalized config IR with defaults applied
|
|
@@ -46,11 +43,9 @@ function defineConfig(config) {
|
|
|
46
43
|
const source = config.contract.source;
|
|
47
44
|
if (source !== null && typeof source !== "object" && typeof source !== "function" && typeof source !== "string" && typeof source !== "number" && typeof source !== "boolean") throw new Error("Config.contract.source must be a value (object, string, number, boolean, null) or a function");
|
|
48
45
|
const output = config.contract.output ?? "src/prisma/contract.json";
|
|
49
|
-
const types = config.contract.types ?? (output.endsWith(".json") ? `${output.slice(0, -5)}.d.ts` : join(dirname(output), "contract.d.ts"));
|
|
50
46
|
const normalizedContract = {
|
|
51
47
|
source: config.contract.source,
|
|
52
|
-
output
|
|
53
|
-
types
|
|
48
|
+
output
|
|
54
49
|
};
|
|
55
50
|
return {
|
|
56
51
|
...config,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-types.mjs","names":["normalizedContract: ContractConfig"],"sources":["../src/config-types.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"config-types.mjs","names":["normalizedContract: ContractConfig"],"sources":["../src/config-types.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type {\n ControlAdapterDescriptor,\n ControlDriverDescriptor,\n ControlDriverInstance,\n ControlExtensionDescriptor,\n ControlFamilyDescriptor,\n ControlTargetDescriptor,\n} from './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. Can be a value or a function that returns a value (sync or async).\n * If a function, it will be called to resolve the contract.\n */\n readonly source: unknown | (() => unknown | Promise<unknown>);\n /**\n * Path to contract.json artifact. Defaults to 'src/prisma/contract.json'.\n * The .d.ts types file will be colocated (e.g., contract.json → contract.d.ts).\n */\n readonly output?: string;\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\n/**\n * Arktype schema for ContractConfig validation.\n * Validates that source is present and output/types are strings when provided.\n */\nconst ContractConfigSchema = type({\n source: 'unknown', // Can be value or function - runtime check needed\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 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});\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 'src/prisma/contract.json' if missing\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 // Validate contract.source is a value or function (runtime check)\n const source = config.contract.source;\n if (\n source !== null &&\n typeof source !== 'object' &&\n typeof source !== 'function' &&\n typeof source !== 'string' &&\n typeof source !== 'number' &&\n typeof source !== 'boolean'\n ) {\n throw new Error(\n 'Config.contract.source must be a value (object, string, number, boolean, null) or a function',\n );\n }\n\n // Apply defaults\n const output = config.contract.output ?? 'src/prisma/contract.json';\n\n const normalizedContract: ContractConfig = {\n source: config.contract.source,\n output,\n };\n\n // Return normalized config\n return {\n ...config,\n contract: normalizedContract,\n };\n }\n\n // Return config as-is if no contract (preserve literal types)\n return config;\n}\n"],"mappings":";;;;;;;AAoFA,MAAM,uBAAuB,KAAK;CAChC,QAAQ;CACR,WAAW;CACZ,CAAC;;;;;AAMF,MAAM,yBAAyB,KAAK;CAClC,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,mBAAmB;CACnB,WAAW;CACX,OAAO;CACP,aAAa;CACd,CAAC;;;;;;;;;;;;AAaF,SAAgB,aACd,QACwC;CAExC,MAAM,YAAY,uBAAuB,OAAO;AAChD,KAAI,qBAAqB,KAAK,QAAQ;EACpC,MAAM,WAAW,UAAU,KAAK,MAA2B,EAAE,QAAQ,CAAC,KAAK,KAAK;AAChF,QAAM,IAAI,MAAM,6BAA6B,WAAW;;AAI1D,KAAI,OAAO,UAAU;EAEnB,MAAM,SAAS,OAAO,SAAS;AAC/B,MACE,WAAW,QACX,OAAO,WAAW,YAClB,OAAO,WAAW,cAClB,OAAO,WAAW,YAClB,OAAO,WAAW,YAClB,OAAO,WAAW,UAElB,OAAM,IAAI,MACR,+FACD;EAIH,MAAM,SAAS,OAAO,SAAS,UAAU;EAEzC,MAAMA,qBAAqC;GACzC,QAAQ,OAAO,SAAS;GACxB;GACD;AAGD,SAAO;GACL,GAAG;GACH,UAAU;GACX;;AAIH,QAAO"}
|
|
@@ -70,7 +70,6 @@ function validateConfig(config) {
|
|
|
70
70
|
if (!contract || typeof contract !== "object") throw errorConfigValidation("contract", { why: "Config.contract must be an object" });
|
|
71
71
|
if (!("source" in contract)) throw errorConfigValidation("contract.source", { why: "Config.contract.source is required when contract is provided" });
|
|
72
72
|
if (contract["output"] !== void 0 && typeof contract["output"] !== "string") throw errorConfigValidation("contract.output", { why: "Config.contract.output must be a string when provided" });
|
|
73
|
-
if (contract["types"] !== void 0 && typeof contract["types"] !== "string") throw errorConfigValidation("contract.types", { why: "Config.contract.types must be a string when provided" });
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-validation.mjs","names":[],"sources":["../src/config-validation.ts"],"sourcesContent":["import type { PrismaNextConfig } from './config-types';\nimport { errorConfigValidation } from './errors';\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 CliStructuredError if config structure is invalid\n */\nexport function validateConfig(config: unknown): asserts config is PrismaNextConfig {\n if (!config || typeof config !== 'object') {\n throw errorConfigValidation('object', {\n why: 'Config must be an object',\n });\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj['family']) {\n throw errorConfigValidation('family');\n }\n\n if (!configObj['target']) {\n throw errorConfigValidation('target');\n }\n\n if (!configObj['adapter']) {\n throw errorConfigValidation('adapter');\n }\n\n // Validate family descriptor\n const family = configObj['family'] as Record<string, unknown>;\n if (family['kind'] !== 'family') {\n throw errorConfigValidation('family.kind', {\n why: 'Config.family must have kind: \"family\"',\n });\n }\n if (typeof family['familyId'] !== 'string') {\n throw errorConfigValidation('family.familyId', {\n why: 'Config.family must have familyId: string',\n });\n }\n if (typeof family['version'] !== 'string') {\n throw errorConfigValidation('family.version', {\n why: 'Config.family must have version: string',\n });\n }\n if (!family['hook'] || typeof family['hook'] !== 'object') {\n throw errorConfigValidation('family.hook', {\n why: 'Config.family must have hook: TargetFamilyHook',\n });\n }\n if (typeof family['create'] !== 'function') {\n throw errorConfigValidation('family.create', {\n why: 'Config.family must have create: function',\n });\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 throw errorConfigValidation('target.kind', {\n why: 'Config.target must have kind: \"target\"',\n });\n }\n if (typeof target['id'] !== 'string') {\n throw errorConfigValidation('target.id', {\n why: 'Config.target must have id: string',\n });\n }\n if (typeof target['familyId'] !== 'string') {\n throw errorConfigValidation('target.familyId', {\n why: 'Config.target must have familyId: string',\n });\n }\n if (typeof target['version'] !== 'string') {\n throw errorConfigValidation('target.version', {\n why: 'Config.target must have version: string',\n });\n }\n if (target['familyId'] !== familyId) {\n throw errorConfigValidation('target.familyId', {\n why: `Config.target.familyId must match Config.family.familyId (expected: ${familyId}, got: ${target['familyId']})`,\n });\n }\n if (typeof target['targetId'] !== 'string') {\n throw errorConfigValidation('target.targetId', {\n why: 'Config.target must have targetId: string',\n });\n }\n if (typeof target['create'] !== 'function') {\n throw errorConfigValidation('target.create', {\n why: 'Config.target must have create: function',\n });\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 throw errorConfigValidation('adapter.kind', {\n why: 'Config.adapter must have kind: \"adapter\"',\n });\n }\n if (typeof adapter['id'] !== 'string') {\n throw errorConfigValidation('adapter.id', {\n why: 'Config.adapter must have id: string',\n });\n }\n if (typeof adapter['familyId'] !== 'string') {\n throw errorConfigValidation('adapter.familyId', {\n why: 'Config.adapter must have familyId: string',\n });\n }\n if (typeof adapter['version'] !== 'string') {\n throw errorConfigValidation('adapter.version', {\n why: 'Config.adapter must have version: string',\n });\n }\n if (adapter['familyId'] !== familyId) {\n throw errorConfigValidation('adapter.familyId', {\n why: `Config.adapter.familyId must match Config.family.familyId (expected: ${familyId}, got: ${adapter['familyId']})`,\n });\n }\n if (typeof adapter['targetId'] !== 'string') {\n throw errorConfigValidation('adapter.targetId', {\n why: 'Config.adapter must have targetId: string',\n });\n }\n if (adapter['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('adapter.targetId', {\n why: `Config.adapter.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${adapter['targetId']})`,\n });\n }\n if (typeof adapter['create'] !== 'function') {\n throw errorConfigValidation('adapter.create', {\n why: 'Config.adapter must have create: function',\n });\n }\n\n // Validate extensions array if present\n if (configObj['extensions'] !== undefined) {\n if (!Array.isArray(configObj['extensions'])) {\n throw errorConfigValidation('extensions', {\n why: 'Config.extensions must be an array',\n });\n }\n for (const ext of configObj['extensions']) {\n if (!ext || typeof ext !== 'object') {\n throw errorConfigValidation('extensions[]', {\n why: 'Config.extensions must contain ExtensionDescriptor objects',\n });\n }\n const extObj = ext as Record<string, unknown>;\n if (extObj['kind'] !== 'extension') {\n throw errorConfigValidation('extensions[].kind', {\n why: 'Config.extensions items must have kind: \"extension\"',\n });\n }\n if (typeof extObj['id'] !== 'string') {\n throw errorConfigValidation('extensions[].id', {\n why: 'Config.extensions items must have id: string',\n });\n }\n if (typeof extObj['familyId'] !== 'string') {\n throw errorConfigValidation('extensions[].familyId', {\n why: 'Config.extensions items must have familyId: string',\n });\n }\n if (typeof extObj['version'] !== 'string') {\n throw errorConfigValidation('extensions[].version', {\n why: 'Config.extensions items must have version: string',\n });\n }\n if (extObj['familyId'] !== familyId) {\n throw errorConfigValidation('extensions[].familyId', {\n why: `Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,\n });\n }\n if (typeof extObj['targetId'] !== 'string') {\n throw errorConfigValidation('extensions[].targetId', {\n why: 'Config.extensions items must have targetId: string',\n });\n }\n if (extObj['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('extensions[].targetId', {\n why: `Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,\n });\n }\n if (typeof extObj['create'] !== 'function') {\n throw errorConfigValidation('extensions[].create', {\n why: '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 throw errorConfigValidation('driver.kind', {\n why: 'Config.driver must have kind: \"driver\"',\n });\n }\n if (typeof driver['id'] !== 'string') {\n throw errorConfigValidation('driver.id', {\n why: 'Config.driver must have id: string',\n });\n }\n if (typeof driver['version'] !== 'string') {\n throw errorConfigValidation('driver.version', {\n why: 'Config.driver must have version: string',\n });\n }\n if (typeof driver['familyId'] !== 'string') {\n throw errorConfigValidation('driver.familyId', {\n why: 'Config.driver must have familyId: string',\n });\n }\n if (driver['familyId'] !== familyId) {\n throw errorConfigValidation('driver.familyId', {\n why: `Config.driver.familyId must match Config.family.familyId (expected: ${familyId}, got: ${driver['familyId']})`,\n });\n }\n if (typeof driver['targetId'] !== 'string') {\n throw errorConfigValidation('driver.targetId', {\n why: 'Config.driver must have targetId: string',\n });\n }\n if (driver['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('driver.targetId', {\n why: `Config.driver.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${driver['targetId']})`,\n });\n }\n if (typeof driver['create'] !== 'function') {\n throw errorConfigValidation('driver.create', {\n why: 'Config.driver must have create: function',\n });\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 throw errorConfigValidation('contract', {\n why: 'Config.contract must be an object',\n });\n }\n if (!('source' in contract)) {\n throw errorConfigValidation('contract.source', {\n why: 'Config.contract.source is required when contract is provided',\n });\n }\n if (contract['output'] !== undefined && typeof contract['output'] !== 'string') {\n throw errorConfigValidation('contract.output', {\n why: 'Config.contract.output must be a string when provided',\n });\n }\n if (contract['types'] !== undefined && typeof contract['types'] !== 'string') {\n throw errorConfigValidation('contract.types', {\n why: 'Config.contract.types must be a string when provided',\n });\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAgB,eAAe,QAAqD;AAClF,KAAI,CAAC,UAAU,OAAO,WAAW,SAC/B,OAAM,sBAAsB,UAAU,EACpC,KAAK,4BACN,CAAC;CAGJ,MAAM,YAAY;AAElB,KAAI,CAAC,UAAU,UACb,OAAM,sBAAsB,SAAS;AAGvC,KAAI,CAAC,UAAU,UACb,OAAM,sBAAsB,SAAS;AAGvC,KAAI,CAAC,UAAU,WACb,OAAM,sBAAsB,UAAU;CAIxC,MAAM,SAAS,UAAU;AACzB,KAAI,OAAO,YAAY,SACrB,OAAM,sBAAsB,eAAe,EACzC,KAAK,4CACN,CAAC;AAEJ,KAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,4CACN,CAAC;AAEJ,KAAI,OAAO,OAAO,eAAe,SAC/B,OAAM,sBAAsB,kBAAkB,EAC5C,KAAK,2CACN,CAAC;AAEJ,KAAI,CAAC,OAAO,WAAW,OAAO,OAAO,YAAY,SAC/C,OAAM,sBAAsB,eAAe,EACzC,KAAK,kDACN,CAAC;AAEJ,KAAI,OAAO,OAAO,cAAc,WAC9B,OAAM,sBAAsB,iBAAiB,EAC3C,KAAK,4CACN,CAAC;CAGJ,MAAM,WAAW,OAAO;CAGxB,MAAM,SAAS,UAAU;AACzB,KAAI,OAAO,YAAY,SACrB,OAAM,sBAAsB,eAAe,EACzC,KAAK,4CACN,CAAC;AAEJ,KAAI,OAAO,OAAO,UAAU,SAC1B,OAAM,sBAAsB,aAAa,EACvC,KAAK,sCACN,CAAC;AAEJ,KAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,4CACN,CAAC;AAEJ,KAAI,OAAO,OAAO,eAAe,SAC/B,OAAM,sBAAsB,kBAAkB,EAC5C,KAAK,2CACN,CAAC;AAEJ,KAAI,OAAO,gBAAgB,SACzB,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,uEAAuE,SAAS,SAAS,OAAO,YAAY,IAClH,CAAC;AAEJ,KAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,4CACN,CAAC;AAEJ,KAAI,OAAO,OAAO,cAAc,WAC9B,OAAM,sBAAsB,iBAAiB,EAC3C,KAAK,4CACN,CAAC;CAEJ,MAAM,mBAAmB,OAAO;CAGhC,MAAM,UAAU,UAAU;AAC1B,KAAI,QAAQ,YAAY,UACtB,OAAM,sBAAsB,gBAAgB,EAC1C,KAAK,8CACN,CAAC;AAEJ,KAAI,OAAO,QAAQ,UAAU,SAC3B,OAAM,sBAAsB,cAAc,EACxC,KAAK,uCACN,CAAC;AAEJ,KAAI,OAAO,QAAQ,gBAAgB,SACjC,OAAM,sBAAsB,oBAAoB,EAC9C,KAAK,6CACN,CAAC;AAEJ,KAAI,OAAO,QAAQ,eAAe,SAChC,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,4CACN,CAAC;AAEJ,KAAI,QAAQ,gBAAgB,SAC1B,OAAM,sBAAsB,oBAAoB,EAC9C,KAAK,wEAAwE,SAAS,SAAS,QAAQ,YAAY,IACpH,CAAC;AAEJ,KAAI,OAAO,QAAQ,gBAAgB,SACjC,OAAM,sBAAsB,oBAAoB,EAC9C,KAAK,6CACN,CAAC;AAEJ,KAAI,QAAQ,gBAAgB,iBAC1B,OAAM,sBAAsB,oBAAoB,EAC9C,KAAK,wEAAwE,iBAAiB,SAAS,QAAQ,YAAY,IAC5H,CAAC;AAEJ,KAAI,OAAO,QAAQ,cAAc,WAC/B,OAAM,sBAAsB,kBAAkB,EAC5C,KAAK,6CACN,CAAC;AAIJ,KAAI,UAAU,kBAAkB,QAAW;AACzC,MAAI,CAAC,MAAM,QAAQ,UAAU,cAAc,CACzC,OAAM,sBAAsB,cAAc,EACxC,KAAK,sCACN,CAAC;AAEJ,OAAK,MAAM,OAAO,UAAU,eAAe;AACzC,OAAI,CAAC,OAAO,OAAO,QAAQ,SACzB,OAAM,sBAAsB,gBAAgB,EAC1C,KAAK,8DACN,CAAC;GAEJ,MAAM,SAAS;AACf,OAAI,OAAO,YAAY,YACrB,OAAM,sBAAsB,qBAAqB,EAC/C,KAAK,yDACN,CAAC;AAEJ,OAAI,OAAO,OAAO,UAAU,SAC1B,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,gDACN,CAAC;AAEJ,OAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,yBAAyB,EACnD,KAAK,sDACN,CAAC;AAEJ,OAAI,OAAO,OAAO,eAAe,SAC/B,OAAM,sBAAsB,wBAAwB,EAClD,KAAK,qDACN,CAAC;AAEJ,OAAI,OAAO,gBAAgB,SACzB,OAAM,sBAAsB,yBAAyB,EACnD,KAAK,6EAA6E,SAAS,SAAS,OAAO,YAAY,IACxH,CAAC;AAEJ,OAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,yBAAyB,EACnD,KAAK,sDACN,CAAC;AAEJ,OAAI,OAAO,gBAAgB,iBACzB,OAAM,sBAAsB,yBAAyB,EACnD,KAAK,6EAA6E,iBAAiB,SAAS,OAAO,YAAY,IAChI,CAAC;AAEJ,OAAI,OAAO,OAAO,cAAc,WAC9B,OAAM,sBAAsB,uBAAuB,EACjD,KAAK,sDACN,CAAC;;;AAMR,KAAI,UAAU,cAAc,QAAW;EACrC,MAAM,SAAS,UAAU;AACzB,MAAI,OAAO,YAAY,SACrB,OAAM,sBAAsB,eAAe,EACzC,KAAK,4CACN,CAAC;AAEJ,MAAI,OAAO,OAAO,UAAU,SAC1B,OAAM,sBAAsB,aAAa,EACvC,KAAK,sCACN,CAAC;AAEJ,MAAI,OAAO,OAAO,eAAe,SAC/B,OAAM,sBAAsB,kBAAkB,EAC5C,KAAK,2CACN,CAAC;AAEJ,MAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,4CACN,CAAC;AAEJ,MAAI,OAAO,gBAAgB,SACzB,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,uEAAuE,SAAS,SAAS,OAAO,YAAY,IAClH,CAAC;AAEJ,MAAI,OAAO,OAAO,gBAAgB,SAChC,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,4CACN,CAAC;AAEJ,MAAI,OAAO,gBAAgB,iBACzB,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,uEAAuE,iBAAiB,SAAS,OAAO,YAAY,IAC1H,CAAC;AAEJ,MAAI,OAAO,OAAO,cAAc,WAC9B,OAAM,sBAAsB,iBAAiB,EAC3C,KAAK,4CACN,CAAC;;AAKN,KAAI,UAAU,gBAAgB,QAAW;EACvC,MAAM,WAAW,UAAU;AAC3B,MAAI,CAAC,YAAY,OAAO,aAAa,SACnC,OAAM,sBAAsB,YAAY,EACtC,KAAK,qCACN,CAAC;AAEJ,MAAI,EAAE,YAAY,UAChB,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,gEACN,CAAC;AAEJ,MAAI,SAAS,cAAc,UAAa,OAAO,SAAS,cAAc,SACpE,OAAM,sBAAsB,mBAAmB,EAC7C,KAAK,yDACN,CAAC;AAEJ,MAAI,SAAS,aAAa,UAAa,OAAO,SAAS,aAAa,SAClE,OAAM,sBAAsB,kBAAkB,EAC5C,KAAK,wDACN,CAAC"}
|
|
1
|
+
{"version":3,"file":"config-validation.mjs","names":[],"sources":["../src/config-validation.ts"],"sourcesContent":["import type { PrismaNextConfig } from './config-types';\nimport { errorConfigValidation } from './errors';\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 CliStructuredError if config structure is invalid\n */\nexport function validateConfig(config: unknown): asserts config is PrismaNextConfig {\n if (!config || typeof config !== 'object') {\n throw errorConfigValidation('object', {\n why: 'Config must be an object',\n });\n }\n\n const configObj = config as Record<string, unknown>;\n\n if (!configObj['family']) {\n throw errorConfigValidation('family');\n }\n\n if (!configObj['target']) {\n throw errorConfigValidation('target');\n }\n\n if (!configObj['adapter']) {\n throw errorConfigValidation('adapter');\n }\n\n // Validate family descriptor\n const family = configObj['family'] as Record<string, unknown>;\n if (family['kind'] !== 'family') {\n throw errorConfigValidation('family.kind', {\n why: 'Config.family must have kind: \"family\"',\n });\n }\n if (typeof family['familyId'] !== 'string') {\n throw errorConfigValidation('family.familyId', {\n why: 'Config.family must have familyId: string',\n });\n }\n if (typeof family['version'] !== 'string') {\n throw errorConfigValidation('family.version', {\n why: 'Config.family must have version: string',\n });\n }\n if (!family['hook'] || typeof family['hook'] !== 'object') {\n throw errorConfigValidation('family.hook', {\n why: 'Config.family must have hook: TargetFamilyHook',\n });\n }\n if (typeof family['create'] !== 'function') {\n throw errorConfigValidation('family.create', {\n why: 'Config.family must have create: function',\n });\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 throw errorConfigValidation('target.kind', {\n why: 'Config.target must have kind: \"target\"',\n });\n }\n if (typeof target['id'] !== 'string') {\n throw errorConfigValidation('target.id', {\n why: 'Config.target must have id: string',\n });\n }\n if (typeof target['familyId'] !== 'string') {\n throw errorConfigValidation('target.familyId', {\n why: 'Config.target must have familyId: string',\n });\n }\n if (typeof target['version'] !== 'string') {\n throw errorConfigValidation('target.version', {\n why: 'Config.target must have version: string',\n });\n }\n if (target['familyId'] !== familyId) {\n throw errorConfigValidation('target.familyId', {\n why: `Config.target.familyId must match Config.family.familyId (expected: ${familyId}, got: ${target['familyId']})`,\n });\n }\n if (typeof target['targetId'] !== 'string') {\n throw errorConfigValidation('target.targetId', {\n why: 'Config.target must have targetId: string',\n });\n }\n if (typeof target['create'] !== 'function') {\n throw errorConfigValidation('target.create', {\n why: 'Config.target must have create: function',\n });\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 throw errorConfigValidation('adapter.kind', {\n why: 'Config.adapter must have kind: \"adapter\"',\n });\n }\n if (typeof adapter['id'] !== 'string') {\n throw errorConfigValidation('adapter.id', {\n why: 'Config.adapter must have id: string',\n });\n }\n if (typeof adapter['familyId'] !== 'string') {\n throw errorConfigValidation('adapter.familyId', {\n why: 'Config.adapter must have familyId: string',\n });\n }\n if (typeof adapter['version'] !== 'string') {\n throw errorConfigValidation('adapter.version', {\n why: 'Config.adapter must have version: string',\n });\n }\n if (adapter['familyId'] !== familyId) {\n throw errorConfigValidation('adapter.familyId', {\n why: `Config.adapter.familyId must match Config.family.familyId (expected: ${familyId}, got: ${adapter['familyId']})`,\n });\n }\n if (typeof adapter['targetId'] !== 'string') {\n throw errorConfigValidation('adapter.targetId', {\n why: 'Config.adapter must have targetId: string',\n });\n }\n if (adapter['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('adapter.targetId', {\n why: `Config.adapter.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${adapter['targetId']})`,\n });\n }\n if (typeof adapter['create'] !== 'function') {\n throw errorConfigValidation('adapter.create', {\n why: 'Config.adapter must have create: function',\n });\n }\n\n // Validate extensions array if present\n if (configObj['extensions'] !== undefined) {\n if (!Array.isArray(configObj['extensions'])) {\n throw errorConfigValidation('extensions', {\n why: 'Config.extensions must be an array',\n });\n }\n for (const ext of configObj['extensions']) {\n if (!ext || typeof ext !== 'object') {\n throw errorConfigValidation('extensions[]', {\n why: 'Config.extensions must contain ExtensionDescriptor objects',\n });\n }\n const extObj = ext as Record<string, unknown>;\n if (extObj['kind'] !== 'extension') {\n throw errorConfigValidation('extensions[].kind', {\n why: 'Config.extensions items must have kind: \"extension\"',\n });\n }\n if (typeof extObj['id'] !== 'string') {\n throw errorConfigValidation('extensions[].id', {\n why: 'Config.extensions items must have id: string',\n });\n }\n if (typeof extObj['familyId'] !== 'string') {\n throw errorConfigValidation('extensions[].familyId', {\n why: 'Config.extensions items must have familyId: string',\n });\n }\n if (typeof extObj['version'] !== 'string') {\n throw errorConfigValidation('extensions[].version', {\n why: 'Config.extensions items must have version: string',\n });\n }\n if (extObj['familyId'] !== familyId) {\n throw errorConfigValidation('extensions[].familyId', {\n why: `Config.extensions[].familyId must match Config.family.familyId (expected: ${familyId}, got: ${extObj['familyId']})`,\n });\n }\n if (typeof extObj['targetId'] !== 'string') {\n throw errorConfigValidation('extensions[].targetId', {\n why: 'Config.extensions items must have targetId: string',\n });\n }\n if (extObj['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('extensions[].targetId', {\n why: `Config.extensions[].targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${extObj['targetId']})`,\n });\n }\n if (typeof extObj['create'] !== 'function') {\n throw errorConfigValidation('extensions[].create', {\n why: '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 throw errorConfigValidation('driver.kind', {\n why: 'Config.driver must have kind: \"driver\"',\n });\n }\n if (typeof driver['id'] !== 'string') {\n throw errorConfigValidation('driver.id', {\n why: 'Config.driver must have id: string',\n });\n }\n if (typeof driver['version'] !== 'string') {\n throw errorConfigValidation('driver.version', {\n why: 'Config.driver must have version: string',\n });\n }\n if (typeof driver['familyId'] !== 'string') {\n throw errorConfigValidation('driver.familyId', {\n why: 'Config.driver must have familyId: string',\n });\n }\n if (driver['familyId'] !== familyId) {\n throw errorConfigValidation('driver.familyId', {\n why: `Config.driver.familyId must match Config.family.familyId (expected: ${familyId}, got: ${driver['familyId']})`,\n });\n }\n if (typeof driver['targetId'] !== 'string') {\n throw errorConfigValidation('driver.targetId', {\n why: 'Config.driver must have targetId: string',\n });\n }\n if (driver['targetId'] !== expectedTargetId) {\n throw errorConfigValidation('driver.targetId', {\n why: `Config.driver.targetId must match Config.target.targetId (expected: ${expectedTargetId}, got: ${driver['targetId']})`,\n });\n }\n if (typeof driver['create'] !== 'function') {\n throw errorConfigValidation('driver.create', {\n why: 'Config.driver must have create: function',\n });\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 throw errorConfigValidation('contract', {\n why: 'Config.contract must be an object',\n });\n }\n if (!('source' in contract)) {\n throw errorConfigValidation('contract.source', {\n why: 'Config.contract.source is required when contract is provided',\n });\n }\n if (contract['output'] !== undefined && typeof contract['output'] !== 'string') {\n throw errorConfigValidation('contract.output', {\n why: 'Config.contract.output must be a string when provided',\n });\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/emission.d.mts
CHANGED
|
@@ -4,7 +4,8 @@ import { OperationRegistry } from "@prisma-next/operations";
|
|
|
4
4
|
|
|
5
5
|
//#region src/emission/canonicalization.d.ts
|
|
6
6
|
declare function canonicalizeContract(ir: ContractIR & {
|
|
7
|
-
|
|
7
|
+
storageHash?: string;
|
|
8
|
+
executionHash?: string;
|
|
8
9
|
profileHash?: string;
|
|
9
10
|
}): string;
|
|
10
11
|
//#endregion
|
|
@@ -29,7 +30,8 @@ interface EmitOptions {
|
|
|
29
30
|
interface EmitResult {
|
|
30
31
|
readonly contractJson: string;
|
|
31
32
|
readonly contractDts: string;
|
|
32
|
-
readonly
|
|
33
|
+
readonly storageHash: string;
|
|
34
|
+
readonly executionHash?: string;
|
|
33
35
|
readonly profileHash: string;
|
|
34
36
|
}
|
|
35
37
|
//#endregion
|
|
@@ -44,14 +46,16 @@ type ContractInput = {
|
|
|
44
46
|
models: Record<string, unknown>;
|
|
45
47
|
relations: Record<string, unknown>;
|
|
46
48
|
storage: Record<string, unknown>;
|
|
49
|
+
execution?: Record<string, unknown>;
|
|
47
50
|
extensionPacks: Record<string, unknown>;
|
|
48
51
|
sources: Record<string, unknown>;
|
|
49
52
|
capabilities: Record<string, Record<string, boolean>>;
|
|
50
53
|
meta: Record<string, unknown>;
|
|
51
54
|
[key: string]: unknown;
|
|
52
55
|
};
|
|
53
|
-
declare function
|
|
56
|
+
declare function computeStorageHash(contract: ContractInput): string;
|
|
54
57
|
declare function computeProfileHash(contract: ContractInput): string;
|
|
58
|
+
declare function computeExecutionHash(contract: ContractInput): string;
|
|
55
59
|
//#endregion
|
|
56
|
-
export { type EmitOptions, type EmitResult, canonicalizeContract,
|
|
60
|
+
export { type EmitOptions, type EmitResult, canonicalizeContract, computeExecutionHash, computeProfileHash, computeStorageHash, emit };
|
|
57
61
|
//# sourceMappingURL=emission.d.mts.map
|
package/dist/emission.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emission.d.mts","names":[],"sources":["../src/emission/canonicalization.ts","../src/emission/types.ts","../src/emission/emit.ts","../src/emission/hashing.ts"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"emission.d.mts","names":[],"sources":["../src/emission/canonicalization.ts","../src/emission/types.ts","../src/emission/emit.ts","../src/emission/hashing.ts"],"sourcesContent":[],"mappings":";;;;;iBAqPgB,oBAAA,KACV;;;;AADN,CAAA,CAAA,EAAgB,MAAA;;;UClPC,WAAA;;+BAEc;EDgPf,SAAA,gBAAoB,CAAA,EC/ON,aDgPxB,CChPsC,eDgP5B,CAAA;kCC/OkB,cAAc;0BACtB;;AAL1B;;;EAG8B,SAAA,sBAAA,CAAA,EAOM,GAPN,CAAA,MAAA,EAOkB,eAPlB,CAAA;EACkB;;;;EAMZ,SAAA,wBAAA,CAAA,EAKE,aALF,CAKgB,eALhB,CAAA;;AAKE,UAGrB,UAAA,CAHqB;EAAa,SAAA,YAAA,EAAA,MAAA;EAGlC,SAAA,WAAU,EAAA,MAAA;;;;ACoB3B;;;iBAAsB,IAAA,KAChB,qBACK,2BACK,mBACb,QAAQ;;;KCxCN,aAAA;;;;UAIK;EH4OM,SAAA,EG3OH,MH2OG,CAAA,MAAoB,EAAA,OAAA,CAAA;WG1OzB;cACG;kBACI;EFVD,OAAA,EEWN,MFXiB,CAAA,MAAA,EAAA,OAAA,CAAA;EAEG,YAAA,EEUf,MFVe,CAAA,MAAA,EEUA,MFVA,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EACa,IAAA,EEUpC,MFVoC,CAAA,MAAA,EAAA,OAAA,CAAA;EAAd,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAA;CACkB;AAAd,iBEmBlB,kBAAA,CFnBkB,QAAA,EEmBW,aFnBX,CAAA,EAAA,MAAA;AACR,iBEmCV,kBAAA,CFnCU,QAAA,EEmCmB,aFnCnB,CAAA,EAAA,MAAA;AAKsB,iBE+ChC,oBAAA,CF/CgC,QAAA,EE+CD,aF/CC,CAAA,EAAA,MAAA"}
|
package/dist/emission.mjs
CHANGED
|
@@ -9,10 +9,12 @@ const TOP_LEVEL_ORDER = [
|
|
|
9
9
|
"canonicalVersion",
|
|
10
10
|
"targetFamily",
|
|
11
11
|
"target",
|
|
12
|
-
"
|
|
12
|
+
"storageHash",
|
|
13
|
+
"executionHash",
|
|
13
14
|
"profileHash",
|
|
14
15
|
"models",
|
|
15
16
|
"storage",
|
|
17
|
+
"execution",
|
|
16
18
|
"capabilities",
|
|
17
19
|
"extensionPacks",
|
|
18
20
|
"meta",
|
|
@@ -32,7 +34,11 @@ function omitDefaults(obj, path) {
|
|
|
32
34
|
for (const [key, value] of Object.entries(obj)) {
|
|
33
35
|
const currentPath = [...path, key];
|
|
34
36
|
if (key === "_generated") continue;
|
|
35
|
-
if (key === "nullable" && value === false)
|
|
37
|
+
if (key === "nullable" && value === false) {
|
|
38
|
+
if (!Object.hasOwn(obj, "default")) continue;
|
|
39
|
+
result[key] = value;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
36
42
|
if (key === "generated" && value === false) continue;
|
|
37
43
|
if (isDefaultValue(value)) {
|
|
38
44
|
const isRequiredModels = isArrayEqual(currentPath, ["models"]);
|
|
@@ -42,6 +48,11 @@ function omitDefaults(obj, path) {
|
|
|
42
48
|
const isRequiredCapabilities = isArrayEqual(currentPath, ["capabilities"]);
|
|
43
49
|
const isRequiredMeta = isArrayEqual(currentPath, ["meta"]);
|
|
44
50
|
const isRequiredSources = isArrayEqual(currentPath, ["sources"]);
|
|
51
|
+
const isRequiredExecutionDefaults = isArrayEqual(currentPath, [
|
|
52
|
+
"execution",
|
|
53
|
+
"mutations",
|
|
54
|
+
"defaults"
|
|
55
|
+
]);
|
|
45
56
|
const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === "extensionPacks";
|
|
46
57
|
const isModelRelations = currentPath.length === 3 && isArrayEqual([currentPath[0], currentPath[2]], ["models", "relations"]);
|
|
47
58
|
const isTableUniques = currentPath.length === 4 && isArrayEqual([
|
|
@@ -71,10 +82,11 @@ function omitDefaults(obj, path) {
|
|
|
71
82
|
"tables",
|
|
72
83
|
"foreignKeys"
|
|
73
84
|
]);
|
|
74
|
-
if (!isRequiredModels && !isRequiredTables && !isRequiredRelations && !isRequiredExtensionPacks && !isRequiredCapabilities && !isRequiredMeta && !isRequiredSources && !isExtensionNamespace && !isModelRelations && !isTableUniques && !isTableIndexes && !isTableForeignKeys) continue;
|
|
85
|
+
if (!isRequiredModels && !isRequiredTables && !isRequiredRelations && !isRequiredExtensionPacks && !isRequiredCapabilities && !isRequiredMeta && !isRequiredSources && !isRequiredExecutionDefaults && !isExtensionNamespace && !isModelRelations && !isTableUniques && !isTableIndexes && !isTableForeignKeys) continue;
|
|
75
86
|
}
|
|
76
87
|
result[key] = omitDefaults(value, currentPath);
|
|
77
88
|
}
|
|
89
|
+
if (Object.hasOwn(obj, "default")) result["nullable"] = false;
|
|
78
90
|
return result;
|
|
79
91
|
}
|
|
80
92
|
function sortObjectKeys(obj) {
|
|
@@ -133,13 +145,13 @@ function canonicalizeContract(ir) {
|
|
|
133
145
|
models: ir.models,
|
|
134
146
|
relations: ir.relations,
|
|
135
147
|
storage: ir.storage,
|
|
148
|
+
...ifDefined("execution", ir.execution),
|
|
136
149
|
extensionPacks: ir.extensionPacks,
|
|
137
150
|
capabilities: ir.capabilities,
|
|
138
151
|
meta: ir.meta,
|
|
139
152
|
sources: ir.sources
|
|
140
153
|
};
|
|
141
|
-
|
|
142
|
-
if (ir.profileHash !== void 0) normalized.profileHash = ir.profileHash;
|
|
154
|
+
Object.assign(normalized, ifDefined("storageHash", ir.storageHash), ifDefined("executionHash", ir.executionHash), ifDefined("profileHash", ir.profileHash));
|
|
143
155
|
const withDefaultsOmitted = omitDefaults(normalized, []);
|
|
144
156
|
const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);
|
|
145
157
|
const withOrderedTopLevel = orderTopLevel(sortObjectKeys({
|
|
@@ -156,18 +168,18 @@ function computeHash(content) {
|
|
|
156
168
|
hash.update(content);
|
|
157
169
|
return `sha256:${hash.digest("hex")}`;
|
|
158
170
|
}
|
|
159
|
-
function
|
|
171
|
+
function computeStorageHash(contract) {
|
|
160
172
|
return computeHash(canonicalizeContract({
|
|
161
173
|
schemaVersion: contract.schemaVersion,
|
|
162
174
|
targetFamily: contract.targetFamily,
|
|
163
175
|
target: contract.target,
|
|
164
|
-
models: contract.models,
|
|
165
|
-
relations: contract.relations,
|
|
166
176
|
storage: contract.storage,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
177
|
+
models: {},
|
|
178
|
+
relations: {},
|
|
179
|
+
extensionPacks: {},
|
|
180
|
+
sources: {},
|
|
181
|
+
capabilities: {},
|
|
182
|
+
meta: {}
|
|
171
183
|
}));
|
|
172
184
|
}
|
|
173
185
|
function computeProfileHash(contract) {
|
|
@@ -184,6 +196,21 @@ function computeProfileHash(contract) {
|
|
|
184
196
|
sources: {}
|
|
185
197
|
}));
|
|
186
198
|
}
|
|
199
|
+
function computeExecutionHash(contract) {
|
|
200
|
+
return computeHash(canonicalizeContract({
|
|
201
|
+
schemaVersion: contract.schemaVersion,
|
|
202
|
+
targetFamily: contract.targetFamily,
|
|
203
|
+
target: contract.target,
|
|
204
|
+
models: {},
|
|
205
|
+
relations: {},
|
|
206
|
+
storage: {},
|
|
207
|
+
extensionPacks: {},
|
|
208
|
+
sources: {},
|
|
209
|
+
capabilities: {},
|
|
210
|
+
meta: {},
|
|
211
|
+
...ifDefined("execution", contract.execution)
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
187
214
|
|
|
188
215
|
//#endregion
|
|
189
216
|
//#region src/emission/emit.ts
|
|
@@ -217,17 +244,20 @@ async function emit(ir, options, targetFamily) {
|
|
|
217
244
|
models: ir.models,
|
|
218
245
|
relations: ir.relations,
|
|
219
246
|
storage: ir.storage,
|
|
247
|
+
...ifDefined("execution", ir.execution),
|
|
220
248
|
extensionPacks: ir.extensionPacks,
|
|
221
249
|
capabilities: ir.capabilities,
|
|
222
250
|
meta: ir.meta,
|
|
223
251
|
sources: ir.sources
|
|
224
252
|
};
|
|
225
|
-
const
|
|
253
|
+
const storageHash = computeStorageHash(contractJson);
|
|
254
|
+
const executionHash = ir.execution ? computeExecutionHash(contractJson) : void 0;
|
|
226
255
|
const profileHash = computeProfileHash(contractJson);
|
|
227
256
|
const contractWithHashes = {
|
|
228
257
|
...ir,
|
|
229
258
|
schemaVersion: contractJson.schemaVersion,
|
|
230
|
-
|
|
259
|
+
storageHash,
|
|
260
|
+
...ifDefined("executionHash", executionHash),
|
|
231
261
|
profileHash
|
|
232
262
|
};
|
|
233
263
|
const contractJsonWithMeta = {
|
|
@@ -243,19 +273,25 @@ async function emit(ir, options, targetFamily) {
|
|
|
243
273
|
...ifDefined("parameterizedRenderers", parameterizedRenderers),
|
|
244
274
|
...ifDefined("parameterizedTypeImports", parameterizedTypeImports)
|
|
245
275
|
} : void 0;
|
|
276
|
+
const contractTypeHashes = {
|
|
277
|
+
storageHash,
|
|
278
|
+
...ifDefined("executionHash", executionHash),
|
|
279
|
+
profileHash
|
|
280
|
+
};
|
|
246
281
|
return {
|
|
247
282
|
contractJson: contractJsonString,
|
|
248
|
-
contractDts: await format(targetFamily.generateContractTypes(ir, codecTypeImports ?? [], operationTypeImports ?? [], generateOptions), {
|
|
283
|
+
contractDts: await format(targetFamily.generateContractTypes(ir, codecTypeImports ?? [], operationTypeImports ?? [], contractTypeHashes, generateOptions), {
|
|
249
284
|
parser: "typescript",
|
|
250
285
|
singleQuote: true,
|
|
251
286
|
semi: true,
|
|
252
287
|
printWidth: 100
|
|
253
288
|
}),
|
|
254
|
-
|
|
289
|
+
storageHash,
|
|
290
|
+
...ifDefined("executionHash", executionHash),
|
|
255
291
|
profileHash
|
|
256
292
|
};
|
|
257
293
|
}
|
|
258
294
|
|
|
259
295
|
//#endregion
|
|
260
|
-
export { canonicalizeContract,
|
|
296
|
+
export { canonicalizeContract, computeExecutionHash, computeProfileHash, computeStorageHash, emit };
|
|
261
297
|
//# sourceMappingURL=emission.mjs.map
|
package/dist/emission.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emission.mjs","names":["result: Record<string, unknown>","sorted: Record<string, unknown>","result: StorageObject","sortedTable: TableObject","ordered: Record<string, unknown>","normalized: NormalizedContract","ctx: ValidationContext","contractWithHashes: ContractIR & { coreHash?: string; profileHash?: string }"],"sources":["../src/emission/canonicalization.ts","../src/emission/hashing.ts","../src/emission/emit.ts"],"sourcesContent":["import type { ContractIR } from '@prisma-next/contract/ir';\nimport { isArrayEqual } from '@prisma-next/utils/array-equal';\n\ntype NormalizedContract = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n coreHash?: string;\n profileHash?: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n sources: Record<string, unknown>;\n};\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'coreHash',\n 'profileHash',\n 'models',\n 'storage',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n 'sources',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n // Exclude metadata fields from canonicalization\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'nullable' && value === false) {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = isArrayEqual(currentPath, ['models']);\n const isRequiredTables = isArrayEqual(currentPath, ['storage', 'tables']);\n const isRequiredRelations = isArrayEqual(currentPath, ['relations']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredSources = isArrayEqual(currentPath, ['sources']);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'relations']);\n const isTableUniques =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'uniques'],\n );\n const isTableIndexes =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'indexes'],\n );\n const isTableForeignKeys =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'foreignKeys'],\n );\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredRelations &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredSources &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n // Sort table names to ensure deterministic ordering\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nfunction orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport function canonicalizeContract(\n ir: ContractIR & { coreHash?: string; profileHash?: string },\n): string {\n const normalized: NormalizedContract = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n };\n\n if (ir.coreHash !== undefined) {\n normalized.coreHash = ir.coreHash;\n }\n\n if (ir.profileHash !== undefined) {\n normalized.profileHash = ir.profileHash;\n }\n\n const withDefaultsOmitted = omitDefaults(normalized, []) as NormalizedContract;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n const withOrderedTopLevel = orderTopLevel(withSortedKeys);\n\n return JSON.stringify(withOrderedTopLevel, null, 2);\n}\n","import { createHash } from 'node:crypto';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport { canonicalizeContract } from './canonicalization';\n\ntype ContractInput = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n sources: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nfunction computeHash(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nexport function computeCoreHash(contract: ContractInput): string {\n const coreContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: contract.models,\n relations: contract.relations,\n storage: contract.storage,\n extensionPacks: contract.extensionPacks,\n sources: contract.sources,\n capabilities: contract.capabilities,\n meta: contract.meta,\n };\n const canonical = canonicalizeContract(coreContract);\n return computeHash(canonical);\n}\n\nexport function computeProfileHash(contract: ContractInput): string {\n const profileContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensionPacks: {},\n capabilities: contract.capabilities,\n meta: {},\n sources: {},\n };\n const canonical = canonicalizeContract(profileContract);\n return computeHash(canonical);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { TargetFamilyHook, ValidationContext } from '@prisma-next/contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { format } from 'prettier';\nimport { canonicalizeContract } from './canonicalization';\nimport { computeCoreHash, computeProfileHash } from './hashing';\nimport type { EmitOptions, EmitResult } from './types';\n\nfunction validateCoreStructure(ir: ContractIR): void {\n if (!ir.targetFamily) {\n throw new Error('ContractIR must have targetFamily');\n }\n if (!ir.target) {\n throw new Error('ContractIR must have target');\n }\n if (!ir.schemaVersion) {\n throw new Error('ContractIR must have schemaVersion');\n }\n if (!ir.models || typeof ir.models !== 'object') {\n throw new Error('ContractIR must have models');\n }\n if (!ir.storage || typeof ir.storage !== 'object') {\n throw new Error('ContractIR must have storage');\n }\n if (!ir.relations || typeof ir.relations !== 'object') {\n throw new Error('ContractIR must have relations');\n }\n if (!ir.extensionPacks || typeof ir.extensionPacks !== 'object') {\n throw new Error('ContractIR must have extensionPacks');\n }\n if (!ir.capabilities || typeof ir.capabilities !== 'object') {\n throw new Error('ContractIR must have capabilities');\n }\n if (!ir.meta || typeof ir.meta !== 'object') {\n throw new Error('ContractIR must have meta');\n }\n if (!ir.sources || typeof ir.sources !== 'object') {\n throw new Error('ContractIR must have sources');\n }\n}\n\nexport async function emit(\n ir: ContractIR,\n options: EmitOptions,\n targetFamily: TargetFamilyHook,\n): Promise<EmitResult> {\n const {\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n parameterizedRenderers,\n parameterizedTypeImports,\n } = options;\n\n validateCoreStructure(ir);\n\n const ctx: ValidationContext = {\n ...ifDefined('operationRegistry', operationRegistry),\n ...ifDefined('codecTypeImports', codecTypeImports),\n ...ifDefined('operationTypeImports', operationTypeImports),\n ...ifDefined('extensionIds', extensionIds),\n };\n targetFamily.validateTypes(ir, ctx);\n\n targetFamily.validateStructure(ir);\n\n const contractJson = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n } as const;\n\n const coreHash = computeCoreHash(contractJson);\n const profileHash = computeProfileHash(contractJson);\n\n const contractWithHashes: ContractIR & { coreHash?: string; profileHash?: string } = {\n ...ir,\n schemaVersion: contractJson.schemaVersion,\n coreHash,\n profileHash,\n };\n\n // Add _generated metadata to indicate this is a generated artifact\n // This ensures consistency between CLI emit and programmatic emit\n // Always add/update _generated with standard content for consistency\n const contractJsonObj = JSON.parse(canonicalizeContract(contractWithHashes)) as Record<\n string,\n unknown\n >;\n const contractJsonWithMeta = {\n ...contractJsonObj,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next contract emit\".',\n regenerate: 'To regenerate, run: prisma-next contract emit',\n },\n };\n const contractJsonString = JSON.stringify(contractJsonWithMeta, null, 2);\n\n const generateOptions =\n parameterizedRenderers || parameterizedTypeImports\n ? {\n ...ifDefined('parameterizedRenderers', parameterizedRenderers),\n ...ifDefined('parameterizedTypeImports', parameterizedTypeImports),\n }\n : undefined;\n\n const contractDtsRaw = targetFamily.generateContractTypes(\n ir,\n codecTypeImports ?? [],\n operationTypeImports ?? [],\n generateOptions,\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n coreHash,\n profileHash,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"emission.mjs","names":["result: Record<string, unknown>","sorted: Record<string, unknown>","result: StorageObject","sortedTable: TableObject","ordered: Record<string, unknown>","normalized: NormalizedContract","ctx: ValidationContext","contractWithHashes: ContractIR & {\n storageHash?: string;\n executionHash?: string;\n profileHash?: string;\n }"],"sources":["../src/emission/canonicalization.ts","../src/emission/hashing.ts","../src/emission/emit.ts"],"sourcesContent":["import type { ContractIR } from '@prisma-next/contract/ir';\nimport { isArrayEqual } from '@prisma-next/utils/array-equal';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\ntype NormalizedContract = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n storageHash?: string;\n executionHash?: string;\n profileHash?: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n execution?: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n sources: Record<string, unknown>;\n};\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'storageHash',\n 'executionHash',\n 'profileHash',\n 'models',\n 'storage',\n 'execution',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n 'sources',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n // Exclude metadata fields from canonicalization\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'nullable' && value === false) {\n const hasDefault = Object.hasOwn(obj, 'default');\n if (!hasDefault) {\n continue;\n }\n result[key] = value;\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = isArrayEqual(currentPath, ['models']);\n const isRequiredTables = isArrayEqual(currentPath, ['storage', 'tables']);\n const isRequiredRelations = isArrayEqual(currentPath, ['relations']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredSources = isArrayEqual(currentPath, ['sources']);\n const isRequiredExecutionDefaults = isArrayEqual(currentPath, [\n 'execution',\n 'mutations',\n 'defaults',\n ]);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'relations']);\n const isTableUniques =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'uniques'],\n );\n const isTableIndexes =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'indexes'],\n );\n const isTableForeignKeys =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'foreignKeys'],\n );\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredRelations &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredSources &&\n !isRequiredExecutionDefaults &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n /**\n * Columns with defaults should always be NOT nullable.\n */\n const hasDefault = Object.hasOwn(obj, 'default');\n if (hasDefault) {\n result['nullable'] = false;\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n // Sort table names to ensure deterministic ordering\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nfunction orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport function canonicalizeContract(\n ir: ContractIR & { storageHash?: string; executionHash?: string; profileHash?: string },\n): string {\n const normalized: NormalizedContract = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n ...ifDefined('execution', ir.execution),\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n };\n Object.assign(\n normalized,\n ifDefined('storageHash', ir.storageHash),\n ifDefined('executionHash', ir.executionHash),\n ifDefined('profileHash', ir.profileHash),\n );\n\n const withDefaultsOmitted = omitDefaults(normalized, []) as NormalizedContract;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n const withOrderedTopLevel = orderTopLevel(withSortedKeys);\n\n return JSON.stringify(withOrderedTopLevel, null, 2);\n}\n","import { createHash } from 'node:crypto';\nimport type { ContractIR } from '@prisma-next/contract/ir';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { canonicalizeContract } from './canonicalization';\n\ntype ContractInput = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n execution?: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n sources: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nfunction computeHash(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nexport function computeStorageHash(contract: ContractInput): string {\n const storageContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n storage: contract.storage,\n models: {},\n relations: {},\n extensionPacks: {},\n sources: {},\n capabilities: {},\n meta: {},\n };\n const canonical = canonicalizeContract(storageContract);\n return computeHash(canonical);\n}\n\nexport function computeProfileHash(contract: ContractInput): string {\n const profileContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensionPacks: {},\n capabilities: contract.capabilities,\n meta: {},\n sources: {},\n };\n const canonical = canonicalizeContract(profileContract);\n return computeHash(canonical);\n}\n\nexport function computeExecutionHash(contract: ContractInput): string {\n const executionContract: ContractIR = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensionPacks: {},\n sources: {},\n capabilities: {},\n meta: {},\n ...ifDefined('execution', contract.execution),\n };\n const canonical = canonicalizeContract(executionContract);\n return computeHash(canonical);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { TargetFamilyHook, ValidationContext } from '@prisma-next/contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { format } from 'prettier';\nimport { canonicalizeContract } from './canonicalization';\nimport { computeExecutionHash, computeProfileHash, computeStorageHash } from './hashing';\nimport type { EmitOptions, EmitResult } from './types';\n\nfunction validateCoreStructure(ir: ContractIR): void {\n if (!ir.targetFamily) {\n throw new Error('ContractIR must have targetFamily');\n }\n if (!ir.target) {\n throw new Error('ContractIR must have target');\n }\n if (!ir.schemaVersion) {\n throw new Error('ContractIR must have schemaVersion');\n }\n if (!ir.models || typeof ir.models !== 'object') {\n throw new Error('ContractIR must have models');\n }\n if (!ir.storage || typeof ir.storage !== 'object') {\n throw new Error('ContractIR must have storage');\n }\n if (!ir.relations || typeof ir.relations !== 'object') {\n throw new Error('ContractIR must have relations');\n }\n if (!ir.extensionPacks || typeof ir.extensionPacks !== 'object') {\n throw new Error('ContractIR must have extensionPacks');\n }\n if (!ir.capabilities || typeof ir.capabilities !== 'object') {\n throw new Error('ContractIR must have capabilities');\n }\n if (!ir.meta || typeof ir.meta !== 'object') {\n throw new Error('ContractIR must have meta');\n }\n if (!ir.sources || typeof ir.sources !== 'object') {\n throw new Error('ContractIR must have sources');\n }\n}\n\nexport async function emit(\n ir: ContractIR,\n options: EmitOptions,\n targetFamily: TargetFamilyHook,\n): Promise<EmitResult> {\n const {\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n parameterizedRenderers,\n parameterizedTypeImports,\n } = options;\n\n validateCoreStructure(ir);\n\n const ctx: ValidationContext = {\n ...ifDefined('operationRegistry', operationRegistry),\n ...ifDefined('codecTypeImports', codecTypeImports),\n ...ifDefined('operationTypeImports', operationTypeImports),\n ...ifDefined('extensionIds', extensionIds),\n };\n targetFamily.validateTypes(ir, ctx);\n\n targetFamily.validateStructure(ir);\n\n const contractJson = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n ...ifDefined('execution', ir.execution),\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n sources: ir.sources,\n } as const;\n\n const storageHash = computeStorageHash(contractJson);\n const executionHash = ir.execution ? computeExecutionHash(contractJson) : undefined;\n const profileHash = computeProfileHash(contractJson);\n\n const contractWithHashes: ContractIR & {\n storageHash?: string;\n executionHash?: string;\n profileHash?: string;\n } = {\n ...ir,\n schemaVersion: contractJson.schemaVersion,\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n\n // Add _generated metadata to indicate this is a generated artifact\n // This ensures consistency between CLI emit and programmatic emit\n // Always add/update _generated with standard content for consistency\n const contractJsonObj = JSON.parse(canonicalizeContract(contractWithHashes)) as Record<\n string,\n unknown\n >;\n const contractJsonWithMeta = {\n ...contractJsonObj,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next contract emit\".',\n regenerate: 'To regenerate, run: prisma-next contract emit',\n },\n };\n const contractJsonString = JSON.stringify(contractJsonWithMeta, null, 2);\n\n const generateOptions =\n parameterizedRenderers || parameterizedTypeImports\n ? {\n ...ifDefined('parameterizedRenderers', parameterizedRenderers),\n ...ifDefined('parameterizedTypeImports', parameterizedTypeImports),\n }\n : undefined;\n\n const contractTypeHashes = {\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n const contractDtsRaw = targetFamily.generateContractTypes(\n ir,\n codecTypeImports ?? [],\n operationTypeImports ?? [],\n contractTypeHashes,\n generateOptions,\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n}\n"],"mappings":"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"}
|
package/dist/stack.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ControlExtensionDescriptor, l as ControlPlaneStack, r as ControlDriverDescriptor, t as ControlAdapterDescriptor, u as ControlTargetDescriptor } from "./types-
|
|
1
|
+
import { a as ControlExtensionDescriptor, l as ControlPlaneStack, r as ControlDriverDescriptor, t as ControlAdapterDescriptor, u as ControlTargetDescriptor } from "./types-yiR2kXAj.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/stack.d.ts
|
|
4
4
|
|
|
@@ -40,7 +40,7 @@ interface MigrationPlan {
|
|
|
40
40
|
readonly targetId: string;
|
|
41
41
|
/** Destination contract identity that the plan intends to reach. */
|
|
42
42
|
readonly destination: {
|
|
43
|
-
readonly
|
|
43
|
+
readonly storageHash: string;
|
|
44
44
|
readonly profileHash?: string;
|
|
45
45
|
};
|
|
46
46
|
/** Ordered list of operations to execute. */
|
|
@@ -197,16 +197,16 @@ interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR = unknown> e
|
|
|
197
197
|
* Mappings are runtime-only and should not be part of ContractIR.
|
|
198
198
|
*
|
|
199
199
|
* Note: The returned ContractIR may include additional fields from the emitted contract
|
|
200
|
-
* (like
|
|
200
|
+
* (like storageHash/executionHash, profileHash) that are not part of the ContractIR type but are preserved
|
|
201
201
|
* for use by verify/sign operations.
|
|
202
202
|
*/
|
|
203
203
|
validateContractIR(contractJson: unknown): ContractIR;
|
|
204
204
|
/**
|
|
205
205
|
* Verifies the database marker against the contract.
|
|
206
|
-
* Compares target,
|
|
206
|
+
* Compares target, storageHash, and profileHash.
|
|
207
207
|
*
|
|
208
208
|
* @param options.contractIR - The validated contract (from validateContractIR). Must have
|
|
209
|
-
*
|
|
209
|
+
* storageHash and target fields for verification. These fields are present in emitted
|
|
210
210
|
* contracts but not in the ContractIR type definition.
|
|
211
211
|
*/
|
|
212
212
|
verify(options: {
|
|
@@ -446,11 +446,11 @@ interface VerifyDatabaseResult {
|
|
|
446
446
|
readonly code?: string;
|
|
447
447
|
readonly summary: string;
|
|
448
448
|
readonly contract: {
|
|
449
|
-
readonly
|
|
449
|
+
readonly storageHash: string;
|
|
450
450
|
readonly profileHash?: string;
|
|
451
451
|
};
|
|
452
452
|
readonly marker?: {
|
|
453
|
-
readonly
|
|
453
|
+
readonly storageHash?: string;
|
|
454
454
|
readonly profileHash?: string;
|
|
455
455
|
};
|
|
456
456
|
readonly target: {
|
|
@@ -471,10 +471,11 @@ interface VerifyDatabaseResult {
|
|
|
471
471
|
* Schema issue type for schema verification results.
|
|
472
472
|
*/
|
|
473
473
|
interface SchemaIssue {
|
|
474
|
-
readonly kind: 'missing_table' | 'missing_column' | 'extra_table' | 'extra_column' | 'extra_primary_key' | 'extra_foreign_key' | 'extra_unique_constraint' | 'extra_index' | 'type_mismatch' | 'nullability_mismatch' | 'primary_key_mismatch' | 'foreign_key_mismatch' | 'unique_constraint_mismatch' | 'index_mismatch' | 'extension_missing';
|
|
474
|
+
readonly kind: 'missing_table' | 'missing_column' | 'extra_table' | 'extra_column' | 'extra_primary_key' | 'extra_foreign_key' | 'extra_unique_constraint' | 'extra_index' | 'type_mismatch' | 'type_missing' | 'type_values_mismatch' | 'nullability_mismatch' | 'primary_key_mismatch' | 'foreign_key_mismatch' | 'unique_constraint_mismatch' | 'index_mismatch' | 'extension_missing' | 'default_missing' | 'default_mismatch';
|
|
475
475
|
readonly table: string;
|
|
476
476
|
readonly column?: string;
|
|
477
477
|
readonly indexOrConstraint?: string;
|
|
478
|
+
readonly typeName?: string;
|
|
478
479
|
readonly expected?: string;
|
|
479
480
|
readonly actual?: string;
|
|
480
481
|
readonly message: string;
|
|
@@ -502,7 +503,7 @@ interface VerifyDatabaseSchemaResult {
|
|
|
502
503
|
readonly code?: string;
|
|
503
504
|
readonly summary: string;
|
|
504
505
|
readonly contract: {
|
|
505
|
-
readonly
|
|
506
|
+
readonly storageHash: string;
|
|
506
507
|
readonly profileHash?: string;
|
|
507
508
|
};
|
|
508
509
|
readonly target: {
|
|
@@ -534,7 +535,8 @@ interface VerifyDatabaseSchemaResult {
|
|
|
534
535
|
interface EmitContractResult {
|
|
535
536
|
readonly contractJson: string;
|
|
536
537
|
readonly contractDts: string;
|
|
537
|
-
readonly
|
|
538
|
+
readonly storageHash: string;
|
|
539
|
+
readonly executionHash?: string;
|
|
538
540
|
readonly profileHash: string;
|
|
539
541
|
}
|
|
540
542
|
/**
|
|
@@ -567,7 +569,7 @@ interface SignDatabaseResult {
|
|
|
567
569
|
readonly ok: boolean;
|
|
568
570
|
readonly summary: string;
|
|
569
571
|
readonly contract: {
|
|
570
|
-
readonly
|
|
572
|
+
readonly storageHash: string;
|
|
571
573
|
readonly profileHash?: string;
|
|
572
574
|
};
|
|
573
575
|
readonly target: {
|
|
@@ -578,7 +580,7 @@ interface SignDatabaseResult {
|
|
|
578
580
|
readonly created: boolean;
|
|
579
581
|
readonly updated: boolean;
|
|
580
582
|
readonly previous?: {
|
|
581
|
-
readonly
|
|
583
|
+
readonly storageHash?: string;
|
|
582
584
|
readonly profileHash?: string;
|
|
583
585
|
};
|
|
584
586
|
};
|
|
@@ -592,4 +594,4 @@ interface SignDatabaseResult {
|
|
|
592
594
|
}
|
|
593
595
|
//#endregion
|
|
594
596
|
export { MigrationRunnerExecutionChecks as A, MigrationPlanOperation as C, MigrationPlannerResult as D, MigrationPlannerFailureResult as E, MigrationRunnerResult as M, MigrationRunnerSuccessValue as N, MigrationPlannerSuccessResult as O, TargetMigrationsCapability as P, MigrationPlan as S, MigrationPlannerConflict as T, SignDatabaseResult as _, ControlExtensionDescriptor as a, MigrationOperationClass as b, ControlFamilyInstance as c, ControlTargetInstance as d, EmitContractResult as f, SchemaVerificationNode as g, SchemaIssue as h, ControlDriverInstance as i, MigrationRunnerFailure as j, MigrationRunner as k, ControlPlaneStack as l, OperationContext as m, ControlAdapterInstance as n, ControlExtensionInstance as o, IntrospectSchemaResult as p, ControlDriverDescriptor as r, ControlFamilyDescriptor as s, ControlAdapterDescriptor as t, ControlTargetDescriptor as u, VerifyDatabaseResult as v, MigrationPlanner as w, MigrationOperationPolicy as x, VerifyDatabaseSchemaResult as y };
|
|
595
|
-
//# sourceMappingURL=types-
|
|
597
|
+
//# sourceMappingURL=types-yiR2kXAj.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-
|
|
1
|
+
{"version":3,"file":"types-yiR2kXAj.d.mts","names":[],"sources":["../src/migrations.ts","../src/types.ts"],"sourcesContent":[],"mappings":";;;;;;;;AA8FA;AAQA;AASA;AAQA;AAcA;;AAAwE,KA5G5D,uBAAA,GA4G4D,UAAA,GAAA,UAAA,GAAA,aAAA;;;AAUxE;AA6BiB,UA9IA,wBAAA,CA8IgB;EAOZ,SAAA,uBAAA,EAAA,SApJwB,uBAoJxB,EAAA;;;;;;AASO,UAlJX,sBAAA,CAkJW;EAUX;EAKE,SAAA,EAAA,EAAA,MAAA;EACwB;EAAW,SAAA,KAAA,EAAA,MAAA;EAAjC;EAEA,SAAA,cAAA,EA9JM,uBA8JN;;;;;;AAgBf,UAvKW,aAAA,CAuKX;EAD4B;EAGpB,SAAA,QAAA,EAAA,MAAA;EAAR;EAAO,SAAA,WAAA,EAAA;IAeI,SAAA,WAAA,EAAA,MAA0B;IAGK,SAAA,WAAA,CAAA,EAAA,MAAA;EAAtB,CAAA;EAAyD;EAAtB,SAAA,UAAA,EAAA,SAlL7B,sBAkL6B,EAAA;;;;;AAGtC,UA3KN,wBAAA,CA2KM;EAAkC;EAAW,SAAA,IAAA,EAAA,MAAA;EAA3B;EAAe,SAAA,OAAA,EAAA,MAAA;;;;ACrMxD;;;AAqB2C,UDiB1B,6BAAA,CCjB0B;EAAtB,SAAA,IAAA,EAAA,SAAA;EAKP,SAAA,IAAA,EDcG,aCdH;;;;;AAgBkC,UDI/B,6BAAA,CCJ+B;EAAd,SAAA,IAAA,EAAA,SAAA;EACpB,SAAA,SAAA,EAAA,SDKiB,wBCLjB,EAAA;;;;;AAYR,KDDM,sBAAA,GAAyB,6BCC/B,GDD+D,6BCC/D;;;;AAQA,UDAW,2BAAA,CCAX;EAmBqC,SAAA,iBAAA,EAAA,MAAA;EAAtB,SAAA,kBAAA,EAAA,MAAA;;;;;AAgB0B,UD3B9B,sBAAA,CC2B8B;EAAiC;EAAR,SAAA,IAAA,EAAA,MAAA;EAjG9D;EAAc,SAAA,OAAA,EAAA,MAAA;EA2GP;EACQ,SAAA,GAAA,CAAA,EAAA,MAAA;EAAW;EAA1B,SAAA,IAAA,CAAA,ED9BQ,MC8BR,CAAA,MAAA,EAAA,OAAA,CAAA;;AAUV;;;AACU,KDnCE,qBAAA,GAAwB,MCmC1B,CDnCiC,2BCmCjC,EDnC8D,sBCmC9D,CAAA;;AASV;;;AAEc,UDpCG,8BAAA,CCoCH;EAGgB;;;;EAJN,SAAA,SAAA,CAAA,EAAA,OAAA;EAeP;;;;EACU,SAAA,UAAA,CAAA,EAAA,OAAA;EAoBV;AAkCjB;;;EACmB,SAAA,iBAAA,CAAA,EAAA,OAAA;;;;;;;;;AAGiB,UDhFnB,gBCgFmB,CAAA,kBAAA,MAAA,GAAA,MAAA,EAAA,kBAAA,MAAA,GAAA,MAAA,CAAA,CAAA;EAA0B,IAAA,CAAA,OAAA,EAAA;IAU7C,SAAA,QAAA,EAAA,OAAuB;IAEQ,SAAA,MAAA,EAAA,OAAA;IAAtB,SAAA,MAAA,EDrFL,wBCqFK;IAAyD;;;;;IAGZ,SAAA,mBAAA,EDlFrC,aCkFqC,CDjFjE,8BCiFiE,CDjFlC,SCiFkC,EDjFvB,SCiFuB,CAAA,CAAA;EAA7B,CAAA,CAAA,ED/EpC,sBC+EoC;;;;AAW1C;;;;;AAKI,UDrFa,eCqFb,CAAA,kBAAA,MAAA,GAAA,MAAA,EAAA,kBAAA,MAAA,GAAA,MAAA,CAAA,CAAA;EAFoE,OAAA,CAAA,OAAA,EAAA;IAIxB,SAAA,IAAA,EDlF7B,aCkF6B;IAAtB,SAAA,MAAA,EDjFL,qBCiFK,CDjFiB,SCiFjB,EDjF4B,SCiF5B,CAAA;IAAyD,SAAA,mBAAA,EAAA,OAAA;IAAtB,SAAA,MAAA,ED/ExC,wBC+EwC;IAClC,SAAA,SAAA,CAAA,EAAA;MAAW,gBAAA,EAAA,EAAA,ED9EV,sBC8EU,CAAA,EAAA,IAAA;MAOa,mBAAA,EAAA,EAAA,EDpFpB,sBCoFoB,CAAA,EAAA,IAAA;IAAW,CAAA;IAAW;;;;IAP/C,SAAA,eAAA,CAAA,EDvEK,8BCuEL;IAkBT;;;;;IAKb,SAAA,mBAAA,EDxF8B,aCwF9B,CDvFE,8BCuFF,CDvFiC,SCuFjC,EDvF4C,SCuF5C,CAAA,CAAA;EAFsE,CAAA,CAAA,EDnFpE,OCmFoE,CDnF5D,qBCmF4D,CAAA;;;;;;AAoB1E;;;;AAII,UD5Fa,0BC4Fb,CAAA,kBAAA,MAAA,GAAA,MAAA,EAAA,kBAAA,MAAA,GAAA,MAAA,EAAA,wBDzFsB,qBCyFtB,CDzF4C,SCyF5C,CAAA,GDzFyD,qBCyFzD,CDzF+E,SCyF/E,CAAA,CAAA,CAAA;EACA,aAAA,CAAA,MAAA,EDxFoB,eCwFpB,CAAA,EDxFsC,gBCwFtC,CDxFuD,SCwFvD,EDxFkE,SCwFlE,CAAA;EAFoE,YAAA,CAAA,MAAA,EDrFjD,eCqFiD,CAAA,EDrF/B,eCqF+B,CDrFf,SCqFe,EDrFJ,SCqFI,CAAA;;;;;ADjTxE;AAKA;AAYA;AAaA;AAmBA;AAYA;AAQiB,UC9CA,qBD8C6B,CAAA,kBAEf,MAAA,EAAA,YAAwB,OAAA,CAAA,SC/C7C,cD+C6C,CC/C9B,SD+C8B,CAAA,CAAA;EAM3C;AASZ;AAQA;AAcA;;;;;EAUiB,kBAAA,CAAA,YAAA,EAA8B,OAAA,CAAA,ECrFF,UDqFE;EA6B9B;;;;;;;;EA0BA,MAAA,CAAA,OAAA,EAAA;IAKE,SAAA,MAAA,ECtIE,qBDsIF,CCtIwB,SDsIxB,EAAA,MAAA,CAAA;IACwB,SAAA,UAAA,EAAA,OAAA;IAAW,SAAA,gBAAA,EAAA,MAAA;IAAjC,SAAA,YAAA,EAAA,MAAA;IAEA,SAAA,UAAA,CAAA,EAAA,MAAA;EAEO,CAAA,CAAA,ECtItB,ODsIsB,CCtId,oBDsIc,CAAA;EACG;;;;EAazB,YAAA,CAAA,OAAA,EAAA;IAD4B,SAAA,MAAA,EC5Ib,qBD4Ia,CC5IS,SD4IT,EAAA,MAAA,CAAA;IAGpB,SAAA,UAAA,EAAA,OAAA;IAAR,SAAA,MAAA,EAAA,OAAA;IAAO,SAAA,YAAA,EAAA,MAAA;IAeI,SAAA,UAAA,CAAA,EAAA,MAA0B;IAGK;;;;IAExB,SAAA,mBAAA,EC1JU,aD0JV,CC1JwB,8BD0JxB,CC1JuD,SD0JvD,EAAA,MAAA,CAAA,CAAA;EAAmC,CAAA,CAAA,ECzJrD,ODyJqD,CCzJ7C,0BDyJ6C,CAAA;EAAW;;;;;EAC7B,IAAA,CAAA,OAAA,EAAA;IAAe,SAAA,MAAA,EClJnC,qBDkJmC,CClJb,SDkJa,EAAA,MAAA,CAAA;;;;ECrMvC,CAAA,CAAA,EAuDX,OAvDW,CAuDH,kBAvDwB,CAAA;EACb;;;;EAyBX,UAAA,CAAA,OAAA,EAAA;IAAR,SAAA,MAAA,EAoCe,qBApCf,CAoCqC,SApCrC,EAAA,MAAA,CAAA;EAOqC,CAAA,CAAA,EA8BrC,OA9BqC,CA8B7B,oBA9B6B,GAAA,IAAA,CAAA;EAAtB;;;;;;;;;;;;;;;;EAmDP,UAAA,CAAA,OAAA,EAAA;IAAR,SAAA,MAAA,EAFe,qBAEf,CAFqC,SAErC,EAAA,MAAA,CAAA;IAOkB,SAAA,UAAA,CAAA,EAAA,OAAA;EAAY,CAAA,CAAA,EAP9B,OAO8B,CAPtB,SAOsB,CAAA;EAOW;;;;;EAU9B,YAAA,EAAA,MAAA,EAjBO,SAiBc,CAAA,EAjBF,cAiBE;EACb;;;;AAUzB;EAC0B,YAAA,CAAA,OAAA,EAAA;IAAW,SAAA,UAAA,EAtBU,UAsBV,GAAA,OAAA;EAA3B,CAAA,CAAA,EAtB8D,OAsB9D,CAtBsE,kBAsBtE,CAAA;;AASV;;;;;;;AACU,UAtBO,qBAsBP,CAAA,kBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,SArBA,cAqBA,CArBe,SAqBf,EArB0B,SAqB1B,CAAA,CAAA;AAeV;;;;;AAqBA;AAkCA;;AACsD,UAlFrC,sBAkFqC,CAAA,kBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,SAjF5C,eAiF4C,CAjF5B,SAiF4B,EAjFjB,SAiFiB,CAAA,CAAA;;;;;;;;AAGoB,UA3EzD,qBA2EyD,CAAA,kBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,SA1EhE,cA0EgE,CA1EjD,SA0EiD,EA1EtC,SA0EsC,CAAA,CAAA;EAAtC,KAAA,CAAA,MAzEtB,MAyEsB,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,CAAA,GAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,SAAA,OAAA,EAAA,CAAA,EAtE/B,OAsE+B,CAAA;IAA0B,SAAA,IAAA,EAtEhC,GAsEgC,EAAA;EAU7C,CAAA,CAAA;EAE+B,KAAA,EAAA,EAjFrC,OAiFqC,CAAA,IAAA,CAAA;;;;;;;;;AAGoC,UA1EnE,wBA0EmE,CAAA,kBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,SAzE1E,iBAyE0E,CAzExD,SAyEwD,EAzE7C,SAyE6C,CAAA,CAAA;;AAWpF;;;;;;;;;;;;;;;;;AAgBY,UAhFK,gBAAA,CAgFL;EARF;;AAkBV;;EAG6D,SAAA,YAAA,CAAA,EAAA,MAAA;EAAlC;;;;EAIC,SAAA,UAAA,CAAA,EAAA,MAAA;EAAW;;;;EAgBtB,SAAA,IAAA,CAAA,EAhGC,QAgGD,CAhGU,MAgGa,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;;;;;;;;;;;;AAQ9B,UAvFO,iBAuFP,CAAA,kBAAA,MAAA,EAAA,kBAAA,MAAA,CAAA,CAAA;EAAgB,SAAA,MAAA,EAtFP,uBAsFO,CAtFiB,SAsFjB,EAtF4B,SAsF5B,CAAA;EAWT,SAAA,OAAA,EAhGG,wBAgGuB,CAhGE,SAgGF,EAhGa,SAgGb,CAAA;EAIvC,SAAA,MAAA,EAnGe,uBAmGf,CAnGuC,SAmGvC,EAnGkD,SAmGlD,CAAA,GAAA,SAAA;EACA,SAAA,cAAA,EAAA,SAnGgC,0BAmGhC,CAnG2D,SAmG3D,EAnGsE,SAmGtE,CAAA,EAAA;;;;;;;;;AAEyB,UA3FZ,uBA2FY,CAAA,kBAAA,MAAA,EAAA,wBAzFH,qBAyFG,CAzFmB,SAyFnB,CAAA,GAzFgC,qBAyFhC,CAzFsD,SAyFtD,CAAA,CAAA,SAxFnB,gBAwFmB,CAxFF,SAwFE,CAAA,CAAA;EAOZ,SAAA,IAAA,EA9FA,gBA8FoB;EA8BpB,MAAA,CAAA,kBAAW,MAAA,CAAA,CAAA,KAAA,EA3Hc,iBA2Hd,CA3HgC,SA2HhC,EA3H2C,SA2H3C,CAAA,CAAA,EA3HwD,eA2HxD;AAkC5B;AAeA;AAmCA;AAcA;AAqBA;;;;;UAvOiB,oGAGS,sBAAsB,WAAW,aAAa,sBACpE,WACA,oCAEsB,sBAAsB,aAAa,sBAAsB,oBACzE,iBAAiB,WAAW;;;;;;;wBAOd,2BAA2B,WAAW,WAAW;YAC7D;;;;;;;;;UAUK,sGAGU,uBAAuB,WAAW,aAAa,uBACtE,WACA,oBAEM,kBAAkB,WAAW;YAC3B;;;;;;;;;;;;;;UAeK,oGAGS,sBAAsB,WAAW,aAAa,sBACpE,WACA,0CAGM,iBAAiB,WAAW;qBACjB,cAAc,QAAQ;;;;;;;;;UAU1B,0GAGY,yBACzB,WACA,aACE,yBAAyB,WAAW,oBAChC,oBAAoB,WAAW;YAC7B;;;;;UAMK,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8BA,WAAA;;;;;;;;;;;;;;UAkCA,sBAAA;;;;;;;;;8BASa;;;;;UAMb,0BAAA;;;;;;;;;;;;;8BAaa;mBACX;;;;;;;;;;;;;;;;;;;;UAqBF,kBAAA;;;;;;;;;;;;;UAcA;;;;;;;mBAOE;;;;;;;;;;;;;UAcF,kBAAA"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as MigrationRunnerExecutionChecks, C as MigrationPlanOperation, D as MigrationPlannerResult, E as MigrationPlannerFailureResult, M as MigrationRunnerResult, N as MigrationRunnerSuccessValue, O as MigrationPlannerSuccessResult, P as TargetMigrationsCapability, S as MigrationPlan, T as MigrationPlannerConflict, _ as SignDatabaseResult, a as ControlExtensionDescriptor, b as MigrationOperationClass, c as ControlFamilyInstance, d as ControlTargetInstance, f as EmitContractResult, g as SchemaVerificationNode, h as SchemaIssue, i as ControlDriverInstance, j as MigrationRunnerFailure, k as MigrationRunner, l as ControlPlaneStack, m as OperationContext, n as ControlAdapterInstance, o as ControlExtensionInstance, p as IntrospectSchemaResult, r as ControlDriverDescriptor, s as ControlFamilyDescriptor, t as ControlAdapterDescriptor, u as ControlTargetDescriptor, v as VerifyDatabaseResult, w as MigrationPlanner, x as MigrationOperationPolicy, y as VerifyDatabaseSchemaResult } from "./types-
|
|
1
|
+
import { A as MigrationRunnerExecutionChecks, C as MigrationPlanOperation, D as MigrationPlannerResult, E as MigrationPlannerFailureResult, M as MigrationRunnerResult, N as MigrationRunnerSuccessValue, O as MigrationPlannerSuccessResult, P as TargetMigrationsCapability, S as MigrationPlan, T as MigrationPlannerConflict, _ as SignDatabaseResult, a as ControlExtensionDescriptor, b as MigrationOperationClass, c as ControlFamilyInstance, d as ControlTargetInstance, f as EmitContractResult, g as SchemaVerificationNode, h as SchemaIssue, i as ControlDriverInstance, j as MigrationRunnerFailure, k as MigrationRunner, l as ControlPlaneStack, m as OperationContext, n as ControlAdapterInstance, o as ControlExtensionInstance, p as IntrospectSchemaResult, r as ControlDriverDescriptor, s as ControlFamilyDescriptor, t as ControlAdapterDescriptor, u as ControlTargetDescriptor, v as VerifyDatabaseResult, w as MigrationPlanner, x as MigrationOperationPolicy, y as VerifyDatabaseSchemaResult } from "./types-yiR2kXAj.mjs";
|
|
2
2
|
export { type ControlAdapterDescriptor, type ControlAdapterInstance, type ControlDriverDescriptor, type ControlDriverInstance, type ControlExtensionDescriptor, type ControlExtensionInstance, type ControlFamilyDescriptor, type ControlFamilyInstance, type ControlPlaneStack, type ControlTargetDescriptor, type ControlTargetInstance, type EmitContractResult, type IntrospectSchemaResult, type MigrationOperationClass, type MigrationOperationPolicy, type MigrationPlan, type MigrationPlanOperation, type MigrationPlanner, type MigrationPlannerConflict, type MigrationPlannerFailureResult, type MigrationPlannerResult, type MigrationPlannerSuccessResult, type MigrationRunner, type MigrationRunnerExecutionChecks, type MigrationRunnerFailure, type MigrationRunnerResult, type MigrationRunnerSuccessValue, type OperationContext, type SchemaIssue, type SchemaVerificationNode, type SignDatabaseResult, type TargetMigrationsCapability, type VerifyDatabaseResult, type VerifyDatabaseSchemaResult };
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/core-control-plane",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.36",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Control plane domain actions, config types, validation, and error factories for Prisma Next",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"arktype": "^2.1.26",
|
|
9
9
|
"prettier": "^3.3.3",
|
|
10
|
-
"@prisma-next/contract": "0.3.0-dev.
|
|
11
|
-
"@prisma-next/operations": "0.3.0-dev.
|
|
12
|
-
"@prisma-next/utils": "0.3.0-dev.
|
|
10
|
+
"@prisma-next/contract": "0.3.0-dev.36",
|
|
11
|
+
"@prisma-next/operations": "0.3.0-dev.36",
|
|
12
|
+
"@prisma-next/utils": "0.3.0-dev.36"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"tsdown": "0.18.4",
|
|
16
16
|
"typescript": "5.9.3",
|
|
17
|
-
"vitest": "4.0.
|
|
17
|
+
"vitest": "4.0.17",
|
|
18
18
|
"@prisma-next/test-utils": "0.0.1",
|
|
19
19
|
"@prisma-next/tsconfig": "0.0.0",
|
|
20
20
|
"@prisma-next/tsdown": "0.0.0"
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
"./types": "./dist/types.mjs",
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/prisma/prisma-next.git",
|
|
42
|
+
"directory": "packages/1-framework/1-core/migration/control-plane"
|
|
43
|
+
},
|
|
39
44
|
"scripts": {
|
|
40
45
|
"build": "tsdown",
|
|
41
46
|
"test": "vitest run --passWithNoTests",
|
package/src/config-types.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { dirname, join } from 'node:path';
|
|
2
1
|
import { type } from 'arktype';
|
|
3
2
|
import type {
|
|
4
3
|
ControlAdapterDescriptor,
|
|
@@ -26,15 +25,9 @@ export interface ContractConfig {
|
|
|
26
25
|
readonly source: unknown | (() => unknown | Promise<unknown>);
|
|
27
26
|
/**
|
|
28
27
|
* Path to contract.json artifact. Defaults to 'src/prisma/contract.json'.
|
|
29
|
-
*
|
|
28
|
+
* The .d.ts types file will be colocated (e.g., contract.json → contract.d.ts).
|
|
30
29
|
*/
|
|
31
30
|
readonly output?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Path to contract.d.ts artifact. Defaults to output with .d.ts extension.
|
|
34
|
-
* If output ends with .json, replaces .json with .d.ts.
|
|
35
|
-
* Otherwise, appends .d.ts to the directory containing output.
|
|
36
|
-
*/
|
|
37
|
-
readonly types?: string;
|
|
38
31
|
}
|
|
39
32
|
|
|
40
33
|
/**
|
|
@@ -92,7 +85,6 @@ export interface PrismaNextConfig<
|
|
|
92
85
|
const ContractConfigSchema = type({
|
|
93
86
|
source: 'unknown', // Can be value or function - runtime check needed
|
|
94
87
|
'output?': 'string',
|
|
95
|
-
'types?': 'string',
|
|
96
88
|
});
|
|
97
89
|
|
|
98
90
|
/**
|
|
@@ -115,7 +107,6 @@ const PrismaNextConfigSchema = type({
|
|
|
115
107
|
*
|
|
116
108
|
* Normalization:
|
|
117
109
|
* - contract.output defaults to 'src/prisma/contract.json' if missing
|
|
118
|
-
* - contract.types defaults to output with .d.ts extension if missing
|
|
119
110
|
*
|
|
120
111
|
* @param config - Raw config input from user
|
|
121
112
|
* @returns Normalized config IR with defaults applied
|
|
@@ -150,16 +141,10 @@ export function defineConfig<TFamilyId extends string = string, TTargetId extend
|
|
|
150
141
|
|
|
151
142
|
// Apply defaults
|
|
152
143
|
const output = config.contract.output ?? 'src/prisma/contract.json';
|
|
153
|
-
const types =
|
|
154
|
-
config.contract.types ??
|
|
155
|
-
(output.endsWith('.json')
|
|
156
|
-
? `${output.slice(0, -5)}.d.ts`
|
|
157
|
-
: join(dirname(output), 'contract.d.ts'));
|
|
158
144
|
|
|
159
145
|
const normalizedContract: ContractConfig = {
|
|
160
146
|
source: config.contract.source,
|
|
161
147
|
output,
|
|
162
|
-
types,
|
|
163
148
|
};
|
|
164
149
|
|
|
165
150
|
// Return normalized config
|
package/src/config-validation.ts
CHANGED
|
@@ -261,10 +261,5 @@ export function validateConfig(config: unknown): asserts config is PrismaNextCon
|
|
|
261
261
|
why: 'Config.contract.output must be a string when provided',
|
|
262
262
|
});
|
|
263
263
|
}
|
|
264
|
-
if (contract['types'] !== undefined && typeof contract['types'] !== 'string') {
|
|
265
|
-
throw errorConfigValidation('contract.types', {
|
|
266
|
-
why: 'Config.contract.types must be a string when provided',
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
264
|
}
|
|
270
265
|
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import type { ContractIR } from '@prisma-next/contract/ir';
|
|
2
2
|
import { isArrayEqual } from '@prisma-next/utils/array-equal';
|
|
3
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
3
4
|
|
|
4
5
|
type NormalizedContract = {
|
|
5
6
|
schemaVersion: string;
|
|
6
7
|
targetFamily: string;
|
|
7
8
|
target: string;
|
|
8
|
-
|
|
9
|
+
storageHash?: string;
|
|
10
|
+
executionHash?: string;
|
|
9
11
|
profileHash?: string;
|
|
10
12
|
models: Record<string, unknown>;
|
|
11
13
|
relations: Record<string, unknown>;
|
|
12
14
|
storage: Record<string, unknown>;
|
|
15
|
+
execution?: Record<string, unknown>;
|
|
13
16
|
extensionPacks: Record<string, unknown>;
|
|
14
17
|
capabilities: Record<string, Record<string, boolean>>;
|
|
15
18
|
meta: Record<string, unknown>;
|
|
@@ -21,10 +24,12 @@ const TOP_LEVEL_ORDER = [
|
|
|
21
24
|
'canonicalVersion',
|
|
22
25
|
'targetFamily',
|
|
23
26
|
'target',
|
|
24
|
-
'
|
|
27
|
+
'storageHash',
|
|
28
|
+
'executionHash',
|
|
25
29
|
'profileHash',
|
|
26
30
|
'models',
|
|
27
31
|
'storage',
|
|
32
|
+
'execution',
|
|
28
33
|
'capabilities',
|
|
29
34
|
'extensionPacks',
|
|
30
35
|
'meta',
|
|
@@ -62,6 +67,11 @@ function omitDefaults(obj: unknown, path: readonly string[]): unknown {
|
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
if (key === 'nullable' && value === false) {
|
|
70
|
+
const hasDefault = Object.hasOwn(obj, 'default');
|
|
71
|
+
if (!hasDefault) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
result[key] = value;
|
|
65
75
|
continue;
|
|
66
76
|
}
|
|
67
77
|
|
|
@@ -77,6 +87,11 @@ function omitDefaults(obj: unknown, path: readonly string[]): unknown {
|
|
|
77
87
|
const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);
|
|
78
88
|
const isRequiredMeta = isArrayEqual(currentPath, ['meta']);
|
|
79
89
|
const isRequiredSources = isArrayEqual(currentPath, ['sources']);
|
|
90
|
+
const isRequiredExecutionDefaults = isArrayEqual(currentPath, [
|
|
91
|
+
'execution',
|
|
92
|
+
'mutations',
|
|
93
|
+
'defaults',
|
|
94
|
+
]);
|
|
80
95
|
const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';
|
|
81
96
|
const isModelRelations =
|
|
82
97
|
currentPath.length === 3 &&
|
|
@@ -108,6 +123,7 @@ function omitDefaults(obj: unknown, path: readonly string[]): unknown {
|
|
|
108
123
|
!isRequiredCapabilities &&
|
|
109
124
|
!isRequiredMeta &&
|
|
110
125
|
!isRequiredSources &&
|
|
126
|
+
!isRequiredExecutionDefaults &&
|
|
111
127
|
!isExtensionNamespace &&
|
|
112
128
|
!isModelRelations &&
|
|
113
129
|
!isTableUniques &&
|
|
@@ -121,6 +137,14 @@ function omitDefaults(obj: unknown, path: readonly string[]): unknown {
|
|
|
121
137
|
result[key] = omitDefaults(value, currentPath);
|
|
122
138
|
}
|
|
123
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Columns with defaults should always be NOT nullable.
|
|
142
|
+
*/
|
|
143
|
+
const hasDefault = Object.hasOwn(obj, 'default');
|
|
144
|
+
if (hasDefault) {
|
|
145
|
+
result['nullable'] = false;
|
|
146
|
+
}
|
|
147
|
+
|
|
124
148
|
return result;
|
|
125
149
|
}
|
|
126
150
|
|
|
@@ -220,7 +244,7 @@ function orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {
|
|
|
220
244
|
}
|
|
221
245
|
|
|
222
246
|
export function canonicalizeContract(
|
|
223
|
-
ir: ContractIR & {
|
|
247
|
+
ir: ContractIR & { storageHash?: string; executionHash?: string; profileHash?: string },
|
|
224
248
|
): string {
|
|
225
249
|
const normalized: NormalizedContract = {
|
|
226
250
|
schemaVersion: ir.schemaVersion,
|
|
@@ -229,19 +253,18 @@ export function canonicalizeContract(
|
|
|
229
253
|
models: ir.models,
|
|
230
254
|
relations: ir.relations,
|
|
231
255
|
storage: ir.storage,
|
|
256
|
+
...ifDefined('execution', ir.execution),
|
|
232
257
|
extensionPacks: ir.extensionPacks,
|
|
233
258
|
capabilities: ir.capabilities,
|
|
234
259
|
meta: ir.meta,
|
|
235
260
|
sources: ir.sources,
|
|
236
261
|
};
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
normalized.profileHash = ir.profileHash;
|
|
244
|
-
}
|
|
262
|
+
Object.assign(
|
|
263
|
+
normalized,
|
|
264
|
+
ifDefined('storageHash', ir.storageHash),
|
|
265
|
+
ifDefined('executionHash', ir.executionHash),
|
|
266
|
+
ifDefined('profileHash', ir.profileHash),
|
|
267
|
+
);
|
|
245
268
|
|
|
246
269
|
const withDefaultsOmitted = omitDefaults(normalized, []) as NormalizedContract;
|
|
247
270
|
const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);
|
package/src/emission/emit.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { TargetFamilyHook, ValidationContext } from '@prisma-next/contract/
|
|
|
3
3
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
4
4
|
import { format } from 'prettier';
|
|
5
5
|
import { canonicalizeContract } from './canonicalization';
|
|
6
|
-
import {
|
|
6
|
+
import { computeExecutionHash, computeProfileHash, computeStorageHash } from './hashing';
|
|
7
7
|
import type { EmitOptions, EmitResult } from './types';
|
|
8
8
|
|
|
9
9
|
function validateCoreStructure(ir: ContractIR): void {
|
|
@@ -72,19 +72,26 @@ export async function emit(
|
|
|
72
72
|
models: ir.models,
|
|
73
73
|
relations: ir.relations,
|
|
74
74
|
storage: ir.storage,
|
|
75
|
+
...ifDefined('execution', ir.execution),
|
|
75
76
|
extensionPacks: ir.extensionPacks,
|
|
76
77
|
capabilities: ir.capabilities,
|
|
77
78
|
meta: ir.meta,
|
|
78
79
|
sources: ir.sources,
|
|
79
80
|
} as const;
|
|
80
81
|
|
|
81
|
-
const
|
|
82
|
+
const storageHash = computeStorageHash(contractJson);
|
|
83
|
+
const executionHash = ir.execution ? computeExecutionHash(contractJson) : undefined;
|
|
82
84
|
const profileHash = computeProfileHash(contractJson);
|
|
83
85
|
|
|
84
|
-
const contractWithHashes: ContractIR & {
|
|
86
|
+
const contractWithHashes: ContractIR & {
|
|
87
|
+
storageHash?: string;
|
|
88
|
+
executionHash?: string;
|
|
89
|
+
profileHash?: string;
|
|
90
|
+
} = {
|
|
85
91
|
...ir,
|
|
86
92
|
schemaVersion: contractJson.schemaVersion,
|
|
87
|
-
|
|
93
|
+
storageHash,
|
|
94
|
+
...ifDefined('executionHash', executionHash),
|
|
88
95
|
profileHash,
|
|
89
96
|
};
|
|
90
97
|
|
|
@@ -113,10 +120,16 @@ export async function emit(
|
|
|
113
120
|
}
|
|
114
121
|
: undefined;
|
|
115
122
|
|
|
123
|
+
const contractTypeHashes = {
|
|
124
|
+
storageHash,
|
|
125
|
+
...ifDefined('executionHash', executionHash),
|
|
126
|
+
profileHash,
|
|
127
|
+
};
|
|
116
128
|
const contractDtsRaw = targetFamily.generateContractTypes(
|
|
117
129
|
ir,
|
|
118
130
|
codecTypeImports ?? [],
|
|
119
131
|
operationTypeImports ?? [],
|
|
132
|
+
contractTypeHashes,
|
|
120
133
|
generateOptions,
|
|
121
134
|
);
|
|
122
135
|
const contractDts = await format(contractDtsRaw, {
|
|
@@ -129,7 +142,8 @@ export async function emit(
|
|
|
129
142
|
return {
|
|
130
143
|
contractJson: contractJsonString,
|
|
131
144
|
contractDts,
|
|
132
|
-
|
|
145
|
+
storageHash,
|
|
146
|
+
...ifDefined('executionHash', executionHash),
|
|
133
147
|
profileHash,
|
|
134
148
|
};
|
|
135
149
|
}
|
package/src/emission/hashing.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import type { ContractIR } from '@prisma-next/contract/ir';
|
|
3
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
3
4
|
import { canonicalizeContract } from './canonicalization';
|
|
4
5
|
|
|
5
6
|
type ContractInput = {
|
|
@@ -9,6 +10,7 @@ type ContractInput = {
|
|
|
9
10
|
models: Record<string, unknown>;
|
|
10
11
|
relations: Record<string, unknown>;
|
|
11
12
|
storage: Record<string, unknown>;
|
|
13
|
+
execution?: Record<string, unknown>;
|
|
12
14
|
extensionPacks: Record<string, unknown>;
|
|
13
15
|
sources: Record<string, unknown>;
|
|
14
16
|
capabilities: Record<string, Record<string, boolean>>;
|
|
@@ -22,20 +24,20 @@ function computeHash(content: string): string {
|
|
|
22
24
|
return `sha256:${hash.digest('hex')}`;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
export function
|
|
26
|
-
const
|
|
27
|
+
export function computeStorageHash(contract: ContractInput): string {
|
|
28
|
+
const storageContract: ContractIR = {
|
|
27
29
|
schemaVersion: contract.schemaVersion,
|
|
28
30
|
targetFamily: contract.targetFamily,
|
|
29
31
|
target: contract.target,
|
|
30
|
-
models: contract.models,
|
|
31
|
-
relations: contract.relations,
|
|
32
32
|
storage: contract.storage,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
models: {},
|
|
34
|
+
relations: {},
|
|
35
|
+
extensionPacks: {},
|
|
36
|
+
sources: {},
|
|
37
|
+
capabilities: {},
|
|
38
|
+
meta: {},
|
|
37
39
|
};
|
|
38
|
-
const canonical = canonicalizeContract(
|
|
40
|
+
const canonical = canonicalizeContract(storageContract);
|
|
39
41
|
return computeHash(canonical);
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -55,3 +57,21 @@ export function computeProfileHash(contract: ContractInput): string {
|
|
|
55
57
|
const canonical = canonicalizeContract(profileContract);
|
|
56
58
|
return computeHash(canonical);
|
|
57
59
|
}
|
|
60
|
+
|
|
61
|
+
export function computeExecutionHash(contract: ContractInput): string {
|
|
62
|
+
const executionContract: ContractIR = {
|
|
63
|
+
schemaVersion: contract.schemaVersion,
|
|
64
|
+
targetFamily: contract.targetFamily,
|
|
65
|
+
target: contract.target,
|
|
66
|
+
models: {},
|
|
67
|
+
relations: {},
|
|
68
|
+
storage: {},
|
|
69
|
+
extensionPacks: {},
|
|
70
|
+
sources: {},
|
|
71
|
+
capabilities: {},
|
|
72
|
+
meta: {},
|
|
73
|
+
...ifDefined('execution', contract.execution),
|
|
74
|
+
};
|
|
75
|
+
const canonical = canonicalizeContract(executionContract);
|
|
76
|
+
return computeHash(canonical);
|
|
77
|
+
}
|
package/src/emission/types.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface EmitOptions {
|
|
|
22
22
|
export interface EmitResult {
|
|
23
23
|
readonly contractJson: string;
|
|
24
24
|
readonly contractDts: string;
|
|
25
|
-
readonly
|
|
25
|
+
readonly storageHash: string;
|
|
26
|
+
readonly executionHash?: string;
|
|
26
27
|
readonly profileHash: string;
|
|
27
28
|
}
|
package/src/exports/emission.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
export { canonicalizeContract } from '../emission/canonicalization';
|
|
4
4
|
export { emit } from '../emission/emit';
|
|
5
|
-
export {
|
|
5
|
+
export { computeExecutionHash, computeProfileHash, computeStorageHash } from '../emission/hashing';
|
|
6
6
|
export type { EmitOptions, EmitResult } from '../emission/types';
|
package/src/migrations.ts
CHANGED
|
@@ -58,7 +58,7 @@ export interface MigrationPlan {
|
|
|
58
58
|
readonly targetId: string;
|
|
59
59
|
/** Destination contract identity that the plan intends to reach. */
|
|
60
60
|
readonly destination: {
|
|
61
|
-
readonly
|
|
61
|
+
readonly storageHash: string;
|
|
62
62
|
readonly profileHash?: string;
|
|
63
63
|
};
|
|
64
64
|
/** Ordered list of operations to execute. */
|
package/src/types.ts
CHANGED
|
@@ -53,17 +53,17 @@ export interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR = unk
|
|
|
53
53
|
* Mappings are runtime-only and should not be part of ContractIR.
|
|
54
54
|
*
|
|
55
55
|
* Note: The returned ContractIR may include additional fields from the emitted contract
|
|
56
|
-
* (like
|
|
56
|
+
* (like storageHash/executionHash, profileHash) that are not part of the ContractIR type but are preserved
|
|
57
57
|
* for use by verify/sign operations.
|
|
58
58
|
*/
|
|
59
59
|
validateContractIR(contractJson: unknown): ContractIR;
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Verifies the database marker against the contract.
|
|
63
|
-
* Compares target,
|
|
63
|
+
* Compares target, storageHash, and profileHash.
|
|
64
64
|
*
|
|
65
65
|
* @param options.contractIR - The validated contract (from validateContractIR). Must have
|
|
66
|
-
*
|
|
66
|
+
* storageHash and target fields for verification. These fields are present in emitted
|
|
67
67
|
* contracts but not in the ContractIR type definition.
|
|
68
68
|
*/
|
|
69
69
|
verify(options: {
|
|
@@ -363,11 +363,11 @@ export interface VerifyDatabaseResult {
|
|
|
363
363
|
readonly code?: string;
|
|
364
364
|
readonly summary: string;
|
|
365
365
|
readonly contract: {
|
|
366
|
-
readonly
|
|
366
|
+
readonly storageHash: string;
|
|
367
367
|
readonly profileHash?: string;
|
|
368
368
|
};
|
|
369
369
|
readonly marker?: {
|
|
370
|
-
readonly
|
|
370
|
+
readonly storageHash?: string;
|
|
371
371
|
readonly profileHash?: string;
|
|
372
372
|
};
|
|
373
373
|
readonly target: {
|
|
@@ -399,15 +399,20 @@ export interface SchemaIssue {
|
|
|
399
399
|
| 'extra_unique_constraint'
|
|
400
400
|
| 'extra_index'
|
|
401
401
|
| 'type_mismatch'
|
|
402
|
+
| 'type_missing'
|
|
403
|
+
| 'type_values_mismatch'
|
|
402
404
|
| 'nullability_mismatch'
|
|
403
405
|
| 'primary_key_mismatch'
|
|
404
406
|
| 'foreign_key_mismatch'
|
|
405
407
|
| 'unique_constraint_mismatch'
|
|
406
408
|
| 'index_mismatch'
|
|
407
|
-
| 'extension_missing'
|
|
409
|
+
| 'extension_missing'
|
|
410
|
+
| 'default_missing'
|
|
411
|
+
| 'default_mismatch';
|
|
408
412
|
readonly table: string;
|
|
409
413
|
readonly column?: string;
|
|
410
414
|
readonly indexOrConstraint?: string;
|
|
415
|
+
readonly typeName?: string;
|
|
411
416
|
readonly expected?: string;
|
|
412
417
|
readonly actual?: string;
|
|
413
418
|
readonly message: string;
|
|
@@ -437,7 +442,7 @@ export interface VerifyDatabaseSchemaResult {
|
|
|
437
442
|
readonly code?: string;
|
|
438
443
|
readonly summary: string;
|
|
439
444
|
readonly contract: {
|
|
440
|
-
readonly
|
|
445
|
+
readonly storageHash: string;
|
|
441
446
|
readonly profileHash?: string;
|
|
442
447
|
};
|
|
443
448
|
readonly target: {
|
|
@@ -470,7 +475,8 @@ export interface VerifyDatabaseSchemaResult {
|
|
|
470
475
|
export interface EmitContractResult {
|
|
471
476
|
readonly contractJson: string;
|
|
472
477
|
readonly contractDts: string;
|
|
473
|
-
readonly
|
|
478
|
+
readonly storageHash: string;
|
|
479
|
+
readonly executionHash?: string;
|
|
474
480
|
readonly profileHash: string;
|
|
475
481
|
}
|
|
476
482
|
|
|
@@ -505,7 +511,7 @@ export interface SignDatabaseResult {
|
|
|
505
511
|
readonly ok: boolean;
|
|
506
512
|
readonly summary: string;
|
|
507
513
|
readonly contract: {
|
|
508
|
-
readonly
|
|
514
|
+
readonly storageHash: string;
|
|
509
515
|
readonly profileHash?: string;
|
|
510
516
|
};
|
|
511
517
|
readonly target: {
|
|
@@ -516,7 +522,7 @@ export interface SignDatabaseResult {
|
|
|
516
522
|
readonly created: boolean;
|
|
517
523
|
readonly updated: boolean;
|
|
518
524
|
readonly previous?: {
|
|
519
|
-
readonly
|
|
525
|
+
readonly storageHash?: string;
|
|
520
526
|
readonly profileHash?: string;
|
|
521
527
|
};
|
|
522
528
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-types-h9ifypQ0.d.mts","names":[],"sources":["../src/config-types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAqDmB,UAjCF,cAAA,CAiCE;EAC0B;;;;EAC8B,SAAA,MAAA,EAAA,OAAA,GAAA,CAAA,GAAA,GAAA,OAAA,GA9B7B,OA8B6B,CAAA,OAAA,CAAA,CAAA;EAAtC;;;;EAUA,SAAA,MAAA,CAAA,EAAA,MAAA;EAAjC;;;;;EAmBgC,SAAA,KAAA,CAAA,EAAA,MAAA;AAuCpC;;;;;;;;;UA5EiB;mBAKE,wBAAwB;mBACxB,wBAAwB,WAAW;oBAClC,yBAAyB,WAAW;qCACnB,2BAA2B,WAAW;;;;;;;oBAOvD,wBAChB,WACA,WACA,sBAAsB,WAAW,YACjC;;;;;;;;;;;0BAYsB;;;;;;sBAMJ;;;;;;;;;;;;;;iBAuCN,2FACN,iBAAiB,WAAW,aACnC,iBAAiB,WAAW"}
|