@prisma-next/sql-contract 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # @prisma-next/sql-contract
2
+
3
+ SQL contract types, validators, and IR factories for Prisma Next.
4
+
5
+ ## Overview
6
+
7
+ This package provides TypeScript type definitions, Arktype validators, and factory functions for constructing SQL contract structures. It is located in the **shared plane**, making it available to both migration-plane (authoring, emitter) and runtime-plane (lanes, runtime) packages.
8
+
9
+ ## Responsibilities
10
+
11
+ - **SQL Contract Types**: Defines SQL-specific contract types (`SqlContract`, `SqlStorage`, `StorageTable`, `ModelDefinition`, `SqlMappings`) that extend framework-level contract types
12
+ - **Contract Validation**: Provides Arktype-based validators for structural validation of SQL contracts, storage, and models
13
+ - **IR Factories**: Provides pure factory functions for constructing contract IR structures in tests and authoring
14
+ - **Shared Plane Access**: Enables both migration-plane and runtime-plane packages to import SQL contract types without violating plane boundaries
15
+
16
+ ## Package Contents
17
+
18
+ - **TypeScript Types**: Type definitions for `SqlContract`, `SqlStorage`, `StorageTable`, `ModelDefinition`, and related types
19
+ - **Validators**: Arktype-based validators for structural validation of contracts, storage, and models
20
+ - **Factories**: Pure factory functions for constructing contract IR structures in tests and authoring
21
+
22
+ ## Usage
23
+
24
+ ### TypeScript Types
25
+
26
+ Import SQL contract types:
27
+
28
+ ```typescript
29
+ import type {
30
+ SqlContract,
31
+ SqlStorage,
32
+ StorageTable,
33
+ ModelDefinition,
34
+ } from '@prisma-next/sql-contract/exports/types';
35
+ ```
36
+
37
+ ### Validators
38
+
39
+ Validate contract structures using Arktype validators:
40
+
41
+ ```typescript
42
+ import { validateSqlContract, validateStorage, validateModel } from '@prisma-next/sql-contract/exports/validators';
43
+
44
+ // Validate a complete contract
45
+ const contract = validateSqlContract<Contract>(contractJson);
46
+
47
+ // Validate storage structure
48
+ const storage = validateStorage(storageJson);
49
+
50
+ // Validate model structure
51
+ const model = validateModel(modelJson);
52
+ ```
53
+
54
+ ### Factories
55
+
56
+ Use factory functions to construct contract IR structures in tests:
57
+
58
+ ```typescript
59
+ import { col, table, storage, model, contract, pk, unique, index, fk } from '@prisma-next/sql-contract/exports/factories';
60
+
61
+ // Create a column
62
+ const idColumn = col('pg/int4@1', false);
63
+
64
+ // Create a table
65
+ const userTable = table(
66
+ {
67
+ id: col('pg/int4@1'),
68
+ email: col('pg/text@1'),
69
+ },
70
+ {
71
+ pk: pk('id'),
72
+ uniques: [unique('email')],
73
+ indexes: [index('email')],
74
+ }
75
+ );
76
+
77
+ // Create storage
78
+ const s = storage({ user: userTable });
79
+
80
+ // Create a model
81
+ const userModel = model('user', {
82
+ id: { column: 'id' },
83
+ email: { column: 'email' },
84
+ });
85
+
86
+ // Create a complete contract
87
+ const c = contract({
88
+ target: 'postgres',
89
+ coreHash: 'sha256:abc123',
90
+ storage: s,
91
+ models: { User: userModel },
92
+ });
93
+ ```
94
+
95
+ ## Exports
96
+
97
+ - `./exports/types`: TypeScript type definitions
98
+ - `./exports/validators`: Arktype validators for structural validation
99
+ - `./exports/factories`: Factory functions for constructing contract IR
100
+
101
+ ## Architecture
102
+
103
+ ```mermaid
104
+ flowchart TD
105
+ subgraph "SQL Contract Package (Shared Plane)"
106
+ TYPES[Type Definitions]
107
+ VALIDATORS[Validators]
108
+ FACTORIES[IR Factories]
109
+ end
110
+
111
+ subgraph "Migration Plane"
112
+ AUTHORING[Authoring]
113
+ EMITTER[Emitter]
114
+ end
115
+
116
+ subgraph "Runtime Plane"
117
+ LANES[Lanes]
118
+ RUNTIME[Runtime]
119
+ end
120
+
121
+ TYPES --> AUTHORING
122
+ TYPES --> EMITTER
123
+ TYPES --> LANES
124
+ TYPES --> RUNTIME
125
+ VALIDATORS --> AUTHORING
126
+ VALIDATORS --> EMITTER
127
+ VALIDATORS --> RUNTIME
128
+ FACTORIES --> AUTHORING
129
+ FACTORIES --> EMITTER
130
+ ```
131
+
132
+ ## Dependencies
133
+
134
+ - **`@prisma-next/contract`**: Framework-level contract types (`ContractBase`)
135
+ - **`arktype`**: Runtime validation library
136
+
137
+ **Dependents:**
138
+ - **`@prisma-next/sql-contract-ts`**: Uses SQL contract types and validators for authoring
139
+ - **`@prisma-next/sql-contract-emitter`**: Uses SQL contract types for emission
140
+ - **`@prisma-next/sql-query`**: Uses SQL contract types for query building
141
+ - **`@prisma-next/sql-runtime`**: Uses SQL contract types for runtime execution
142
+ - **`@prisma-next/sql-lane`**: Uses SQL contract types for lane operations
143
+
144
+ ## Related Packages
145
+
146
+ - `@prisma-next/contract`: Framework-level contract types (`ContractBase`)
147
+ - `@prisma-next/sql-contract-ts`: SQL contract authoring surface (uses this package)
148
+ - `@prisma-next/emitter`: Contract emission engine (uses validators)
149
+
150
+ ## Related Subsystems
151
+
152
+ - **[Data Contract](../../../docs/architecture%20docs/subsystems/1.%20Data%20Contract.md)**: Detailed subsystem specification
153
+ - **[Contract Emitter & Types](../../../docs/architecture%20docs/subsystems/2.%20Contract%20Emitter%20&%20Types.md)**: Contract emission
154
+
@@ -0,0 +1,33 @@
1
+ import { StorageColumn, SqlStorage, ModelDefinition, SqlMappings, SqlContract, ForeignKey, Index, ModelField, PrimaryKey, StorageTable, UniqueConstraint } from './types.js';
2
+ import '@prisma-next/contract/types';
3
+
4
+ declare function col(typeId: string, nullable?: boolean): StorageColumn;
5
+ declare function pk(...columns: readonly string[]): PrimaryKey;
6
+ declare function unique(...columns: readonly string[]): UniqueConstraint;
7
+ declare function index(...columns: readonly string[]): Index;
8
+ declare function fk(columns: readonly string[], refTable: string, refColumns: readonly string[], name?: string): ForeignKey;
9
+ declare function table(columns: Record<string, StorageColumn>, opts?: {
10
+ pk?: PrimaryKey;
11
+ uniques?: readonly UniqueConstraint[];
12
+ indexes?: readonly Index[];
13
+ fks?: readonly ForeignKey[];
14
+ }): StorageTable;
15
+ declare function model(table: string, fields: Record<string, ModelField>, relations?: Record<string, unknown>): ModelDefinition;
16
+ declare function storage(tables: Record<string, StorageTable>): SqlStorage;
17
+ declare function contract(opts: {
18
+ target: string;
19
+ coreHash: string;
20
+ storage: SqlStorage;
21
+ models?: Record<string, ModelDefinition>;
22
+ relations?: Record<string, unknown>;
23
+ mappings?: Partial<SqlMappings>;
24
+ schemaVersion?: '1';
25
+ targetFamily?: 'sql';
26
+ profileHash?: string;
27
+ capabilities?: Record<string, Record<string, boolean>>;
28
+ extensions?: Record<string, unknown>;
29
+ meta?: Record<string, unknown>;
30
+ sources?: Record<string, unknown>;
31
+ }): SqlContract;
32
+
33
+ export { col, contract, fk, index, model, pk, storage, table, unique };
@@ -0,0 +1,82 @@
1
+ // src/factories.ts
2
+ function col(typeId, nullable = false) {
3
+ return {
4
+ type: typeId,
5
+ nullable
6
+ };
7
+ }
8
+ function pk(...columns) {
9
+ return {
10
+ columns
11
+ };
12
+ }
13
+ function unique(...columns) {
14
+ return {
15
+ columns
16
+ };
17
+ }
18
+ function index(...columns) {
19
+ return {
20
+ columns
21
+ };
22
+ }
23
+ function fk(columns, refTable, refColumns, name) {
24
+ const references = {
25
+ table: refTable,
26
+ columns: refColumns
27
+ };
28
+ return {
29
+ columns,
30
+ references,
31
+ ...name !== void 0 && { name }
32
+ };
33
+ }
34
+ function table(columns, opts) {
35
+ return {
36
+ columns,
37
+ ...opts?.pk !== void 0 && { primaryKey: opts.pk },
38
+ uniques: opts?.uniques ?? [],
39
+ indexes: opts?.indexes ?? [],
40
+ foreignKeys: opts?.fks ?? []
41
+ };
42
+ }
43
+ function model(table2, fields, relations = {}) {
44
+ const storage2 = { table: table2 };
45
+ return {
46
+ storage: storage2,
47
+ fields,
48
+ relations
49
+ };
50
+ }
51
+ function storage(tables) {
52
+ return { tables };
53
+ }
54
+ function contract(opts) {
55
+ return {
56
+ schemaVersion: opts.schemaVersion ?? "1",
57
+ target: opts.target,
58
+ targetFamily: opts.targetFamily ?? "sql",
59
+ coreHash: opts.coreHash,
60
+ storage: opts.storage,
61
+ models: opts.models ?? {},
62
+ relations: opts.relations ?? {},
63
+ mappings: opts.mappings ?? {},
64
+ ...opts.profileHash !== void 0 && { profileHash: opts.profileHash },
65
+ ...opts.capabilities !== void 0 && { capabilities: opts.capabilities },
66
+ ...opts.extensions !== void 0 && { extensions: opts.extensions },
67
+ ...opts.meta !== void 0 && { meta: opts.meta },
68
+ ...opts.sources !== void 0 && { sources: opts.sources }
69
+ };
70
+ }
71
+ export {
72
+ col,
73
+ contract,
74
+ fk,
75
+ index,
76
+ model,
77
+ pk,
78
+ storage,
79
+ table,
80
+ unique
81
+ };
82
+ //# sourceMappingURL=factories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/factories.ts"],"sourcesContent":["import type {\n ForeignKey,\n ForeignKeyReferences,\n Index,\n ModelDefinition,\n ModelField,\n ModelStorage,\n PrimaryKey,\n SqlContract,\n SqlMappings,\n SqlStorage,\n StorageColumn,\n StorageTable,\n UniqueConstraint,\n} from './types';\n\nexport function col(typeId: string, nullable = false): StorageColumn {\n return {\n type: typeId,\n nullable,\n };\n}\n\nexport function pk(...columns: readonly string[]): PrimaryKey {\n return {\n columns,\n };\n}\n\nexport function unique(...columns: readonly string[]): UniqueConstraint {\n return {\n columns,\n };\n}\n\nexport function index(...columns: readonly string[]): Index {\n return {\n columns,\n };\n}\n\nexport function fk(\n columns: readonly string[],\n refTable: string,\n refColumns: readonly string[],\n name?: string,\n): ForeignKey {\n const references: ForeignKeyReferences = {\n table: refTable,\n columns: refColumns,\n };\n return {\n columns,\n references,\n ...(name !== undefined && { name }),\n };\n}\n\nexport function table(\n columns: Record<string, StorageColumn>,\n opts?: {\n pk?: PrimaryKey;\n uniques?: readonly UniqueConstraint[];\n indexes?: readonly Index[];\n fks?: readonly ForeignKey[];\n },\n): StorageTable {\n return {\n columns,\n ...(opts?.pk !== undefined && { primaryKey: opts.pk }),\n uniques: opts?.uniques ?? [],\n indexes: opts?.indexes ?? [],\n foreignKeys: opts?.fks ?? [],\n };\n}\n\nexport function model(\n table: string,\n fields: Record<string, ModelField>,\n relations: Record<string, unknown> = {},\n): ModelDefinition {\n const storage: ModelStorage = { table };\n return {\n storage,\n fields,\n relations,\n };\n}\n\nexport function storage(tables: Record<string, StorageTable>): SqlStorage {\n return { tables };\n}\n\nexport function contract(opts: {\n target: string;\n coreHash: string;\n storage: SqlStorage;\n models?: Record<string, ModelDefinition>;\n relations?: Record<string, unknown>;\n mappings?: Partial<SqlMappings>;\n schemaVersion?: '1';\n targetFamily?: 'sql';\n profileHash?: string;\n capabilities?: Record<string, Record<string, boolean>>;\n extensions?: Record<string, unknown>;\n meta?: Record<string, unknown>;\n sources?: Record<string, unknown>;\n}): SqlContract {\n return {\n schemaVersion: opts.schemaVersion ?? '1',\n target: opts.target,\n targetFamily: opts.targetFamily ?? 'sql',\n coreHash: opts.coreHash,\n storage: opts.storage,\n models: opts.models ?? {},\n relations: opts.relations ?? {},\n mappings: (opts.mappings ?? {}) as SqlMappings,\n ...(opts.profileHash !== undefined && { profileHash: opts.profileHash }),\n ...(opts.capabilities !== undefined && { capabilities: opts.capabilities }),\n ...(opts.extensions !== undefined && { extensions: opts.extensions }),\n ...(opts.meta !== undefined && { meta: opts.meta }),\n ...(opts.sources !== undefined && { sources: opts.sources as Record<string, unknown> }),\n } as SqlContract;\n}\n"],"mappings":";AAgBO,SAAS,IAAI,QAAgB,WAAW,OAAsB;AACnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AACF;AAEO,SAAS,MAAM,SAAwC;AAC5D,SAAO;AAAA,IACL;AAAA,EACF;AACF;AAEO,SAAS,UAAU,SAA8C;AACtE,SAAO;AAAA,IACL;AAAA,EACF;AACF;AAEO,SAAS,SAAS,SAAmC;AAC1D,SAAO;AAAA,IACL;AAAA,EACF;AACF;AAEO,SAAS,GACd,SACA,UACA,YACA,MACY;AACZ,QAAM,aAAmC;AAAA,IACvC,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,EACnC;AACF;AAEO,SAAS,MACd,SACA,MAMc;AACd,SAAO;AAAA,IACL;AAAA,IACA,GAAI,MAAM,OAAO,UAAa,EAAE,YAAY,KAAK,GAAG;AAAA,IACpD,SAAS,MAAM,WAAW,CAAC;AAAA,IAC3B,SAAS,MAAM,WAAW,CAAC;AAAA,IAC3B,aAAa,MAAM,OAAO,CAAC;AAAA,EAC7B;AACF;AAEO,SAAS,MACdA,QACA,QACA,YAAqC,CAAC,GACrB;AACjB,QAAMC,WAAwB,EAAE,OAAAD,OAAM;AACtC,SAAO;AAAA,IACL,SAAAC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,QAAQ,QAAkD;AACxE,SAAO,EAAE,OAAO;AAClB;AAEO,SAAS,SAAS,MAcT;AACd,SAAO;AAAA,IACL,eAAe,KAAK,iBAAiB;AAAA,IACrC,QAAQ,KAAK;AAAA,IACb,cAAc,KAAK,gBAAgB;AAAA,IACnC,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK,UAAU,CAAC;AAAA,IACxB,WAAW,KAAK,aAAa,CAAC;AAAA,IAC9B,UAAW,KAAK,YAAY,CAAC;AAAA,IAC7B,GAAI,KAAK,gBAAgB,UAAa,EAAE,aAAa,KAAK,YAAY;AAAA,IACtE,GAAI,KAAK,iBAAiB,UAAa,EAAE,cAAc,KAAK,aAAa;AAAA,IACzE,GAAI,KAAK,eAAe,UAAa,EAAE,YAAY,KAAK,WAAW;AAAA,IACnE,GAAI,KAAK,SAAS,UAAa,EAAE,MAAM,KAAK,KAAK;AAAA,IACjD,GAAI,KAAK,YAAY,UAAa,EAAE,SAAS,KAAK,QAAmC;AAAA,EACvF;AACF;","names":["table","storage"]}
@@ -0,0 +1,69 @@
1
+ import { ContractBase } from '@prisma-next/contract/types';
2
+
3
+ type StorageColumn = {
4
+ readonly type: string;
5
+ readonly nullable: boolean;
6
+ };
7
+ type PrimaryKey = {
8
+ readonly columns: readonly string[];
9
+ readonly name?: string;
10
+ };
11
+ type UniqueConstraint = {
12
+ readonly columns: readonly string[];
13
+ readonly name?: string;
14
+ };
15
+ type Index = {
16
+ readonly columns: readonly string[];
17
+ readonly name?: string;
18
+ };
19
+ type ForeignKeyReferences = {
20
+ readonly table: string;
21
+ readonly columns: readonly string[];
22
+ };
23
+ type ForeignKey = {
24
+ readonly columns: readonly string[];
25
+ readonly references: ForeignKeyReferences;
26
+ readonly name?: string;
27
+ };
28
+ type StorageTable = {
29
+ readonly columns: Record<string, StorageColumn>;
30
+ readonly primaryKey?: PrimaryKey;
31
+ readonly uniques: ReadonlyArray<UniqueConstraint>;
32
+ readonly indexes: ReadonlyArray<Index>;
33
+ readonly foreignKeys: ReadonlyArray<ForeignKey>;
34
+ };
35
+ type SqlStorage = {
36
+ readonly tables: Record<string, StorageTable>;
37
+ };
38
+ type ModelField = {
39
+ readonly column: string;
40
+ };
41
+ type ModelStorage = {
42
+ readonly table: string;
43
+ };
44
+ type ModelDefinition = {
45
+ readonly storage: ModelStorage;
46
+ readonly fields: Record<string, ModelField>;
47
+ readonly relations: Record<string, unknown>;
48
+ };
49
+ type SqlMappings = {
50
+ readonly modelToTable?: Record<string, string>;
51
+ readonly tableToModel?: Record<string, string>;
52
+ readonly fieldToColumn?: Record<string, Record<string, string>>;
53
+ readonly columnToField?: Record<string, Record<string, string>>;
54
+ readonly codecTypes: Record<string, {
55
+ readonly output: unknown;
56
+ }>;
57
+ readonly operationTypes: Record<string, Record<string, unknown>>;
58
+ };
59
+ type SqlContract<S extends SqlStorage = SqlStorage, M extends Record<string, unknown> = Record<string, unknown>, R extends Record<string, unknown> = Record<string, unknown>, Map extends SqlMappings = SqlMappings> = ContractBase & {
60
+ readonly targetFamily: string;
61
+ readonly storage: S;
62
+ readonly models: M;
63
+ readonly relations: R;
64
+ readonly mappings: Map;
65
+ };
66
+ type ExtractCodecTypes<TContract extends SqlContract<SqlStorage>> = TContract['mappings']['codecTypes'];
67
+ type ExtractOperationTypes<TContract extends SqlContract<SqlStorage>> = TContract['mappings']['operationTypes'];
68
+
69
+ export type { ExtractCodecTypes, ExtractOperationTypes, ForeignKey, ForeignKeyReferences, Index, ModelDefinition, ModelField, ModelStorage, PrimaryKey, SqlContract, SqlMappings, SqlStorage, StorageColumn, StorageTable, UniqueConstraint };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,38 @@
1
+ import { ModelDefinition, SqlContract, SqlStorage } from './types.js';
2
+ import '@prisma-next/contract/types';
3
+
4
+ /**
5
+ * Validates the structural shape of SqlStorage using Arktype.
6
+ *
7
+ * @param value - The storage value to validate
8
+ * @returns The validated storage if structure is valid
9
+ * @throws Error if the storage structure is invalid
10
+ */
11
+ declare function validateStorage(value: unknown): SqlStorage;
12
+ /**
13
+ * Validates the structural shape of ModelDefinition using Arktype.
14
+ *
15
+ * @param value - The model value to validate
16
+ * @returns The validated model if structure is valid
17
+ * @throws Error if the model structure is invalid
18
+ */
19
+ declare function validateModel(value: unknown): ModelDefinition;
20
+ /**
21
+ * Validates the structural shape of a SqlContract using Arktype.
22
+ *
23
+ * **Responsibility: Validation Only**
24
+ * This function validates that the contract has the correct structure and types.
25
+ * It does NOT normalize the contract - normalization must happen in the contract builder.
26
+ *
27
+ * The contract passed to this function must already be normalized (all required fields present).
28
+ * If normalization is needed, it should be done by the contract builder before calling this function.
29
+ *
30
+ * This ensures all required fields are present and have the correct types.
31
+ *
32
+ * @param value - The contract value to validate (typically from a JSON import)
33
+ * @returns The validated contract if structure is valid
34
+ * @throws Error if the contract structure is invalid
35
+ */
36
+ declare function validateSqlContract<T extends SqlContract<SqlStorage>>(value: unknown): T;
37
+
38
+ export { validateModel, validateSqlContract, validateStorage };
@@ -0,0 +1,95 @@
1
+ // src/validators.ts
2
+ import { type } from "arktype";
3
+ var StorageColumnSchema = type.declare().type({
4
+ type: "string",
5
+ nullable: "boolean"
6
+ });
7
+ var PrimaryKeySchema = type.declare().type({
8
+ columns: type.string.array().readonly(),
9
+ "name?": "string"
10
+ });
11
+ var UniqueConstraintSchema = type.declare().type({
12
+ columns: type.string.array().readonly(),
13
+ "name?": "string"
14
+ });
15
+ var IndexSchema = type.declare().type({
16
+ columns: type.string.array().readonly(),
17
+ "name?": "string"
18
+ });
19
+ var ForeignKeyReferencesSchema = type.declare().type({
20
+ table: "string",
21
+ columns: type.string.array().readonly()
22
+ });
23
+ var ForeignKeySchema = type.declare().type({
24
+ columns: type.string.array().readonly(),
25
+ references: ForeignKeyReferencesSchema,
26
+ "name?": "string"
27
+ });
28
+ var StorageTableSchema = type.declare().type({
29
+ columns: type({ "[string]": StorageColumnSchema }),
30
+ "primaryKey?": PrimaryKeySchema,
31
+ uniques: UniqueConstraintSchema.array().readonly(),
32
+ indexes: IndexSchema.array().readonly(),
33
+ foreignKeys: ForeignKeySchema.array().readonly()
34
+ });
35
+ var StorageSchema = type.declare().type({
36
+ tables: type({ "[string]": StorageTableSchema })
37
+ });
38
+ var ModelFieldSchema = type.declare().type({
39
+ column: "string"
40
+ });
41
+ var ModelStorageSchema = type.declare().type({
42
+ table: "string"
43
+ });
44
+ var ModelSchema = type.declare().type({
45
+ storage: ModelStorageSchema,
46
+ fields: type({ "[string]": ModelFieldSchema }),
47
+ relations: type({ "[string]": "unknown" })
48
+ });
49
+ var SqlContractSchema = type({
50
+ "schemaVersion?": "'1'",
51
+ target: "string",
52
+ targetFamily: "'sql'",
53
+ coreHash: "string",
54
+ "profileHash?": "string",
55
+ "capabilities?": "Record<string, Record<string, boolean>>",
56
+ "extensions?": "Record<string, unknown>",
57
+ "meta?": "Record<string, unknown>",
58
+ "sources?": "Record<string, unknown>",
59
+ models: type({ "[string]": ModelSchema }),
60
+ storage: StorageSchema
61
+ });
62
+ function validateStorage(value) {
63
+ const result = StorageSchema(value);
64
+ if (result instanceof type.errors) {
65
+ const messages = result.map((p) => p.message).join("; ");
66
+ throw new Error(`Storage validation failed: ${messages}`);
67
+ }
68
+ return result;
69
+ }
70
+ function validateModel(value) {
71
+ const result = ModelSchema(value);
72
+ if (result instanceof type.errors) {
73
+ const messages = result.map((p) => p.message).join("; ");
74
+ throw new Error(`Model validation failed: ${messages}`);
75
+ }
76
+ return result;
77
+ }
78
+ function validateSqlContract(value) {
79
+ const rawValue = value;
80
+ if (rawValue.targetFamily !== void 0 && rawValue.targetFamily !== "sql") {
81
+ throw new Error(`Unsupported target family: ${rawValue.targetFamily}`);
82
+ }
83
+ const contractResult = SqlContractSchema(value);
84
+ if (contractResult instanceof type.errors) {
85
+ const messages = contractResult.map((p) => p.message).join("; ");
86
+ throw new Error(`Contract structural validation failed: ${messages}`);
87
+ }
88
+ return contractResult;
89
+ }
90
+ export {
91
+ validateModel,
92
+ validateSqlContract,
93
+ validateStorage
94
+ };
95
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/validators.ts"],"sourcesContent":["import { type } from 'arktype';\nimport type {\n ForeignKey,\n ForeignKeyReferences,\n Index,\n ModelDefinition,\n ModelField,\n ModelStorage,\n PrimaryKey,\n SqlContract,\n SqlStorage,\n StorageColumn,\n StorageTable,\n UniqueConstraint,\n} from './types';\n\nconst StorageColumnSchema = type.declare<StorageColumn>().type({\n type: 'string',\n nullable: 'boolean',\n});\n\nconst PrimaryKeySchema = type.declare<PrimaryKey>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nconst UniqueConstraintSchema = type.declare<UniqueConstraint>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nconst IndexSchema = type.declare<Index>().type({\n columns: type.string.array().readonly(),\n 'name?': 'string',\n});\n\nconst ForeignKeyReferencesSchema = type.declare<ForeignKeyReferences>().type({\n table: 'string',\n columns: type.string.array().readonly(),\n});\n\nconst ForeignKeySchema = type.declare<ForeignKey>().type({\n columns: type.string.array().readonly(),\n references: ForeignKeyReferencesSchema,\n 'name?': 'string',\n});\n\nconst StorageTableSchema = type.declare<StorageTable>().type({\n columns: type({ '[string]': StorageColumnSchema }),\n 'primaryKey?': PrimaryKeySchema,\n uniques: UniqueConstraintSchema.array().readonly(),\n indexes: IndexSchema.array().readonly(),\n foreignKeys: ForeignKeySchema.array().readonly(),\n});\n\nconst StorageSchema = type.declare<SqlStorage>().type({\n tables: type({ '[string]': StorageTableSchema }),\n});\n\nconst ModelFieldSchema = type.declare<ModelField>().type({\n column: 'string',\n});\n\nconst ModelStorageSchema = type.declare<ModelStorage>().type({\n table: 'string',\n});\n\nconst ModelSchema = type.declare<ModelDefinition>().type({\n storage: ModelStorageSchema,\n fields: type({ '[string]': ModelFieldSchema }),\n relations: type({ '[string]': 'unknown' }),\n});\n\nconst SqlContractSchema = type({\n 'schemaVersion?': \"'1'\",\n target: 'string',\n targetFamily: \"'sql'\",\n coreHash: 'string',\n 'profileHash?': 'string',\n 'capabilities?': 'Record<string, Record<string, boolean>>',\n 'extensions?': 'Record<string, unknown>',\n 'meta?': 'Record<string, unknown>',\n 'sources?': 'Record<string, unknown>',\n models: type({ '[string]': ModelSchema }),\n storage: StorageSchema,\n});\n\n/**\n * Validates the structural shape of SqlStorage using Arktype.\n *\n * @param value - The storage value to validate\n * @returns The validated storage if structure is valid\n * @throws Error if the storage structure is invalid\n */\nexport function validateStorage(value: unknown): SqlStorage {\n const result = StorageSchema(value);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Storage validation failed: ${messages}`);\n }\n return result;\n}\n\n/**\n * Validates the structural shape of ModelDefinition using Arktype.\n *\n * @param value - The model value to validate\n * @returns The validated model if structure is valid\n * @throws Error if the model structure is invalid\n */\nexport function validateModel(value: unknown): ModelDefinition {\n const result = ModelSchema(value);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Model validation failed: ${messages}`);\n }\n return result;\n}\n\n/**\n * Validates the structural shape of a SqlContract using Arktype.\n *\n * **Responsibility: Validation Only**\n * This function validates that the contract has the correct structure and types.\n * It does NOT normalize the contract - normalization must happen in the contract builder.\n *\n * The contract passed to this function must already be normalized (all required fields present).\n * If normalization is needed, it should be done by the contract builder before calling this function.\n *\n * This ensures all required fields are present and have the correct types.\n *\n * @param value - The contract value to validate (typically from a JSON import)\n * @returns The validated contract if structure is valid\n * @throws Error if the contract structure is invalid\n */\nexport function validateSqlContract<T extends SqlContract<SqlStorage>>(value: unknown): T {\n // Check targetFamily first to provide a clear error message for unsupported target families\n const rawValue = value as { targetFamily?: string };\n if (rawValue.targetFamily !== undefined && rawValue.targetFamily !== 'sql') {\n throw new Error(`Unsupported target family: ${rawValue.targetFamily}`);\n }\n\n const contractResult = SqlContractSchema(value);\n\n if (contractResult instanceof type.errors) {\n const messages = contractResult.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Contract structural validation failed: ${messages}`);\n }\n\n // After validation, contractResult matches the schema and preserves the input structure\n // TypeScript needs an assertion here due to exactOptionalPropertyTypes differences\n // between Arktype's inferred type and the generic T, but runtime-wise they're compatible\n return contractResult as T;\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAgBrB,IAAM,sBAAsB,KAAK,QAAuB,EAAE,KAAK;AAAA,EAC7D,MAAM;AAAA,EACN,UAAU;AACZ,CAAC;AAED,IAAM,mBAAmB,KAAK,QAAoB,EAAE,KAAK;AAAA,EACvD,SAAS,KAAK,OAAO,MAAM,EAAE,SAAS;AAAA,EACtC,SAAS;AACX,CAAC;AAED,IAAM,yBAAyB,KAAK,QAA0B,EAAE,KAAK;AAAA,EACnE,SAAS,KAAK,OAAO,MAAM,EAAE,SAAS;AAAA,EACtC,SAAS;AACX,CAAC;AAED,IAAM,cAAc,KAAK,QAAe,EAAE,KAAK;AAAA,EAC7C,SAAS,KAAK,OAAO,MAAM,EAAE,SAAS;AAAA,EACtC,SAAS;AACX,CAAC;AAED,IAAM,6BAA6B,KAAK,QAA8B,EAAE,KAAK;AAAA,EAC3E,OAAO;AAAA,EACP,SAAS,KAAK,OAAO,MAAM,EAAE,SAAS;AACxC,CAAC;AAED,IAAM,mBAAmB,KAAK,QAAoB,EAAE,KAAK;AAAA,EACvD,SAAS,KAAK,OAAO,MAAM,EAAE,SAAS;AAAA,EACtC,YAAY;AAAA,EACZ,SAAS;AACX,CAAC;AAED,IAAM,qBAAqB,KAAK,QAAsB,EAAE,KAAK;AAAA,EAC3D,SAAS,KAAK,EAAE,YAAY,oBAAoB,CAAC;AAAA,EACjD,eAAe;AAAA,EACf,SAAS,uBAAuB,MAAM,EAAE,SAAS;AAAA,EACjD,SAAS,YAAY,MAAM,EAAE,SAAS;AAAA,EACtC,aAAa,iBAAiB,MAAM,EAAE,SAAS;AACjD,CAAC;AAED,IAAM,gBAAgB,KAAK,QAAoB,EAAE,KAAK;AAAA,EACpD,QAAQ,KAAK,EAAE,YAAY,mBAAmB,CAAC;AACjD,CAAC;AAED,IAAM,mBAAmB,KAAK,QAAoB,EAAE,KAAK;AAAA,EACvD,QAAQ;AACV,CAAC;AAED,IAAM,qBAAqB,KAAK,QAAsB,EAAE,KAAK;AAAA,EAC3D,OAAO;AACT,CAAC;AAED,IAAM,cAAc,KAAK,QAAyB,EAAE,KAAK;AAAA,EACvD,SAAS;AAAA,EACT,QAAQ,KAAK,EAAE,YAAY,iBAAiB,CAAC;AAAA,EAC7C,WAAW,KAAK,EAAE,YAAY,UAAU,CAAC;AAC3C,CAAC;AAED,IAAM,oBAAoB,KAAK;AAAA,EAC7B,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,QAAQ,KAAK,EAAE,YAAY,YAAY,CAAC;AAAA,EACxC,SAAS;AACX,CAAC;AASM,SAAS,gBAAgB,OAA4B;AAC1D,QAAM,SAAS,cAAc,KAAK;AAClC,MAAI,kBAAkB,KAAK,QAAQ;AACjC,UAAM,WAAW,OAAO,IAAI,CAAC,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI;AAC5E,UAAM,IAAI,MAAM,8BAA8B,QAAQ,EAAE;AAAA,EAC1D;AACA,SAAO;AACT;AASO,SAAS,cAAc,OAAiC;AAC7D,QAAM,SAAS,YAAY,KAAK;AAChC,MAAI,kBAAkB,KAAK,QAAQ;AACjC,UAAM,WAAW,OAAO,IAAI,CAAC,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI;AAC5E,UAAM,IAAI,MAAM,4BAA4B,QAAQ,EAAE;AAAA,EACxD;AACA,SAAO;AACT;AAkBO,SAAS,oBAAuD,OAAmB;AAExF,QAAM,WAAW;AACjB,MAAI,SAAS,iBAAiB,UAAa,SAAS,iBAAiB,OAAO;AAC1E,UAAM,IAAI,MAAM,8BAA8B,SAAS,YAAY,EAAE;AAAA,EACvE;AAEA,QAAM,iBAAiB,kBAAkB,KAAK;AAE9C,MAAI,0BAA0B,KAAK,QAAQ;AACzC,UAAM,WAAW,eAAe,IAAI,CAAC,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI;AACpF,UAAM,IAAI,MAAM,0CAA0C,QAAQ,EAAE;AAAA,EACtE;AAKA,SAAO;AACT;","names":[]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@prisma-next/sql-contract",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "description": "SQL contract types, validators, and IR factories for Prisma Next",
7
+ "dependencies": {
8
+ "arktype": "^2.1.25",
9
+ "@prisma-next/contract": "0.0.1"
10
+ },
11
+ "devDependencies": {
12
+ "@vitest/coverage-v8": "^2.1.1",
13
+ "tsup": "^8.3.0",
14
+ "typescript": "^5.9.3",
15
+ "vitest": "^2.1.1",
16
+ "@prisma-next/test-utils": "0.0.1"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "exports": {
22
+ "./types": {
23
+ "types": "./dist/exports/types.d.ts",
24
+ "import": "./dist/exports/types.js"
25
+ },
26
+ "./validators": {
27
+ "types": "./dist/exports/validators.d.ts",
28
+ "import": "./dist/exports/validators.js"
29
+ },
30
+ "./factories": {
31
+ "types": "./dist/exports/factories.d.ts",
32
+ "import": "./dist/exports/factories.js"
33
+ }
34
+ },
35
+ "scripts": {
36
+ "build": "tsup --config tsup.config.ts",
37
+ "test": "vitest run",
38
+ "test:coverage": "vitest run --coverage",
39
+ "typecheck": "tsc --project tsconfig.json --noEmit",
40
+ "lint": "biome check . --config-path ../../../biome.json --error-on-warnings",
41
+ "clean": "node ../../../../scripts/clean.mjs"
42
+ }
43
+ }