@prisma-next/operations 0.3.0-dev.145 → 0.3.0-dev.146

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 CHANGED
@@ -1,29 +1,28 @@
1
1
  # @prisma-next/operations
2
2
 
3
- Target-neutral operation registry and capability helpers for Prisma Next.
3
+ Target-neutral operation registry for Prisma Next.
4
4
 
5
5
  ## Overview
6
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.
7
+ This package provides a generic, target-neutral operation registry. It's part of the core ring and has no dependencies on target-specific packages.
8
8
 
9
9
  ## Responsibilities
10
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
11
+ - **Operation Registry**: Generic operation registry interface and implementation
12
+ - `OperationRegistry<T>`: Generic interface for registering and iterating operations, parameterized by entry type
13
+ - `createOperationRegistry<T>()`: Factory function to create operation registries
14
+ - `OperationEntry`: Base entry type with `args` and `returns`
15
+ - `OperationDescriptor<T>`: Entry plus a `method` name, used for registration
16
+ - `ParamSpec`: Describes an operation parameter (`codecId`, `nullable`), used for both arguments and return values
19
17
 
20
18
  ## Dependencies
21
19
 
22
- - **Note**: This package has no runtime dependencies. `OperationRegistry` is used by contract types, but operations package itself has no contract dependencies.
20
+
21
+ - **Depends on**: Nothing (leaf package)
23
22
  - **Depended on by**:
24
23
  - `@prisma-next/sql-operations` (extends with SQL-specific lowering specs)
25
- - `@prisma-next/sql-relational-core` (uses for capability checking)
26
- - `@prisma-next/runtime` (uses for operation registry creation)
24
+ - `@prisma-next/sql-relational-core` (imports `ParamSpec` for AST and type definitions)
25
+ - `@prisma-next/runtime-executor` (uses for operation registry creation)
27
26
 
28
27
  ## Architecture
29
28
 
@@ -55,36 +54,37 @@ flowchart TD
55
54
  ### Creating an Operation Registry
56
55
 
57
56
  ```typescript
58
- import { createOperationRegistry, type OperationSignature } from '@prisma-next/operations';
57
+ import { createOperationRegistry, type OperationDescriptor } from '@prisma-next/operations';
59
58
 
60
59
  const registry = createOperationRegistry();
61
60
 
62
- const signature: OperationSignature = {
63
- forTypeId: 'pg/vector@1',
61
+ const descriptor: OperationDescriptor = {
64
62
  method: 'cosineDistance',
65
- args: [{ kind: 'typeId', type: 'pg/vector@1' }],
66
- returns: { kind: 'builtin', type: 'number' },
63
+ args: [{ codecId: 'pg/vector@1', nullable: false }],
64
+ returns: { codecId: 'pg/float8@1', nullable: false },
67
65
  };
68
66
 
69
- registry.register(signature);
70
- const operations = registry.byType('pg/vector@1');
67
+ registry.register(descriptor);
68
+ const entries = registry.entries(); // Record<string, OperationEntry>
71
69
  ```
72
70
 
73
- ### Checking Capabilities
71
+ ### Using a Custom Entry Type
74
72
 
75
73
  ```typescript
76
- import { hasAllCapabilities } from '@prisma-next/operations';
74
+ import { createOperationRegistry, type OperationEntry, type OperationDescriptor } from '@prisma-next/operations';
77
75
 
78
- const contractCapabilities = {
79
- pgvector: {
80
- 'index.ivfflat': true,
81
- },
82
- };
76
+ interface MyEntry extends OperationEntry {
77
+ readonly extra: string;
78
+ }
79
+
80
+ const registry = createOperationRegistry<MyEntry>();
83
81
 
84
- const hasCapability = hasAllCapabilities(
85
- ['pgvector.index.ivfflat'],
86
- contractCapabilities,
87
- );
82
+ registry.register({
83
+ method: 'myMethod',
84
+ args: [],
85
+ returns: { codecId: 'pg/int4@1', nullable: false },
86
+ extra: 'custom data',
87
+ });
88
88
  ```
