@prisma-next/core-control-plane 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 +118 -0
- package/dist/chunk-DZPZSLCM.js +178 -0
- package/dist/chunk-DZPZSLCM.js.map +1 -0
- package/dist/exports/config-types.d.ts +69 -0
- package/dist/exports/config-types.js +53 -0
- package/dist/exports/config-types.js.map +1 -0
- package/dist/exports/config-validation.d.ts +17 -0
- package/dist/exports/config-validation.js +252 -0
- package/dist/exports/config-validation.js.map +1 -0
- package/dist/exports/emission.d.ts +42 -0
- package/dist/exports/emission.js +313 -0
- package/dist/exports/emission.js.map +1 -0
- package/dist/exports/errors.d.ts +146 -0
- package/dist/exports/errors.js +35 -0
- package/dist/exports/errors.js.map +1 -0
- package/dist/exports/schema-view.d.ts +87 -0
- package/dist/exports/schema-view.js +1 -0
- package/dist/exports/schema-view.js.map +1 -0
- package/dist/exports/types.d.ts +371 -0
- package/dist/exports/types.js +1 -0
- package/dist/exports/types.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# @prisma-next/core-control-plane
|
|
2
|
+
|
|
3
|
+
Control plane domain actions, config types, validation, and error factories for Prisma Next.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides the core domain logic for control plane operations (contract emission, database verification) without any file I/O or CLI awareness. It's part of the core layer and can be used programmatically or by the CLI layer.
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- **Config Types**: Type definitions for Prisma Next configuration (`PrismaNextConfig`, `ControlFamilyDescriptor`, `ControlTargetDescriptor`, `ControlAdapterDescriptor`, `ControlDriverDescriptor`, `ControlExtensionDescriptor`)
|
|
12
|
+
- **Config Validation**: Pure validation logic for config structure (no file I/O)
|
|
13
|
+
- **Config Normalization**: `defineConfig()` function for normalizing config with defaults
|
|
14
|
+
- **Domain Actions**:
|
|
15
|
+
- `verifyDatabase()`: Verifies database contract markers (accepts config object and ContractIR)
|
|
16
|
+
|
|
17
|
+
Note: Contract emission is implemented on family instances (e.g., `familyInstance.emitContract()`), not as a core domain action.
|
|
18
|
+
- **Error Factories**: Domain error factories (`CliStructuredError`, config errors, runtime errors)
|
|
19
|
+
- **Pack Manifest Types**: Type definitions for extension pack manifests
|
|
20
|
+
|
|
21
|
+
## Dependencies
|
|
22
|
+
|
|
23
|
+
- **Depends on**:
|
|
24
|
+
- `@prisma-next/contract` - ContractIR types
|
|
25
|
+
- `@prisma-next/emitter` - TargetFamilyHook, emit function
|
|
26
|
+
- `@prisma-next/operations` - OperationRegistry
|
|
27
|
+
- `arktype` - Validation
|
|
28
|
+
|
|
29
|
+
- **Depended on by**:
|
|
30
|
+
- `@prisma-next/cli` - CLI layer uses domain actions
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
```mermaid
|
|
35
|
+
flowchart TD
|
|
36
|
+
subgraph "Core Layer"
|
|
37
|
+
CCP[@prisma-next/core-control-plane]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
subgraph "Tooling Layer"
|
|
41
|
+
CLI[@prisma-next/cli]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
CLI -->|uses| CCP
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
### Config Types and Validation
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { defineConfig, validateConfig, type PrismaNextConfig } from '@prisma-next/core-control-plane/config-types';
|
|
53
|
+
import { validateConfig } from '@prisma-next/core-control-plane/config-validation';
|
|
54
|
+
|
|
55
|
+
// Define and normalize config
|
|
56
|
+
const config = defineConfig({
|
|
57
|
+
family: sqlFamilyDescriptor,
|
|
58
|
+
target: postgresTargetDescriptor,
|
|
59
|
+
adapter: postgresAdapterDescriptor,
|
|
60
|
+
contract: {
|
|
61
|
+
source: contractBuilder,
|
|
62
|
+
output: 'src/prisma/contract.json',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Validate config structure (pure validation, no file I/O)
|
|
67
|
+
validateConfig(config);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Verify Database
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { verifyDatabase } from '@prisma-next/core-control-plane/verify-database';
|
|
74
|
+
|
|
75
|
+
// Verify database - accepts config object and ContractIR (no file loading)
|
|
76
|
+
const result = await verifyDatabase({
|
|
77
|
+
config: loadedConfig,
|
|
78
|
+
contractIR: parsedContract,
|
|
79
|
+
dbUrl: connectionString,
|
|
80
|
+
contractPath: 'src/prisma/contract.json',
|
|
81
|
+
configPath: 'prisma-next.config.ts',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (result.ok) {
|
|
85
|
+
console.log('Database matches contract');
|
|
86
|
+
} else {
|
|
87
|
+
console.error(`Verification failed: ${result.summary}`);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Error Factories
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import {
|
|
95
|
+
errorConfigFileNotFound,
|
|
96
|
+
errorMarkerMissing,
|
|
97
|
+
errorHashMismatch,
|
|
98
|
+
} from '@prisma-next/core-control-plane/errors';
|
|
99
|
+
|
|
100
|
+
throw errorConfigFileNotFound('prisma-next.config.ts', {
|
|
101
|
+
why: 'Config file not found in current directory',
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Package Location
|
|
106
|
+
|
|
107
|
+
This package is part of the **framework domain**, **core layer**, **migration plane**:
|
|
108
|
+
- **Domain**: framework (target-agnostic)
|
|
109
|
+
- **Layer**: core
|
|
110
|
+
- **Plane**: migration (control plane operations)
|
|
111
|
+
- **Path**: `packages/framework/core-control-plane`
|
|
112
|
+
|
|
113
|
+
## Related Documentation
|
|
114
|
+
|
|
115
|
+
- [Package Layering](../../../../docs/architecture docs/Package-Layering.md)
|
|
116
|
+
- [ADR 140 - Package Layering & Target-Family Namespacing](../../../../docs/architecture docs/adrs/ADR 140 - Package Layering & Target-Family Namespacing.md)
|
|
117
|
+
|
|
118
|
+
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var CliStructuredError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
domain;
|
|
5
|
+
severity;
|
|
6
|
+
why;
|
|
7
|
+
fix;
|
|
8
|
+
where;
|
|
9
|
+
meta;
|
|
10
|
+
docsUrl;
|
|
11
|
+
constructor(code, summary, options) {
|
|
12
|
+
super(summary);
|
|
13
|
+
this.name = "CliStructuredError";
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.domain = options?.domain ?? "CLI";
|
|
16
|
+
this.severity = options?.severity ?? "error";
|
|
17
|
+
this.why = options?.why;
|
|
18
|
+
this.fix = options?.fix;
|
|
19
|
+
this.where = options?.where ? {
|
|
20
|
+
path: options.where.path,
|
|
21
|
+
line: options.where.line
|
|
22
|
+
} : void 0;
|
|
23
|
+
this.meta = options?.meta;
|
|
24
|
+
this.docsUrl = options?.docsUrl;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Converts this error to a CLI error envelope for output formatting.
|
|
28
|
+
*/
|
|
29
|
+
toEnvelope() {
|
|
30
|
+
const codePrefix = this.domain === "CLI" ? "PN-CLI-" : "PN-RTM-";
|
|
31
|
+
return {
|
|
32
|
+
code: `${codePrefix}${this.code}`,
|
|
33
|
+
domain: this.domain,
|
|
34
|
+
severity: this.severity,
|
|
35
|
+
summary: this.message,
|
|
36
|
+
why: this.why,
|
|
37
|
+
fix: this.fix,
|
|
38
|
+
where: this.where,
|
|
39
|
+
meta: this.meta,
|
|
40
|
+
docsUrl: this.docsUrl
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
function errorConfigFileNotFound(configPath, options) {
|
|
45
|
+
return new CliStructuredError("4001", "Config file not found", {
|
|
46
|
+
domain: "CLI",
|
|
47
|
+
...options?.why ? { why: options.why } : { why: "Config file not found" },
|
|
48
|
+
fix: "Run 'prisma-next init' to create a config file",
|
|
49
|
+
docsUrl: "https://prisma-next.dev/docs/cli/config",
|
|
50
|
+
...configPath ? { where: { path: configPath } } : {}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function errorContractConfigMissing(options) {
|
|
54
|
+
return new CliStructuredError("4002", "Contract configuration missing", {
|
|
55
|
+
domain: "CLI",
|
|
56
|
+
why: options?.why ?? "The contract configuration is required for emit",
|
|
57
|
+
fix: "Add contract configuration to your prisma-next.config.ts",
|
|
58
|
+
docsUrl: "https://prisma-next.dev/docs/cli/contract-emit"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function errorContractValidationFailed(reason, options) {
|
|
62
|
+
return new CliStructuredError("4003", "Contract validation failed", {
|
|
63
|
+
domain: "CLI",
|
|
64
|
+
why: reason,
|
|
65
|
+
fix: "Check your contract file for errors",
|
|
66
|
+
docsUrl: "https://prisma-next.dev/docs/contracts",
|
|
67
|
+
...options?.where ? { where: options.where } : {}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function errorFileNotFound(filePath, options) {
|
|
71
|
+
return new CliStructuredError("4004", "File not found", {
|
|
72
|
+
domain: "CLI",
|
|
73
|
+
why: options?.why ?? `File not found: ${filePath}`,
|
|
74
|
+
fix: "Check that the file path is correct",
|
|
75
|
+
where: { path: filePath }
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function errorDatabaseUrlRequired(options) {
|
|
79
|
+
return new CliStructuredError("4005", "Database URL is required", {
|
|
80
|
+
domain: "CLI",
|
|
81
|
+
why: options?.why ?? "Database URL is required for db verify",
|
|
82
|
+
fix: "Provide --db flag or config.db.url in prisma-next.config.ts"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function errorQueryRunnerFactoryRequired(options) {
|
|
86
|
+
return new CliStructuredError("4006", "Query runner factory is required", {
|
|
87
|
+
domain: "CLI",
|
|
88
|
+
why: options?.why ?? "Config.db.queryRunnerFactory is required for db verify",
|
|
89
|
+
fix: "Add db.queryRunnerFactory to prisma-next.config.ts",
|
|
90
|
+
docsUrl: "https://prisma-next.dev/docs/cli/db-verify"
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function errorFamilyReadMarkerSqlRequired(options) {
|
|
94
|
+
return new CliStructuredError("4007", "Family readMarker() is required", {
|
|
95
|
+
domain: "CLI",
|
|
96
|
+
why: options?.why ?? "Family verify.readMarker is required for db verify",
|
|
97
|
+
fix: "Ensure family.verify.readMarker() is exported by your family package",
|
|
98
|
+
docsUrl: "https://prisma-next.dev/docs/cli/db-verify"
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function errorDriverRequired(options) {
|
|
102
|
+
return new CliStructuredError("4010", "Driver is required for DB-connected commands", {
|
|
103
|
+
domain: "CLI",
|
|
104
|
+
why: options?.why ?? "Config.driver is required for db verify",
|
|
105
|
+
fix: "Add driver to prisma-next.config.ts",
|
|
106
|
+
docsUrl: "https://prisma-next.dev/docs/cli/db-verify"
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function errorConfigValidation(field, options) {
|
|
110
|
+
return new CliStructuredError("4001", "Config file not found", {
|
|
111
|
+
domain: "CLI",
|
|
112
|
+
why: options?.why ?? `Config must have a "${field}" field`,
|
|
113
|
+
fix: "Run 'prisma-next init' to create a config file",
|
|
114
|
+
docsUrl: "https://prisma-next.dev/docs/cli/config"
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function errorMarkerMissing(options) {
|
|
118
|
+
return new CliStructuredError("3001", "Marker missing", {
|
|
119
|
+
domain: "RTM",
|
|
120
|
+
why: options?.why ?? "Contract marker not found in database",
|
|
121
|
+
fix: "Run `prisma-next db sign --db <url>` to create marker"
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function errorHashMismatch(options) {
|
|
125
|
+
return new CliStructuredError("3002", "Hash mismatch", {
|
|
126
|
+
domain: "RTM",
|
|
127
|
+
why: options?.why ?? "Contract hash does not match database marker",
|
|
128
|
+
fix: "Migrate database or re-sign if intentional",
|
|
129
|
+
...options?.expected || options?.actual ? {
|
|
130
|
+
meta: {
|
|
131
|
+
...options.expected ? { expected: options.expected } : {},
|
|
132
|
+
...options.actual ? { actual: options.actual } : {}
|
|
133
|
+
}
|
|
134
|
+
} : {}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function errorTargetMismatch(expected, actual, options) {
|
|
138
|
+
return new CliStructuredError("3003", "Target mismatch", {
|
|
139
|
+
domain: "RTM",
|
|
140
|
+
why: options?.why ?? `Contract target does not match config target (expected: ${expected}, actual: ${actual})`,
|
|
141
|
+
fix: "Align contract target and config target",
|
|
142
|
+
meta: { expected, actual }
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function errorRuntime(summary, options) {
|
|
146
|
+
return new CliStructuredError("3000", summary, {
|
|
147
|
+
domain: "RTM",
|
|
148
|
+
...options?.why ? { why: options.why } : { why: "Verification failed" },
|
|
149
|
+
...options?.fix ? { fix: options.fix } : { fix: "Check contract and database state" },
|
|
150
|
+
...options?.meta ? { meta: options.meta } : {}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function errorUnexpected(message, options) {
|
|
154
|
+
return new CliStructuredError("4999", "Unexpected error", {
|
|
155
|
+
domain: "CLI",
|
|
156
|
+
why: options?.why ?? message,
|
|
157
|
+
fix: options?.fix ?? "Check the error message and try again"
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export {
|
|
162
|
+
CliStructuredError,
|
|
163
|
+
errorConfigFileNotFound,
|
|
164
|
+
errorContractConfigMissing,
|
|
165
|
+
errorContractValidationFailed,
|
|
166
|
+
errorFileNotFound,
|
|
167
|
+
errorDatabaseUrlRequired,
|
|
168
|
+
errorQueryRunnerFactoryRequired,
|
|
169
|
+
errorFamilyReadMarkerSqlRequired,
|
|
170
|
+
errorDriverRequired,
|
|
171
|
+
errorConfigValidation,
|
|
172
|
+
errorMarkerMissing,
|
|
173
|
+
errorHashMismatch,
|
|
174
|
+
errorTargetMismatch,
|
|
175
|
+
errorRuntime,
|
|
176
|
+
errorUnexpected
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=chunk-DZPZSLCM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * CLI error envelope for output formatting.\n * This is the serialized form of a CliStructuredError.\n */\nexport interface CliErrorEnvelope {\n readonly code: string;\n readonly domain: string;\n readonly severity: 'error' | 'warn' | 'info';\n readonly summary: string;\n readonly why: string | undefined;\n readonly fix: string | undefined;\n readonly where:\n | {\n readonly path: string | undefined;\n readonly line: number | undefined;\n }\n | undefined;\n readonly meta: Record<string, unknown> | undefined;\n readonly docsUrl: string | undefined;\n}\n\n/**\n * Structured CLI error that contains all information needed for error envelopes.\n * Call sites throw these errors with full context.\n */\nexport class CliStructuredError extends Error {\n readonly code: string;\n readonly domain: 'CLI' | 'RTM';\n readonly severity: 'error' | 'warn' | 'info';\n readonly why: string | undefined;\n readonly fix: string | undefined;\n readonly where:\n | {\n readonly path: string | undefined;\n readonly line: number | undefined;\n }\n | undefined;\n readonly meta: Record<string, unknown> | undefined;\n readonly docsUrl: string | undefined;\n\n constructor(\n code: string,\n summary: string,\n options?: {\n readonly domain?: 'CLI' | 'RTM';\n readonly severity?: 'error' | 'warn' | 'info';\n readonly why?: string;\n readonly fix?: string;\n readonly where?: { readonly path?: string; readonly line?: number };\n readonly meta?: Record<string, unknown>;\n readonly docsUrl?: string;\n },\n ) {\n super(summary);\n this.name = 'CliStructuredError';\n this.code = code;\n this.domain = options?.domain ?? 'CLI';\n this.severity = options?.severity ?? 'error';\n this.why = options?.why;\n this.fix = options?.fix;\n this.where = options?.where\n ? {\n path: options.where.path,\n line: options.where.line,\n }\n : undefined;\n this.meta = options?.meta;\n this.docsUrl = options?.docsUrl;\n }\n\n /**\n * Converts this error to a CLI error envelope for output formatting.\n */\n toEnvelope(): CliErrorEnvelope {\n const codePrefix = this.domain === 'CLI' ? 'PN-CLI-' : 'PN-RTM-';\n return {\n code: `${codePrefix}${this.code}`,\n domain: this.domain,\n severity: this.severity,\n summary: this.message,\n why: this.why,\n fix: this.fix,\n where: this.where,\n meta: this.meta,\n docsUrl: this.docsUrl,\n };\n }\n}\n\n// ============================================================================\n// Config Errors (PN-CLI-4001-4007)\n// ============================================================================\n\n/**\n * Config file not found or missing.\n */\nexport function errorConfigFileNotFound(\n configPath?: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4001', 'Config file not found', {\n domain: 'CLI',\n ...(options?.why ? { why: options.why } : { why: 'Config file not found' }),\n fix: \"Run 'prisma-next init' to create a config file\",\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n ...(configPath ? { where: { path: configPath } } : {}),\n });\n}\n\n/**\n * Contract configuration missing from config.\n */\nexport function errorContractConfigMissing(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4002', 'Contract configuration missing', {\n domain: 'CLI',\n why: options?.why ?? 'The contract configuration is required for emit',\n fix: 'Add contract configuration to your prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/contract-emit',\n });\n}\n\n/**\n * Contract validation failed.\n */\nexport function errorContractValidationFailed(\n reason: string,\n options?: {\n readonly where?: { readonly path?: string; readonly line?: number };\n },\n): CliStructuredError {\n return new CliStructuredError('4003', 'Contract validation failed', {\n domain: 'CLI',\n why: reason,\n fix: 'Check your contract file for errors',\n docsUrl: 'https://prisma-next.dev/docs/contracts',\n ...(options?.where ? { where: options.where } : {}),\n });\n}\n\n/**\n * File not found.\n */\nexport function errorFileNotFound(\n filePath: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4004', 'File not found', {\n domain: 'CLI',\n why: options?.why ?? `File not found: ${filePath}`,\n fix: 'Check that the file path is correct',\n where: { path: filePath },\n });\n}\n\n/**\n * Database URL is required but not provided.\n */\nexport function errorDatabaseUrlRequired(options?: { readonly why?: string }): CliStructuredError {\n return new CliStructuredError('4005', 'Database URL is required', {\n domain: 'CLI',\n why: options?.why ?? 'Database URL is required for db verify',\n fix: 'Provide --db flag or config.db.url in prisma-next.config.ts',\n });\n}\n\n/**\n * Query runner factory is required but not provided in config.\n */\nexport function errorQueryRunnerFactoryRequired(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4006', 'Query runner factory is required', {\n domain: 'CLI',\n why: options?.why ?? 'Config.db.queryRunnerFactory is required for db verify',\n fix: 'Add db.queryRunnerFactory to prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * Family verify.readMarker is required but not provided.\n */\nexport function errorFamilyReadMarkerSqlRequired(options?: {\n readonly why?: string;\n}): CliStructuredError {\n return new CliStructuredError('4007', 'Family readMarker() is required', {\n domain: 'CLI',\n why: options?.why ?? 'Family verify.readMarker is required for db verify',\n fix: 'Ensure family.verify.readMarker() is exported by your family package',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * Driver is required for DB-connected commands but not provided.\n */\nexport function errorDriverRequired(options?: { readonly why?: string }): CliStructuredError {\n return new CliStructuredError('4010', 'Driver is required for DB-connected commands', {\n domain: 'CLI',\n why: options?.why ?? 'Config.driver is required for db verify',\n fix: 'Add driver to prisma-next.config.ts',\n docsUrl: 'https://prisma-next.dev/docs/cli/db-verify',\n });\n}\n\n/**\n * Config validation error (missing required fields).\n */\nexport function errorConfigValidation(\n field: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4001', 'Config file not found', {\n domain: 'CLI',\n why: options?.why ?? `Config must have a \"${field}\" field`,\n fix: \"Run 'prisma-next init' to create a config file\",\n docsUrl: 'https://prisma-next.dev/docs/cli/config',\n });\n}\n\n// ============================================================================\n// Runtime Errors (PN-RTM-3000-3003)\n// ============================================================================\n\n/**\n * Contract marker not found in database.\n */\nexport function errorMarkerMissing(options?: {\n readonly why?: string;\n readonly dbUrl?: string;\n}): CliStructuredError {\n return new CliStructuredError('3001', 'Marker missing', {\n domain: 'RTM',\n why: options?.why ?? 'Contract marker not found in database',\n fix: 'Run `prisma-next db sign --db <url>` to create marker',\n });\n}\n\n/**\n * Contract hash does not match database marker.\n */\nexport function errorHashMismatch(options?: {\n readonly why?: string;\n readonly expected?: string;\n readonly actual?: string;\n}): CliStructuredError {\n return new CliStructuredError('3002', 'Hash mismatch', {\n domain: 'RTM',\n why: options?.why ?? 'Contract hash does not match database marker',\n fix: 'Migrate database or re-sign if intentional',\n ...(options?.expected || options?.actual\n ? {\n meta: {\n ...(options.expected ? { expected: options.expected } : {}),\n ...(options.actual ? { actual: options.actual } : {}),\n },\n }\n : {}),\n });\n}\n\n/**\n * Contract target does not match config target.\n */\nexport function errorTargetMismatch(\n expected: string,\n actual: string,\n options?: {\n readonly why?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('3003', 'Target mismatch', {\n domain: 'RTM',\n why:\n options?.why ??\n `Contract target does not match config target (expected: ${expected}, actual: ${actual})`,\n fix: 'Align contract target and config target',\n meta: { expected, actual },\n });\n}\n\n/**\n * Generic runtime error.\n */\nexport function errorRuntime(\n summary: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n readonly meta?: Record<string, unknown>;\n },\n): CliStructuredError {\n return new CliStructuredError('3000', summary, {\n domain: 'RTM',\n ...(options?.why ? { why: options.why } : { why: 'Verification failed' }),\n ...(options?.fix ? { fix: options.fix } : { fix: 'Check contract and database state' }),\n ...(options?.meta ? { meta: options.meta } : {}),\n });\n}\n\n// ============================================================================\n// Generic Error\n// ============================================================================\n\n/**\n * Generic unexpected error.\n */\nexport function errorUnexpected(\n message: string,\n options?: {\n readonly why?: string;\n readonly fix?: string;\n },\n): CliStructuredError {\n return new CliStructuredError('4999', 'Unexpected error', {\n domain: 'CLI',\n why: options?.why ?? message,\n fix: options?.fix ?? 'Check the error message and try again',\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ControlFamilyDescriptor, ControlTargetDescriptor, ControlAdapterDescriptor, ControlExtensionDescriptor, ControlDriverDescriptor } from './types.js';
|
|
2
|
+
import '@prisma-next/contract/ir';
|
|
3
|
+
import '@prisma-next/contract/pack-manifest-types';
|
|
4
|
+
import '@prisma-next/contract/types';
|
|
5
|
+
import './schema-view.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Contract configuration specifying source and artifact locations.
|
|
9
|
+
*/
|
|
10
|
+
interface ContractConfig {
|
|
11
|
+
/**
|
|
12
|
+
* Contract source. Can be a value or a function that returns a value (sync or async).
|
|
13
|
+
* If a function, it will be called to resolve the contract.
|
|
14
|
+
*/
|
|
15
|
+
readonly source: unknown | (() => unknown | Promise<unknown>);
|
|
16
|
+
/**
|
|
17
|
+
* Path to contract.json artifact. Defaults to 'src/prisma/contract.json'.
|
|
18
|
+
* This is the canonical location where other CLI commands can find the contract JSON.
|
|
19
|
+
*/
|
|
20
|
+
readonly output?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Path to contract.d.ts artifact. Defaults to output with .d.ts extension.
|
|
23
|
+
* If output ends with .json, replaces .json with .d.ts.
|
|
24
|
+
* Otherwise, appends .d.ts to the directory containing output.
|
|
25
|
+
*/
|
|
26
|
+
readonly types?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Configuration for Prisma Next CLI.
|
|
30
|
+
* Uses Control*Descriptor types for type-safe wiring with compile-time compatibility checks.
|
|
31
|
+
*
|
|
32
|
+
* @template TFamilyId - The family ID (e.g., 'sql', 'document')
|
|
33
|
+
* @template TTargetId - The target ID (e.g., 'postgres', 'mysql')
|
|
34
|
+
*/
|
|
35
|
+
interface PrismaNextConfig<TFamilyId extends string = string, TTargetId extends string = string> {
|
|
36
|
+
readonly family: ControlFamilyDescriptor<TFamilyId>;
|
|
37
|
+
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
|
|
38
|
+
readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;
|
|
39
|
+
readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
|
|
40
|
+
/**
|
|
41
|
+
* Driver descriptor for DB-connected CLI commands.
|
|
42
|
+
* Required for DB-connected commands (e.g., db verify).
|
|
43
|
+
* Optional for commands that don't need database access (e.g., emit).
|
|
44
|
+
*/
|
|
45
|
+
readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId>;
|
|
46
|
+
readonly db?: {
|
|
47
|
+
readonly url?: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Contract configuration. Specifies source and artifact locations.
|
|
51
|
+
* Required for emit command; optional for other commands that only read artifacts.
|
|
52
|
+
*/
|
|
53
|
+
readonly contract?: ContractConfig;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Helper function to define a Prisma Next config.
|
|
57
|
+
* Validates and normalizes the config using Arktype, then returns the normalized IR.
|
|
58
|
+
*
|
|
59
|
+
* Normalization:
|
|
60
|
+
* - contract.output defaults to 'src/prisma/contract.json' if missing
|
|
61
|
+
* - contract.types defaults to output with .d.ts extension if missing
|
|
62
|
+
*
|
|
63
|
+
* @param config - Raw config input from user
|
|
64
|
+
* @returns Normalized config IR with defaults applied
|
|
65
|
+
* @throws Error if config structure is invalid
|
|
66
|
+
*/
|
|
67
|
+
declare function defineConfig<TFamilyId extends string = string, TTargetId extends string = string>(config: PrismaNextConfig<TFamilyId, TTargetId>): PrismaNextConfig<TFamilyId, TTargetId>;
|
|
68
|
+
|
|
69
|
+
export { type ContractConfig, type PrismaNextConfig, defineConfig };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/config-types.ts
|
|
2
|
+
import { dirname, join } from "path";
|
|
3
|
+
import { type } from "arktype";
|
|
4
|
+
var ContractConfigSchema = type({
|
|
5
|
+
source: "unknown",
|
|
6
|
+
// Can be value or function - runtime check needed
|
|
7
|
+
"output?": "string",
|
|
8
|
+
"types?": "string"
|
|
9
|
+
});
|
|
10
|
+
var PrismaNextConfigSchema = type({
|
|
11
|
+
family: "unknown",
|
|
12
|
+
// ControlFamilyDescriptor - validated separately
|
|
13
|
+
target: "unknown",
|
|
14
|
+
// ControlTargetDescriptor - validated separately
|
|
15
|
+
adapter: "unknown",
|
|
16
|
+
// ControlAdapterDescriptor - validated separately
|
|
17
|
+
"extensions?": "unknown[]",
|
|
18
|
+
"driver?": "unknown",
|
|
19
|
+
// ControlDriverDescriptor - validated separately (optional)
|
|
20
|
+
"db?": "unknown",
|
|
21
|
+
"contract?": ContractConfigSchema
|
|
22
|
+
});
|
|
23
|
+
function defineConfig(config) {
|
|
24
|
+
const validated = PrismaNextConfigSchema(config);
|
|
25
|
+
if (validated instanceof type.errors) {
|
|
26
|
+
const messages = validated.map((p) => p.message).join("; ");
|
|
27
|
+
throw new Error(`Config validation failed: ${messages}`);
|
|
28
|
+
}
|
|
29
|
+
if (config.contract) {
|
|
30
|
+
const source = config.contract.source;
|
|
31
|
+
if (source !== null && typeof source !== "object" && typeof source !== "function" && typeof source !== "string" && typeof source !== "number" && typeof source !== "boolean") {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"Config.contract.source must be a value (object, string, number, boolean, null) or a function"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
const output = config.contract.output ?? "src/prisma/contract.json";
|
|
37
|
+
const types = config.contract.types ?? (output.endsWith(".json") ? `${output.slice(0, -5)}.d.ts` : join(dirname(output), "contract.d.ts"));
|
|
38
|
+
const normalizedContract = {
|
|
39
|
+
source: config.contract.source,
|
|
40
|
+
output,
|
|
41
|
+
types
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
...config,
|
|
45
|
+
contract: normalizedContract
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
defineConfig
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=config-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/config-types.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport { 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 */\nexport type CliDriver = ControlDriverInstance;\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 * This is the canonical location where other CLI commands can find the contract JSON.\n */\n readonly output?: string;\n /**\n * Path to contract.d.ts artifact. Defaults to output with .d.ts extension.\n * If output ends with .json, replaces .json with .d.ts.\n * Otherwise, appends .d.ts to the directory containing output.\n */\n readonly types?: 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 */\nexport interface PrismaNextConfig<\n TFamilyId extends string = string,\n TTargetId extends string = string,\n> {\n readonly family: ControlFamilyDescriptor<TFamilyId>;\n readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;\n readonly adapter: ControlAdapterDescriptor<TFamilyId, TTargetId>;\n readonly extensions?: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];\n /**\n * Driver descriptor for DB-connected CLI commands.\n * Required for DB-connected commands (e.g., db verify).\n * Optional for commands that don't need database access (e.g., emit).\n */\n readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId>;\n readonly db?: {\n readonly url?: string;\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 'types?': '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 'extensions?': '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 * - contract.types defaults to output with .d.ts extension 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 const types =\n config.contract.types ??\n (output.endsWith('.json')\n ? `${output.slice(0, -5)}.d.ts`\n : join(dirname(output), 'contract.d.ts'));\n\n const normalizedContract: ContractConfig = {\n source: config.contract.source,\n output,\n types,\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":";AAAA,SAAS,SAAS,YAAY;AAC9B,SAAS,YAAY;AAwErB,IAAM,uBAAuB,KAAK;AAAA,EAChC,QAAQ;AAAA;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AACZ,CAAC;AAMD,IAAM,yBAAyB,KAAK;AAAA,EAClC,QAAQ;AAAA;AAAA,EACR,QAAQ;AAAA;AAAA,EACR,SAAS;AAAA;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA;AAAA,EACX,OAAO;AAAA,EACP,aAAa;AACf,CAAC;AAcM,SAAS,aACd,QACwC;AAExC,QAAM,YAAY,uBAAuB,MAAM;AAC/C,MAAI,qBAAqB,KAAK,QAAQ;AACpC,UAAM,WAAW,UAAU,IAAI,CAAC,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI;AAC/E,UAAM,IAAI,MAAM,6BAA6B,QAAQ,EAAE;AAAA,EACzD;AAGA,MAAI,OAAO,UAAU;AAEnB,UAAM,SAAS,OAAO,SAAS;AAC/B,QACE,WAAW,QACX,OAAO,WAAW,YAClB,OAAO,WAAW,cAClB,OAAO,WAAW,YAClB,OAAO,WAAW,YAClB,OAAO,WAAW,WAClB;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,UAAM,SAAS,OAAO,SAAS,UAAU;AACzC,UAAM,QACJ,OAAO,SAAS,UACf,OAAO,SAAS,OAAO,IACpB,GAAG,OAAO,MAAM,GAAG,EAAE,CAAC,UACtB,KAAK,QAAQ,MAAM,GAAG,eAAe;AAE3C,UAAM,qBAAqC;AAAA,MACzC,QAAQ,OAAO,SAAS;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AAGA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU;AAAA,IACZ;AAAA,EACF;AAGA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PrismaNextConfig } from './config-types.js';
|
|
2
|
+
import './types.js';
|
|
3
|
+
import '@prisma-next/contract/ir';
|
|
4
|
+
import '@prisma-next/contract/pack-manifest-types';
|
|
5
|
+
import '@prisma-next/contract/types';
|
|
6
|
+
import './schema-view.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validates that the config has the required structure.
|
|
10
|
+
* This is pure validation logic with no file I/O or CLI awareness.
|
|
11
|
+
*
|
|
12
|
+
* @param config - Config object to validate
|
|
13
|
+
* @throws CliStructuredError if config structure is invalid
|
|
14
|
+
*/
|
|
15
|
+
declare function validateConfig(config: unknown): asserts config is PrismaNextConfig;
|
|
16
|
+
|
|
17
|
+
export { validateConfig };
|