@prisma-next/contract-authoring 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +17 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +29 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -5
- package/src/capability-registry.ts +27 -0
- package/src/index.ts +2 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import { AuthoringEntityContext, AuthoringEntityTypeDescriptor, AuthoringEntityTypeNamespace } from "@prisma-next/framework-components/authoring";
|
|
2
2
|
|
|
3
|
+
//#region src/capability-registry.d.ts
|
|
4
|
+
type CapabilityMatrix = Readonly<Record<string, Readonly<Record<string, boolean>>>>;
|
|
5
|
+
/**
|
|
6
|
+
* Deep-merges any number of capability matrices into a single matrix.
|
|
7
|
+
*
|
|
8
|
+
* Merge is purely structural — namespaces and capability flags from later
|
|
9
|
+
* sources overlay earlier ones. Undefined entries are skipped so callers
|
|
10
|
+
* can pass optional sources without pre-filtering.
|
|
11
|
+
*
|
|
12
|
+
* The helper is target-agnostic: it contains no SQL or family-specific
|
|
13
|
+
* knowledge. Higher layers contribute their own capability matrices (for
|
|
14
|
+
* example, a target pack, an extension pack, or the contract author's
|
|
15
|
+
* own `capabilities` block) and call this helper to fold them together.
|
|
16
|
+
*/
|
|
17
|
+
declare function mergeCapabilityMatrices(...sources: ReadonlyArray<CapabilityMatrix | undefined>): Record<string, Record<string, boolean>>;
|
|
18
|
+
//#endregion
|
|
3
19
|
//#region src/composed-helpers-scaffolding.d.ts
|
|
4
20
|
/**
|
|
5
21
|
* Family-agnostic merge / instantiation scaffolding for pack-bag-driven
|
|
@@ -66,5 +82,5 @@ interface ForeignKeyDefaultsState {
|
|
|
66
82
|
readonly index: boolean;
|
|
67
83
|
}
|
|
68
84
|
//#endregion
|
|
69
|
-
export { type AuthoringNamespaceKey, type EntityHelperFactoryOptions, type EntityHelperFunction, type EntityHelpersFromNamespace, type ExtractAuthoringNamespaceFromPack, type ForeignKeyDefaultsState, type IndexDef, type MergeExtensionAuthoringNamespaces, type UnionToIntersection, createEntityHelpersFromNamespace };
|
|
85
|
+
export { type AuthoringNamespaceKey, type CapabilityMatrix, type EntityHelperFactoryOptions, type EntityHelperFunction, type EntityHelpersFromNamespace, type ExtractAuthoringNamespaceFromPack, type ForeignKeyDefaultsState, type IndexDef, type MergeExtensionAuthoringNamespaces, type UnionToIntersection, createEntityHelpersFromNamespace, mergeCapabilityMatrices };
|
|
70
86
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/composed-helpers-scaffolding.ts","../src/descriptors.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/capability-registry.ts","../src/composed-helpers-scaffolding.ts","../src/descriptors.ts"],"mappings":";;;KAAY,gBAAA,GAAmB,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA;;;AAAhE;;;;;;;;;;iBAcgB,uBAAA,CAAA,GACX,OAAA,EAAS,aAAA,CAAc,gBAAA,gBACzB,MAAA,SAAe,MAAA;;;;;AAhBlB;;;;;;;;;;;;;;AAAsE;KCyB1D,mBAAA,OAA0B,CAAA,oBAAqB,KAAA,EAAO,CAAC,6BACjE,KAAA,sBAEE,CAAA;AAAA,KAGQ,qBAAA;AAAA,KAEA,iCAAA,mBAEE,qBAAA,oBAEV,IAAA;EAAA,SACO,SAAA,oBAA6B,GAAA;AAAA,IAEpC,SAAA,SAAkB,MAAA,oBAChB,SAAA,GACA,cAAA,GACF,cAAA;AAAA,KAEQ,iCAAA,6BAEE,qBAAA,mBACK,MAAA,kBAEjB,cAAA,SAAuB,MAAA,0BACb,cAAA,iBACJ,cAAA,GACA,mBAAA,eAEgB,cAAA,GAAiB,iCAAA,CAC3B,cAAA,CAAe,CAAA,GACf,GAAA,EACA,cAAA,UAEI,cAAA,KAEZ,cAAA;;;;;;KAOD,4BAAA,oBAAgD,6BAAA,IACnD,UAAA;EAAA,SACW,OAAA,GAAU,KAAA,eAAoB,GAAA,EAAK,sBAAA;AAAA;EAExC,KAAA,EAAO,KAAA;EAAO,MAAA,EAAQ,MAAA;AAAA;EACtB,KAAA;EAAgB,MAAA;AAAA;AAAA,KAEZ,oBAAA,oBAAwC,6BAAA,IAClD,4BAAA,CAA6B,UAAA;EAAsB,KAAA;EAAoB,MAAA;AAAA,KAClE,KAAA,EAAO,KAAA,KAAU,MAAA;AAAA,KAGZ,0BAAA,qCACW,SAAA,GAAY,SAAA,CAAU,CAAA,UAAW,6BAAA,GAClD,oBAAA,CAAqB,SAAA,CAAU,CAAA,KAC/B,SAAA,CAAU,CAAA,UAAW,MAAA,oBACnB,0BAAA,CAA2B,SAAA,CAAU,CAAA;AAAA,UAI5B,0BAAA;EAAA,SACN,GAAA,EAAK,sBAAsB;AAAA;;;AA3DL;AAEjC;;;iBAkEgB,gCAAA,CACd,SAAA,EAAW,4BAAA,EACX,OAAA,EAAS,0BAAA,EACT,IAAA,uBACC,MAAA;;;UCvGc,QAAA;EAAA,SACN,OAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,OAAA,GAAU,MAAM;AAAA;AAAA,UAGV,uBAAA;EAAA,SACN,UAAA;EAAA,SACA,KAAK;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
1
|
import { instantiateAuthoringEntityType } from "@prisma-next/framework-components/authoring";
|
|
2
|
+
//#region src/capability-registry.ts
|
|
3
|
+
/**
|
|
4
|
+
* Deep-merges any number of capability matrices into a single matrix.
|
|
5
|
+
*
|
|
6
|
+
* Merge is purely structural — namespaces and capability flags from later
|
|
7
|
+
* sources overlay earlier ones. Undefined entries are skipped so callers
|
|
8
|
+
* can pass optional sources without pre-filtering.
|
|
9
|
+
*
|
|
10
|
+
* The helper is target-agnostic: it contains no SQL or family-specific
|
|
11
|
+
* knowledge. Higher layers contribute their own capability matrices (for
|
|
12
|
+
* example, a target pack, an extension pack, or the contract author's
|
|
13
|
+
* own `capabilities` block) and call this helper to fold them together.
|
|
14
|
+
*/
|
|
15
|
+
function mergeCapabilityMatrices(...sources) {
|
|
16
|
+
const result = {};
|
|
17
|
+
for (const source of sources) {
|
|
18
|
+
if (source === void 0) continue;
|
|
19
|
+
for (const [namespace, capabilities] of Object.entries(source)) {
|
|
20
|
+
const existing = result[namespace];
|
|
21
|
+
result[namespace] = existing ? {
|
|
22
|
+
...existing,
|
|
23
|
+
...capabilities
|
|
24
|
+
} : { ...capabilities };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
2
30
|
//#region src/composed-helpers-scaffolding.ts
|
|
3
31
|
/**
|
|
4
32
|
* Walks an entity-type namespace (after cross-pack merge) and produces the
|
|
@@ -27,6 +55,6 @@ function createEntityHelper(helperPath, descriptor, options) {
|
|
|
27
55
|
return (...args) => instantiateAuthoringEntityType(helperPath, descriptor, args, options.ctx);
|
|
28
56
|
}
|
|
29
57
|
//#endregion
|
|
30
|
-
export { createEntityHelpersFromNamespace };
|
|
58
|
+
export { createEntityHelpersFromNamespace, mergeCapabilityMatrices };
|
|
31
59
|
|
|
32
60
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/composed-helpers-scaffolding.ts"],"sourcesContent":["import type {\n AuthoringEntityContext,\n AuthoringEntityTypeDescriptor,\n AuthoringEntityTypeNamespace,\n} from '@prisma-next/framework-components/authoring';\nimport { instantiateAuthoringEntityType } from '@prisma-next/framework-components/authoring';\n\n/**\n * Family-agnostic merge / instantiation scaffolding for pack-bag-driven\n * authoring contributions. The per-namespace shape (`field`, `type`,\n * `entityTypes`) is parameterized by the discriminator key so each\n * namespace can reuse the same extractor + cross-pack merger without\n * re-deriving the template per family. Call sites flatten merged\n * `entityTypes` onto the user-facing top-level helpers surface\n * alongside the built-in `model` / `rel` (e.g. `helpers.enum(...)`).\n * The contribution data structure stays as\n * `authoring.entityTypes.<name>` — pack authors keep contributing\n * through the namespace; the composed-helpers template performs the\n * rename in the type system.\n *\n * SQL-specific composition (the `field` / `model` / `rel` / `type` core\n * helpers, the SQL index-types merge) lives in the SQL contract-ts\n * package and imports from here.\n */\n\nexport type UnionToIntersection<U> = (U extends unknown ? (value: U) => void : never) extends (\n value: infer I,\n) => void\n ? I\n : never;\n\nexport type AuthoringNamespaceKey = 'field' | 'type' | 'entityTypes';\n\nexport type ExtractAuthoringNamespaceFromPack<\n Pack,\n Key extends AuthoringNamespaceKey,\n EmptyNamespace,\n> = Pack extends {\n readonly authoring?: { readonly [P in Key]?: infer Namespace };\n}\n ? Namespace extends Record<string, unknown>\n ? Namespace\n : EmptyNamespace\n : EmptyNamespace;\n\nexport type MergeExtensionAuthoringNamespaces<\n ExtensionPacks,\n Key extends AuthoringNamespaceKey,\n EmptyNamespace = Record<never, never>,\n> =\n ExtensionPacks extends Record<string, unknown>\n ? keyof ExtensionPacks extends never\n ? EmptyNamespace\n : UnionToIntersection<\n {\n [K in keyof ExtensionPacks]: ExtractAuthoringNamespaceFromPack<\n ExtensionPacks[K],\n Key,\n EmptyNamespace\n >;\n }[keyof ExtensionPacks]\n >\n : EmptyNamespace;\n\n/**\n * Entity-helper shape derivation. Mirrors `FieldHelpersFromNamespace` /\n * `TypeHelpersFromNamespace` in the SQL package: leaf descriptors become\n * callable helpers; nested namespaces recurse.\n */\ntype ExtractFactoryInputAndOutput<Descriptor extends AuthoringEntityTypeDescriptor> =\n Descriptor['output'] extends {\n readonly factory: (input: infer Input, ctx: AuthoringEntityContext) => infer Output;\n }\n ? { input: Input; output: Output }\n : { input: unknown; output: unknown };\n\nexport type EntityHelperFunction<Descriptor extends AuthoringEntityTypeDescriptor> =\n ExtractFactoryInputAndOutput<Descriptor> extends { input: infer Input; output: infer Output }\n ? (input: Input) => Output\n : never;\n\nexport type EntityHelpersFromNamespace<Namespace> = {\n readonly [K in keyof Namespace]: Namespace[K] extends AuthoringEntityTypeDescriptor\n ? EntityHelperFunction<Namespace[K]>\n : Namespace[K] extends Record<string, unknown>\n ? EntityHelpersFromNamespace<Namespace[K]>\n : never;\n};\n\nexport interface EntityHelperFactoryOptions {\n readonly ctx: AuthoringEntityContext;\n}\n\n/**\n * Walks an entity-type namespace (after cross-pack merge) and produces the\n * runtime callable surface mirroring its tree shape. Each leaf\n * descriptor becomes a function `(input) => factory(input, ctx)`;\n * nested namespace objects recurse.\n */\nexport function createEntityHelpersFromNamespace(\n namespace: AuthoringEntityTypeNamespace,\n options: EntityHelperFactoryOptions,\n path: readonly string[] = [],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isLeafEntityDescriptor(value)) {\n result[key] = createEntityHelper(currentPath.join('.'), value, options);\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n result[key] = createEntityHelpersFromNamespace(\n value as AuthoringEntityTypeNamespace,\n options,\n currentPath,\n );\n }\n }\n return result;\n}\n\nfunction isLeafEntityDescriptor(value: unknown): value is AuthoringEntityTypeDescriptor {\n if (\n typeof value !== 'object' ||\n value === null ||\n (value as { kind?: unknown }).kind !== 'entity'\n ) {\n return false;\n }\n const discriminator = (value as { discriminator?: unknown }).discriminator;\n return typeof discriminator === 'string' && discriminator.length > 0;\n}\n\nfunction createEntityHelper(\n helperPath: string,\n descriptor: AuthoringEntityTypeDescriptor,\n options: EntityHelperFactoryOptions,\n): (...args: readonly unknown[]) => unknown {\n return (...args: readonly unknown[]) =>\n instantiateAuthoringEntityType(helperPath, descriptor, args, options.ctx);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/capability-registry.ts","../src/composed-helpers-scaffolding.ts"],"sourcesContent":["export type CapabilityMatrix = Readonly<Record<string, Readonly<Record<string, boolean>>>>;\n\n/**\n * Deep-merges any number of capability matrices into a single matrix.\n *\n * Merge is purely structural — namespaces and capability flags from later\n * sources overlay earlier ones. Undefined entries are skipped so callers\n * can pass optional sources without pre-filtering.\n *\n * The helper is target-agnostic: it contains no SQL or family-specific\n * knowledge. Higher layers contribute their own capability matrices (for\n * example, a target pack, an extension pack, or the contract author's\n * own `capabilities` block) and call this helper to fold them together.\n */\nexport function mergeCapabilityMatrices(\n ...sources: ReadonlyArray<CapabilityMatrix | undefined>\n): Record<string, Record<string, boolean>> {\n const result: Record<string, Record<string, boolean>> = {};\n for (const source of sources) {\n if (source === undefined) continue;\n for (const [namespace, capabilities] of Object.entries(source)) {\n const existing = result[namespace];\n result[namespace] = existing ? { ...existing, ...capabilities } : { ...capabilities };\n }\n }\n return result;\n}\n","import type {\n AuthoringEntityContext,\n AuthoringEntityTypeDescriptor,\n AuthoringEntityTypeNamespace,\n} from '@prisma-next/framework-components/authoring';\nimport { instantiateAuthoringEntityType } from '@prisma-next/framework-components/authoring';\n\n/**\n * Family-agnostic merge / instantiation scaffolding for pack-bag-driven\n * authoring contributions. The per-namespace shape (`field`, `type`,\n * `entityTypes`) is parameterized by the discriminator key so each\n * namespace can reuse the same extractor + cross-pack merger without\n * re-deriving the template per family. Call sites flatten merged\n * `entityTypes` onto the user-facing top-level helpers surface\n * alongside the built-in `model` / `rel` (e.g. `helpers.enum(...)`).\n * The contribution data structure stays as\n * `authoring.entityTypes.<name>` — pack authors keep contributing\n * through the namespace; the composed-helpers template performs the\n * rename in the type system.\n *\n * SQL-specific composition (the `field` / `model` / `rel` / `type` core\n * helpers, the SQL index-types merge) lives in the SQL contract-ts\n * package and imports from here.\n */\n\nexport type UnionToIntersection<U> = (U extends unknown ? (value: U) => void : never) extends (\n value: infer I,\n) => void\n ? I\n : never;\n\nexport type AuthoringNamespaceKey = 'field' | 'type' | 'entityTypes';\n\nexport type ExtractAuthoringNamespaceFromPack<\n Pack,\n Key extends AuthoringNamespaceKey,\n EmptyNamespace,\n> = Pack extends {\n readonly authoring?: { readonly [P in Key]?: infer Namespace };\n}\n ? Namespace extends Record<string, unknown>\n ? Namespace\n : EmptyNamespace\n : EmptyNamespace;\n\nexport type MergeExtensionAuthoringNamespaces<\n ExtensionPacks,\n Key extends AuthoringNamespaceKey,\n EmptyNamespace = Record<never, never>,\n> =\n ExtensionPacks extends Record<string, unknown>\n ? keyof ExtensionPacks extends never\n ? EmptyNamespace\n : UnionToIntersection<\n {\n [K in keyof ExtensionPacks]: ExtractAuthoringNamespaceFromPack<\n ExtensionPacks[K],\n Key,\n EmptyNamespace\n >;\n }[keyof ExtensionPacks]\n >\n : EmptyNamespace;\n\n/**\n * Entity-helper shape derivation. Mirrors `FieldHelpersFromNamespace` /\n * `TypeHelpersFromNamespace` in the SQL package: leaf descriptors become\n * callable helpers; nested namespaces recurse.\n */\ntype ExtractFactoryInputAndOutput<Descriptor extends AuthoringEntityTypeDescriptor> =\n Descriptor['output'] extends {\n readonly factory: (input: infer Input, ctx: AuthoringEntityContext) => infer Output;\n }\n ? { input: Input; output: Output }\n : { input: unknown; output: unknown };\n\nexport type EntityHelperFunction<Descriptor extends AuthoringEntityTypeDescriptor> =\n ExtractFactoryInputAndOutput<Descriptor> extends { input: infer Input; output: infer Output }\n ? (input: Input) => Output\n : never;\n\nexport type EntityHelpersFromNamespace<Namespace> = {\n readonly [K in keyof Namespace]: Namespace[K] extends AuthoringEntityTypeDescriptor\n ? EntityHelperFunction<Namespace[K]>\n : Namespace[K] extends Record<string, unknown>\n ? EntityHelpersFromNamespace<Namespace[K]>\n : never;\n};\n\nexport interface EntityHelperFactoryOptions {\n readonly ctx: AuthoringEntityContext;\n}\n\n/**\n * Walks an entity-type namespace (after cross-pack merge) and produces the\n * runtime callable surface mirroring its tree shape. Each leaf\n * descriptor becomes a function `(input) => factory(input, ctx)`;\n * nested namespace objects recurse.\n */\nexport function createEntityHelpersFromNamespace(\n namespace: AuthoringEntityTypeNamespace,\n options: EntityHelperFactoryOptions,\n path: readonly string[] = [],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isLeafEntityDescriptor(value)) {\n result[key] = createEntityHelper(currentPath.join('.'), value, options);\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n result[key] = createEntityHelpersFromNamespace(\n value as AuthoringEntityTypeNamespace,\n options,\n currentPath,\n );\n }\n }\n return result;\n}\n\nfunction isLeafEntityDescriptor(value: unknown): value is AuthoringEntityTypeDescriptor {\n if (\n typeof value !== 'object' ||\n value === null ||\n (value as { kind?: unknown }).kind !== 'entity'\n ) {\n return false;\n }\n const discriminator = (value as { discriminator?: unknown }).discriminator;\n return typeof discriminator === 'string' && discriminator.length > 0;\n}\n\nfunction createEntityHelper(\n helperPath: string,\n descriptor: AuthoringEntityTypeDescriptor,\n options: EntityHelperFactoryOptions,\n): (...args: readonly unknown[]) => unknown {\n return (...args: readonly unknown[]) =>\n instantiateAuthoringEntityType(helperPath, descriptor, args, options.ctx);\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,wBACd,GAAG,SACsC;CACzC,MAAM,SAAkD,CAAC;CACzD,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,WAAW,KAAA,GAAW;EAC1B,KAAK,MAAM,CAAC,WAAW,iBAAiB,OAAO,QAAQ,MAAM,GAAG;GAC9D,MAAM,WAAW,OAAO;GACxB,OAAO,aAAa,WAAW;IAAE,GAAG;IAAU,GAAG;GAAa,IAAI,EAAE,GAAG,aAAa;EACtF;CACF;CACA,OAAO;AACT;;;;;;;;;ACyEA,SAAgB,iCACd,WACA,SACA,OAA0B,CAAC,GACF;CACzB,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,GAAG;EACpD,MAAM,cAAc,CAAC,GAAG,MAAM,GAAG;EACjC,IAAI,uBAAuB,KAAK,GAAG;GACjC,OAAO,OAAO,mBAAmB,YAAY,KAAK,GAAG,GAAG,OAAO,OAAO;GACtE;EACF;EACA,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,GACrE,OAAO,OAAO,iCACZ,OACA,SACA,WACF;CAEJ;CACA,OAAO;AACT;AAEA,SAAS,uBAAuB,OAAwD;CACtF,IACE,OAAO,UAAU,YACjB,UAAU,QACT,MAA6B,SAAS,UAEvC,OAAO;CAET,MAAM,gBAAiB,MAAsC;CAC7D,OAAO,OAAO,kBAAkB,YAAY,cAAc,SAAS;AACrE;AAEA,SAAS,mBACP,YACA,YACA,SAC0C;CAC1C,QAAQ,GAAG,SACT,+BAA+B,YAAY,YAAY,MAAM,QAAQ,GAAG;AAC5E"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/contract-authoring",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "Target-agnostic authored storage descriptor types for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/framework-components": "0.
|
|
9
|
+
"@prisma-next/framework-components": "0.12.0"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@prisma-next/tsconfig": "0.
|
|
13
|
-
"@prisma-next/tsdown": "0.
|
|
12
|
+
"@prisma-next/tsconfig": "0.12.0",
|
|
13
|
+
"@prisma-next/tsdown": "0.12.0",
|
|
14
14
|
"tsdown": "0.22.0",
|
|
15
15
|
"typescript": "5.9.3",
|
|
16
16
|
"vitest": "4.1.6"
|
|
17
17
|
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": ">=5.9"
|
|
20
|
+
},
|
|
21
|
+
"peerDependenciesMeta": {
|
|
22
|
+
"typescript": {
|
|
23
|
+
"optional": true
|
|
24
|
+
}
|
|
25
|
+
},
|
|
18
26
|
"files": [
|
|
19
27
|
"dist",
|
|
20
28
|
"src"
|
|
21
29
|
],
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
22
31
|
"exports": {
|
|
23
32
|
".": "./dist/index.mjs",
|
|
24
33
|
"./package.json": "./package.json"
|
|
25
34
|
},
|
|
26
|
-
"
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=24"
|
|
37
|
+
},
|
|
27
38
|
"repository": {
|
|
28
39
|
"type": "git",
|
|
29
40
|
"url": "https://github.com/prisma/prisma-next.git",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type CapabilityMatrix = Readonly<Record<string, Readonly<Record<string, boolean>>>>;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deep-merges any number of capability matrices into a single matrix.
|
|
5
|
+
*
|
|
6
|
+
* Merge is purely structural — namespaces and capability flags from later
|
|
7
|
+
* sources overlay earlier ones. Undefined entries are skipped so callers
|
|
8
|
+
* can pass optional sources without pre-filtering.
|
|
9
|
+
*
|
|
10
|
+
* The helper is target-agnostic: it contains no SQL or family-specific
|
|
11
|
+
* knowledge. Higher layers contribute their own capability matrices (for
|
|
12
|
+
* example, a target pack, an extension pack, or the contract author's
|
|
13
|
+
* own `capabilities` block) and call this helper to fold them together.
|
|
14
|
+
*/
|
|
15
|
+
export function mergeCapabilityMatrices(
|
|
16
|
+
...sources: ReadonlyArray<CapabilityMatrix | undefined>
|
|
17
|
+
): Record<string, Record<string, boolean>> {
|
|
18
|
+
const result: Record<string, Record<string, boolean>> = {};
|
|
19
|
+
for (const source of sources) {
|
|
20
|
+
if (source === undefined) continue;
|
|
21
|
+
for (const [namespace, capabilities] of Object.entries(source)) {
|
|
22
|
+
const existing = result[namespace];
|
|
23
|
+
result[namespace] = existing ? { ...existing, ...capabilities } : { ...capabilities };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|