89
89
 
90
90
  ## Package Location
package/dist/index.d.mts CHANGED
@@ -1,32 +1,20 @@
1
1
  //#region src/index.d.ts
2
- type ArgSpec = {
3
- readonly kind: 'typeId';
4
- readonly type: string;
5
- } | {
6
- readonly kind: 'param';
7
- } | {
8
- readonly kind: 'literal';
9
- };
10
- type ReturnSpec = {
11
- readonly kind: 'typeId';
12
- readonly type: string;
13
- } | {
14
- readonly kind: 'builtin';
15
- readonly type: 'number' | 'boolean' | 'string';
16
- };
17
- interface OperationSignature {
18
- readonly forTypeId: string;
19
- readonly method: string;
20
- readonly args: ReadonlyArray<ArgSpec>;
21
- readonly returns: ReturnSpec;
22
- readonly capabilities?: ReadonlyArray<string>;
2
+ interface ParamSpec {
3
+ readonly codecId: string;
4
+ readonly nullable: boolean;
23
5
  }
24
- interface OperationRegistry<T extends OperationSignature = OperationSignature> {
25
- register(op: T): void;
26
- byType(typeId: string): ReadonlyArray<T>;
6
+ interface OperationEntry {
7
+ readonly args: readonly ParamSpec[];
8
+ readonly returns: ParamSpec;
9
+ }
10
+ type OperationDescriptor<T extends OperationEntry = OperationEntry> = T & {
11
+ readonly method: string;
12
+ };
13
+ interface OperationRegistry<T extends OperationEntry = OperationEntry> {
14
+ register(descriptor: OperationDescriptor<T>): void;
15
+ entries(): Readonly<Record<string, T>>;
27
16
  }
28
- declare function createOperationRegistry<T extends OperationSignature = OperationSignature>(): OperationRegistry<T>;
29
- declare function hasAllCapabilities(capabilities: ReadonlyArray<string>, contractCapabilities?: Record<string, Record<string, boolean>>): boolean;
17
+ declare function createOperationRegistry<T extends OperationEntry = OperationEntry>(): OperationRegistry<T>;
30
18
  //#endregion
31
- export { ArgSpec, OperationRegistry, OperationSignature, ReturnSpec, createOperationRegistry, hasAllCapabilities };
19
+ export { OperationDescriptor, OperationEntry, OperationRegistry, ParamSpec, createOperationRegistry };
32
20
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";KAAY,OAAA;EAAA,SAAA,IAAO,EAAA,QAAA;EAKP,SAAA,IAAU,EAAA,MAAA;AAItB,CAAA,GAAiB;EAGc,SAAA,IAAA,EAAA,OAAA;CAAd,GAAA;EACG,SAAA,IAAA,EAAA,SAAA;CACM;AAAa,KAT3B,UAAA,GAS2B;EAGtB,SAAA,IAAA,EAAA,QAAiB;EAAW,SAAA,IAAA,EAAA,MAAA;CAAqB,GAAA;EACnD,SAAA,IAAA,EAAA,SAAA;EACyB,SAAA,IAAA,EAAA,QAAA,GAAA,SAAA,GAAA,QAAA;CAAd;AAAa,UAVtB,kBAAA,CAUsB;EAyBvB,SAAA,SAAA,EAAA,MAAuB;EAC3B,SAAA,MAAA,EAAA,MAAA;EAAqB,SAAA,IAAA,EAjChB,aAiCgB,CAjCF,OAiCE,CAAA;EACV,SAAA,OAAA,EAjCH,UAiCG;EAAlB,SAAA,YAAA,CAAA,EAhCqB,aAgCrB,CAAA,MAAA,CAAA;;AAIW,UAjCC,iBAiCiB,CAAA,UAjCW,kBAiCX,GAjCgC,kBAiChC,CAAA,CAAA;EAClB,QAAA,CAAA,EAAA,EAjCD,CAiCC,CAAA,EAAA,IAAA;EACwB,MAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAjCd,aAiCc,CAjCA,CAiCA,CAAA;;AAAT,iBARf,uBAQe,CAAA,UAPnB,kBAOmB,GAPE,kBAOF,CAAA,CAAA,CAAA,EAN1B,iBAM0B,CANR,CAMQ,CAAA;iBAFf,kBAAA,eACA,8CACS,eAAe"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";UAAiB,SAAA;EAAA,SAAA,OAAS,EAAA,MAAA;EAKT,SAAA,QAAc,EAAA,OAAA;AAK/B;AAA0C,UALzB,cAAA,CAKyB;EAAiB,SAAA,IAAA,EAAA,SAJjC,SAIiC,EAAA;EAAkB,SAAA,OAAA,EAHzD,SAGyD;;AAI5D,KAJL,mBAIsB,CAAA,UAJQ,cAIR,GAJyB,cAIzB,CAAA,GAJ2C,CAI3C,GAAA;EAAW,SAAA,MAAA,EAAA,MAAA;CAAiB;AACnB,UAD1B,iBAC0B,CAAA,UADE,cACF,GADmB,cACnB,CAAA,CAAA;EAApB,QAAA,CAAA,UAAA,EAAA,mBAAA,CAAoB,CAApB,CAAA,CAAA,EAAA,IAAA;EACc,OAAA,EAAA,EAAxB,QAAwB,CAAf,MAAe,CAAA,MAAA,EAAA,CAAA,CAAA,CAAA;;AAAxB,iBAGG,uBAHH,CAAA,UAID,cAJC,GAIgB,cAJhB,CAAA,CAAA,CAAA,EAKR,iBALQ,CAKU,CALV,CAAA"}
package/dist/index.mjs CHANGED
@@ -1,28 +1,18 @@
1
1
  //#region src/index.ts
2
- var OperationRegistryImpl = class {
3
- operations = /* @__PURE__ */ new Map();
4
- register(op) {
5
- const existing = this.operations.get(op.forTypeId) ?? [];
6
- if (existing.find((existingOp) => existingOp.method === op.method)) throw new Error(`Operation method "${op.method}" already registered for typeId "${op.forTypeId}"`);
7
- existing.push(op);
8
- this.operations.set(op.forTypeId, existing);
9
- }
10
- byType(typeId) {
11
- return this.operations.get(typeId) ?? [];
12
- }
13
- };
14
2
  function createOperationRegistry() {
15
- return new OperationRegistryImpl();
16
- }
17
- function hasAllCapabilities(capabilities, contractCapabilities) {
18
- if (!contractCapabilities) return false;
19
- return capabilities.every((cap) => {
20
- const [namespace, ...rest] = cap.split(".");
21
- const key = rest.join(".");
22
- return (namespace ? contractCapabilities[namespace] : void 0)?.[key] === true;
23
- });
3
+ const operations = Object.create(null);
4
+ return {
5
+ register(descriptor) {
6
+ if (descriptor.method in operations) throw new Error(`Operation "${descriptor.method}" is already registered`);
7
+ const { method: _method, ...entry } = descriptor;
8
+ operations[descriptor.method] = entry;
9
+ },
10
+ entries() {
11
+ return Object.freeze({ ...operations });
12
+ }
13
+ };
24
14
  }
25
15
 
26
16
  //#endregion
27
- export { createOperationRegistry, hasAllCapabilities };
17
+ export { createOperationRegistry };
28
18
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"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<T extends OperationSignature = OperationSignature> {\n register(op: T): void;\n byType(typeId: string): ReadonlyArray<T>;\n}\n\nclass OperationRegistryImpl<T extends OperationSignature = OperationSignature>\n implements OperationRegistry<T>\n{\n private readonly operations = new Map<string, T[]>();\n\n register(op: T): 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<T> {\n return this.operations.get(typeId) ?? [];\n }\n}\n\nexport function createOperationRegistry<\n T extends OperationSignature = OperationSignature,\n>(): OperationRegistry<T> {\n return new OperationRegistryImpl<T>();\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,MAEA;CACE,AAAiB,6BAAa,IAAI,KAAkB;CAEpD,SAAS,IAAa;EACpB,MAAM,WAAW,KAAK,WAAW,IAAI,GAAG,UAAU,IAAI,EAAE;AAExD,MADkB,SAAS,MAAM,eAAe,WAAW,WAAW,GAAG,OAAO,CAE9E,OAAM,IAAI,MACR,qBAAqB,GAAG,OAAO,mCAAmC,GAAG,UAAU,GAChF;AAEH,WAAS,KAAK,GAAG;AACjB,OAAK,WAAW,IAAI,GAAG,WAAW,SAAS;;CAG7C,OAAO,QAAkC;AACvC,SAAO,KAAK,WAAW,IAAI,OAAO,IAAI,EAAE;;;AAI5C,SAAgB,0BAEU;AACxB,QAAO,IAAI,uBAA0B;;AAGvC,SAAgB,mBACd,cACA,sBACS;AACT,KAAI,CAAC,qBACH,QAAO;AAGT,QAAO,aAAa,OAAO,QAAQ;EACjC,MAAM,CAAC,WAAW,GAAG,QAAQ,IAAI,MAAM,IAAI;EAC3C,MAAM,MAAM,KAAK,KAAK,IAAI;AAE1B,UADsB,YAAY,qBAAqB,aAAa,UAC7C,SAAS;GAChC"}
1
+ {"version":3,"file":"index.mjs","names":["operations: Record<string, T>"],"sources":["../src/index.ts"],"sourcesContent":["export interface ParamSpec {\n readonly codecId: string;\n readonly nullable: boolean;\n}\n\nexport interface OperationEntry {\n readonly args: readonly ParamSpec[];\n readonly returns: ParamSpec;\n}\n\nexport type OperationDescriptor<T extends OperationEntry = OperationEntry> = T & {\n readonly method: string;\n};\n\nexport interface OperationRegistry<T extends OperationEntry = OperationEntry> {\n register(descriptor: OperationDescriptor<T>): void;\n entries(): Readonly<Record<string, T>>;\n}\n\nexport function createOperationRegistry<\n T extends OperationEntry = OperationEntry,\n>(): OperationRegistry<T> {\n const operations: Record<string, T> = Object.create(null);\n\n return {\n register(descriptor: OperationDescriptor<T>) {\n if (descriptor.method in operations) {\n throw new Error(`Operation \"${descriptor.method}\" is already registered`);\n }\n const { method: _method, ...entry } = descriptor;\n // OperationDescriptor<T> = T & { method }, so stripping method yields T.\n // TypeScript can't prove Omit<T & { method }, 'method'> = T for generic T.\n operations[descriptor.method] = entry as unknown as T;\n },\n entries() {\n return Object.freeze({ ...operations });\n },\n };\n}\n"],"mappings":";AAmBA,SAAgB,0BAEU;CACxB,MAAMA,aAAgC,OAAO,OAAO,KAAK;AAEzD,QAAO;EACL,SAAS,YAAoC;AAC3C,OAAI,WAAW,UAAU,WACvB,OAAM,IAAI,MAAM,cAAc,WAAW,OAAO,yBAAyB;GAE3E,MAAM,EAAE,QAAQ,SAAS,GAAG,UAAU;AAGtC,cAAW,WAAW,UAAU;;EAElC,UAAU;AACR,UAAO,OAAO,OAAO,EAAE,GAAG,YAAY,CAAC;;EAE1C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/operations",
3
- "version": "0.3.0-dev.145",
3
+ "version": "0.3.0-dev.146",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Target-neutral operation registry and capability helpers for Prisma Next",
@@ -10,8 +10,8 @@
10
10
  "typescript": "5.9.3",
11
11
  "vitest": "4.0.17",
12
12
  "@prisma-next/test-utils": "0.0.1",
13
- "@prisma-next/tsconfig": "0.0.0",
14
- "@prisma-next/tsdown": "0.0.0"
13
+ "@prisma-next/tsdown": "0.0.0",
14
+ "@prisma-next/tsconfig": "0.0.0"
15
15
  },
