@prisma-next/operations 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 +102 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# @prisma-next/operations
|
|
2
|
+
|
|
3
|
+
Target-neutral operation registry and capability helpers for Prisma Next.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides target-neutral operation registry types and capability checking utilities. It's part of the core ring and has no dependencies on target-specific packages.
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- **Operation Registry**: Core operation registry interface and implementation
|
|
12
|
+
- `OperationRegistry`: Interface for registering and querying operations
|
|
13
|
+
- `createOperationRegistry()`: Factory function to create operation registries
|
|
14
|
+
- `OperationSignature`: Core operation signature type (target-neutral)
|
|
15
|
+
- `ArgSpec`, `ReturnSpec`: Type definitions for operation arguments and return values
|
|
16
|
+
|
|
17
|
+
- **Capability Checking**: Target-neutral capability validation
|
|
18
|
+
- `hasAllCapabilities()`: Checks if all required capabilities are present in a contract
|
|
19
|
+
|
|
20
|
+
## Dependencies
|
|
21
|
+
|
|
22
|
+
- **Depends on**: `@prisma-next/plan` (for plan error types)
|
|
23
|
+
- **Note**: This package does not depend on `@prisma-next/contract` despite being in the same layer. `OperationRegistry` is used by contract types, but operations package itself has no contract dependencies.
|
|
24
|
+
- **Depended on by**:
|
|
25
|
+
- `@prisma-next/sql-operations` (extends with SQL-specific lowering specs)
|
|
26
|
+
- `@prisma-next/sql-relational-core` (uses for capability checking)
|
|
27
|
+
- `@prisma-next/runtime` (uses for operation registry creation)
|
|
28
|
+
|
|
29
|
+
## Architecture
|
|
30
|
+
|
|
31
|
+
```mermaid
|
|
32
|
+
flowchart TD
|
|
33
|
+
subgraph "Core Ring"
|
|
34
|
+
OPS[@prisma-next/operations]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
subgraph "Targets Ring"
|
|
38
|
+
SQL_OPS[@prisma-next/sql-operations]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
subgraph "Lanes Ring"
|
|
42
|
+
REL_CORE[@prisma-next/sql-relational-core]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
subgraph "Runtime Ring"
|
|
46
|
+
RT[@prisma-next/runtime]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
OPS --> SQL_OPS
|
|
50
|
+
OPS --> REL_CORE
|
|
51
|
+
OPS --> RT
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
### Creating an Operation Registry
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { createOperationRegistry, type OperationSignature } from '@prisma-next/operations';
|
|
60
|
+
|
|
61
|
+
const registry = createOperationRegistry();
|
|
62
|
+
|
|
63
|
+
const signature: OperationSignature = {
|
|
64
|
+
forTypeId: 'pg/vector@1',
|
|
65
|
+
method: 'cosineDistance',
|
|
66
|
+
args: [{ kind: 'typeId', type: 'pg/vector@1' }],
|
|
67
|
+
returns: { kind: 'builtin', type: 'number' },
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
registry.register(signature);
|
|
71
|
+
const operations = registry.byType('pg/vector@1');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Checking Capabilities
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { hasAllCapabilities } from '@prisma-next/operations';
|
|
78
|
+
|
|
79
|
+
const contractCapabilities = {
|
|
80
|
+
pgvector: {
|
|
81
|
+
'index.ivfflat': true,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const hasCapability = hasAllCapabilities(
|
|
86
|
+
['pgvector.index.ivfflat'],
|
|
87
|
+
contractCapabilities,
|
|
88
|
+
);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Package Location
|
|
92
|
+
|
|
93
|
+
This package is part of the **framework domain**, **core layer**, **shared plane**:
|
|
94
|
+
- **Domain**: framework (target-agnostic)
|
|
95
|
+
- **Layer**: core
|
|
96
|
+
- **Plane**: shared
|
|
97
|
+
- **Path**: `packages/framework/core-operations`
|
|
98
|
+
|
|
99
|
+
## Related Documentation
|
|
100
|
+
|
|
101
|
+
- [Package Layering](../../../../docs/architecture docs/Package-Layering.md)
|
|
102
|
+
- [ADR 140 - Package Layering & Target-Family Namespacing](../../../../docs/architecture docs/adrs/ADR 140 - Package Layering & Target-Family Namespacing.md)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type ArgSpec = {
|
|
2
|
+
readonly kind: 'typeId';
|
|
3
|
+
readonly type: string;
|
|
4
|
+
} | {
|
|
5
|
+
readonly kind: 'param';
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'literal';
|
|
8
|
+
};
|
|
9
|
+
type ReturnSpec = {
|
|
10
|
+
readonly kind: 'typeId';
|
|
11
|
+
readonly type: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: 'builtin';
|
|
14
|
+
readonly type: 'number' | 'boolean' | 'string';
|
|
15
|
+
};
|
|
16
|
+
interface OperationSignature {
|
|
17
|
+
readonly forTypeId: string;
|
|
18
|
+
readonly method: string;
|
|
19
|
+
readonly args: ReadonlyArray<ArgSpec>;
|
|
20
|
+
readonly returns: ReturnSpec;
|
|
21
|
+
readonly capabilities?: ReadonlyArray<string>;
|
|
22
|
+
}
|
|
23
|
+
interface OperationRegistry {
|
|
24
|
+
register(op: OperationSignature): void;
|
|
25
|
+
byType(typeId: string): ReadonlyArray<OperationSignature>;
|
|
26
|
+
}
|
|
27
|
+
declare function createOperationRegistry(): OperationRegistry;
|
|
28
|
+
declare function hasAllCapabilities(capabilities: ReadonlyArray<string>, contractCapabilities?: Record<string, Record<string, boolean>>): boolean;
|
|
29
|
+
|
|
30
|
+
export { type ArgSpec, type OperationRegistry, type OperationSignature, type ReturnSpec, createOperationRegistry, hasAllCapabilities };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var OperationRegistryImpl = class {
|
|
3
|
+
operations = /* @__PURE__ */ new Map();
|
|
4
|
+
register(op) {
|
|
5
|
+
const existing = this.operations.get(op.forTypeId) ?? [];
|
|
6
|
+
const duplicate = existing.find((existingOp) => existingOp.method === op.method);
|
|
7
|
+
if (duplicate) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`Operation method "${op.method}" already registered for typeId "${op.forTypeId}"`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
existing.push(op);
|
|
13
|
+
this.operations.set(op.forTypeId, existing);
|
|
14
|
+
}
|
|
15
|
+
byType(typeId) {
|
|
16
|
+
return this.operations.get(typeId) ?? [];
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
function createOperationRegistry() {
|
|
20
|
+
return new OperationRegistryImpl();
|
|
21
|
+
}
|
|
22
|
+
function hasAllCapabilities(capabilities, contractCapabilities) {
|
|
23
|
+
if (!contractCapabilities) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return capabilities.every((cap) => {
|
|
27
|
+
const [namespace, ...rest] = cap.split(".");
|
|
28
|
+
const key = rest.join(".");
|
|
29
|
+
const namespaceCaps = namespace ? contractCapabilities[namespace] : void 0;
|
|
30
|
+
return namespaceCaps?.[key] === true;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
createOperationRegistry,
|
|
35
|
+
hasAllCapabilities
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type ArgSpec =\n | { readonly kind: 'typeId'; readonly type: string }\n | { readonly kind: 'param' }\n | { readonly kind: 'literal' };\n\nexport type ReturnSpec =\n | { readonly kind: 'typeId'; readonly type: string }\n | { readonly kind: 'builtin'; readonly type: 'number' | 'boolean' | 'string' };\n\nexport interface OperationSignature {\n readonly forTypeId: string;\n readonly method: string;\n readonly args: ReadonlyArray<ArgSpec>;\n readonly returns: ReturnSpec;\n readonly capabilities?: ReadonlyArray<string>;\n}\n\nexport interface OperationRegistry {\n register(op: OperationSignature): void;\n byType(typeId: string): ReadonlyArray<OperationSignature>;\n}\n\nclass OperationRegistryImpl implements OperationRegistry {\n private readonly operations = new Map<string, OperationSignature[]>();\n\n register(op: OperationSignature): void {\n const existing = this.operations.get(op.forTypeId) ?? [];\n const duplicate = existing.find((existingOp) => existingOp.method === op.method);\n if (duplicate) {\n throw new Error(\n `Operation method \"${op.method}\" already registered for typeId \"${op.forTypeId}\"`,\n );\n }\n existing.push(op);\n this.operations.set(op.forTypeId, existing);\n }\n\n byType(typeId: string): ReadonlyArray<OperationSignature> {\n return this.operations.get(typeId) ?? [];\n }\n}\n\nexport function createOperationRegistry(): OperationRegistry {\n return new OperationRegistryImpl();\n}\n\nexport function hasAllCapabilities(\n capabilities: ReadonlyArray<string>,\n contractCapabilities?: Record<string, Record<string, boolean>>,\n): boolean {\n if (!contractCapabilities) {\n return false;\n }\n\n return capabilities.every((cap) => {\n const [namespace, ...rest] = cap.split('.');\n const key = rest.join('.');\n const namespaceCaps = namespace ? contractCapabilities[namespace] : undefined;\n return namespaceCaps?.[key] === true;\n });\n}\n"],"mappings":";AAsBA,IAAM,wBAAN,MAAyD;AAAA,EACtC,aAAa,oBAAI,IAAkC;AAAA,EAEpE,SAAS,IAA8B;AACrC,UAAM,WAAW,KAAK,WAAW,IAAI,GAAG,SAAS,KAAK,CAAC;AACvD,UAAM,YAAY,SAAS,KAAK,CAAC,eAAe,WAAW,WAAW,GAAG,MAAM;AAC/E,QAAI,WAAW;AACb,YAAM,IAAI;AAAA,QACR,qBAAqB,GAAG,MAAM,oCAAoC,GAAG,SAAS;AAAA,MAChF;AAAA,IACF;AACA,aAAS,KAAK,EAAE;AAChB,SAAK,WAAW,IAAI,GAAG,WAAW,QAAQ;AAAA,EAC5C;AAAA,EAEA,OAAO,QAAmD;AACxD,WAAO,KAAK,WAAW,IAAI,MAAM,KAAK,CAAC;AAAA,EACzC;AACF;AAEO,SAAS,0BAA6C;AAC3D,SAAO,IAAI,sBAAsB;AACnC;AAEO,SAAS,mBACd,cACA,sBACS;AACT,MAAI,CAAC,sBAAsB;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,aAAa,MAAM,CAAC,QAAQ;AACjC,UAAM,CAAC,WAAW,GAAG,IAAI,IAAI,IAAI,MAAM,GAAG;AAC1C,UAAM,MAAM,KAAK,KAAK,GAAG;AACzB,UAAM,gBAAgB,YAAY,qBAAqB,SAAS,IAAI;AACpE,WAAO,gBAAgB,GAAG,MAAM;AAAA,EAClC,CAAC;AACH;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prisma-next/operations",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "Target-neutral operation registry and capability helpers for Prisma Next",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@prisma-next/plan": "0.0.1"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"tsup": "^8.3.0",
|
|
12
|
+
"typescript": "^5.9.3",
|
|
13
|
+
"vitest": "^2.1.1",
|
|
14
|
+
"@prisma-next/test-utils": "0.0.1"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup --config tsup.config.ts",
|
|
27
|
+
"test": "vitest run --passWithNoTests",
|
|
28
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
29
|
+
"typecheck": "tsc --project tsconfig.json --noEmit",
|
|
30
|
+
"lint": "biome check . --config-path ../../../biome.json --error-on-warnings",
|
|
31
|
+
"clean": "node ../../../scripts/clean.mjs"
|
|
32
|
+
}
|
|
33
|
+
}
|