16
16
  "files": [
17
17
  "dist",
package/src/index.ts CHANGED
@@ -1,65 +1,39 @@
1
- export type ArgSpec =
2
- | { readonly kind: 'typeId'; readonly type: string }
3
- | { readonly kind: 'param' }
4
- | { readonly kind: 'literal' };
5
-
6
- export type ReturnSpec =
7
- | { readonly kind: 'typeId'; readonly type: string }
8
- | { readonly kind: 'builtin'; readonly type: 'number' | 'boolean' | 'string' };
9
-
10
- export interface OperationSignature {
11
- readonly forTypeId: string;
12
- readonly method: string;
13
- readonly args: ReadonlyArray<ArgSpec>;
14
- readonly returns: ReturnSpec;
15
- readonly capabilities?: ReadonlyArray<string>;
1
+ export interface ParamSpec {
2
+ readonly codecId: string;
3
+ readonly nullable: boolean;
16
4
  }
17
5
 
18
- export interface OperationRegistry<T extends OperationSignature = OperationSignature> {
19
- register(op: T): void;
20
- byType(typeId: string): ReadonlyArray<T>;
6
+ export interface OperationEntry {
7
+ readonly args: readonly ParamSpec[];
8
+ readonly returns: ParamSpec;
21
9
  }
22
10
 
23
- class OperationRegistryImpl<T extends OperationSignature = OperationSignature>
24
- implements OperationRegistry<T>
25
- {
26
- private readonly operations = new Map<string, T[]>();
27
-
28
- register(op: T): void {
29
- const existing = this.operations.get(op.forTypeId) ?? [];
30
- const duplicate = existing.find((existingOp) => existingOp.method === op.method);
31
- if (duplicate) {
32
- throw new Error(
33
- `Operation method "${op.method}" already registered for typeId "${op.forTypeId}"`,
34
- );
35
- }
36
- existing.push(op);
37
- this.operations.set(op.forTypeId, existing);
38
- }
11
+ export type OperationDescriptor<T extends OperationEntry = OperationEntry> = T & {
12
+ readonly method: string;
13
+ };
39
14
 
40
- byType(typeId: string): ReadonlyArray<T> {
41
- return this.operations.get(typeId) ?? [];
42
- }
15
+ export interface OperationRegistry<T extends OperationEntry = OperationEntry> {
16
+ register(descriptor: OperationDescriptor<T>): void;
17
+ entries(): Readonly<Record<string, T>>;
43
18
  }
44
19
 
45
20
  export function createOperationRegistry<
46
- T extends OperationSignature = OperationSignature,
21
+ T extends OperationEntry = OperationEntry,
47
22
  >(): OperationRegistry<T> {
48
- return new OperationRegistryImpl<T>();
49
- }
50
-
51
- export function hasAllCapabilities(
52
- capabilities: ReadonlyArray<string>,
53
- contractCapabilities?: Record<string, Record<string, boolean>>,
54
- ): boolean {
55
- if (!contractCapabilities) {
56
- return false;
57
- }
58
-
59
- return capabilities.every((cap) => {
60
- const [namespace, ...rest] = cap.split('.');
61
- const key = rest.join('.');
62
- const namespaceCaps = namespace ? contractCapabilities[namespace] : undefined;
63
- return namespaceCaps?.[key] === true;
64
- });
23
+ const operations: Record<string, T> = Object.create(null);
24
+
25
+ return {
26
+ register(descriptor: OperationDescriptor<T>) {
27
+ if (descriptor.method in operations) {
28
+ throw new Error(`Operation "${descriptor.method}" is already registered`);
29
+ }
30
+ const { method: _method, ...entry } = descriptor;
31
+ // OperationDescriptor<T> = T & { method }, so stripping method yields T.
32
+ // TypeScript can't prove Omit<T & { method }, 'method'> = T for generic T.
33
+ operations[descriptor.method] = entry as unknown as T;
34
+ },
35
+ entries() {
36
+ return Object.freeze({ ...operations });
37
+ },
38
+ };
65
39
  }