@ankhorage/contracts 24.2.1 → 25.0.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/CHANGELOG.md +6 -0
- package/README.md +1 -3
- package/dist/capability.d.ts +25 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +2 -0
- package/dist/capability.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/structure/generated.d.ts +2 -2
- package/dist/structure/generated.js +2 -2
- package/dist/structure/generated.js.map +1 -1
- package/package.json +4 -4
- package/src/capability.test.ts +118 -0
- package/src/capability.ts +37 -0
- package/src/cli/index.ts +1 -1
- package/src/cli.test.ts +1 -1
- package/src/index.ts +0 -1
- package/src/structure/generated.ts +2 -2
- package/dist/capabilities.d.ts +0 -39
- package/dist/capabilities.d.ts.map +0 -1
- package/dist/capabilities.js +0 -116
- package/dist/capabilities.js.map +0 -1
- package/src/capabilities.test.ts +0 -259
- package/src/capabilities.ts +0 -186
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ankhorage/contracts
|
|
2
2
|
|
|
3
|
+
## 25.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 7d6e71f: Replace the runtime-bearing `./capabilities` export with the declaration-only `./capability` surface. Capability validation, normalization, comparison, and runtime vocabularies are no longer exported from Contracts.
|
|
8
|
+
|
|
3
9
|
## 24.2.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/contracts
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Serializable app, capability, binding, theme, auth, and secret-store contracts for Ankhorage.
|
|
9
9
|
|
|
@@ -15,7 +15,6 @@ Serializable app, capability, binding, theme, auth, and secret-store contracts f
|
|
|
15
15
|
- [Architecture overview](././paradox/diagrams/architecture-overview.mmd)
|
|
16
16
|
- [Module relationships](././paradox/diagrams/module-relationships.mmd)
|
|
17
17
|
- [Export graph](././paradox/diagrams/export-graph.mmd)
|
|
18
|
-
- [isCapabilityId sequence](././paradox/diagrams/sequences/is-capability-id.mmd)
|
|
19
18
|
- [isInfraAdapterDescriptor sequence](././paradox/diagrams/sequences/is-infra-adapter-descriptor.mmd)
|
|
20
19
|
- [isInfraAuthSpec sequence](././paradox/diagrams/sequences/is-infra-auth-spec.mmd)
|
|
21
20
|
- [isInfraDeploymentSpec sequence](././paradox/diagrams/sequences/is-infra-deployment-spec.mmd)
|
|
@@ -26,5 +25,4 @@ Serializable app, capability, binding, theme, auth, and secret-store contracts f
|
|
|
26
25
|
- [isSerializableSet sequence](././paradox/diagrams/sequences/is-serializable-set.mmd)
|
|
27
26
|
- [isSerializableValue sequence](././paradox/diagrams/sequences/is-serializable-value.mmd)
|
|
28
27
|
- [isStructureDescriptorDocument sequence](././paradox/diagrams/sequences/is-structure-descriptor-document.mmd)
|
|
29
|
-
- [normalizeCapability sequence](././paradox/diagrams/sequences/normalize-capability.mmd)
|
|
30
28
|
- [parseInfraManifest sequence](././paradox/diagrams/sequences/parse-infra-manifest.mmd)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DataSchemaSlot } from './data/schemas.js';
|
|
2
|
+
export type CapabilityAccess = 'emit' | 'invoke' | 'read' | 'subscribe' | 'write';
|
|
3
|
+
export type CapabilityBindingKind = 'action' | 'api' | 'auth' | 'authorization' | 'context' | 'event' | 'permission' | 'state' | 'storage';
|
|
4
|
+
export type CapabilityBindingRole = 'source' | 'target';
|
|
5
|
+
/**
|
|
6
|
+
* Portable description of one bindable or executable Ankhorage capability.
|
|
7
|
+
*
|
|
8
|
+
* Packages publish capability catalogs from `src/capabilities/index.ts`. Runtime registries,
|
|
9
|
+
* handlers, adapters, transport details, and framework objects remain package-owned and are not
|
|
10
|
+
* part of this serializable contract.
|
|
11
|
+
*/
|
|
12
|
+
export interface Capability {
|
|
13
|
+
readonly id: `${string}.${string}`;
|
|
14
|
+
readonly owner: string;
|
|
15
|
+
readonly access: readonly CapabilityAccess[];
|
|
16
|
+
readonly binding: {
|
|
17
|
+
readonly kind: CapabilityBindingKind;
|
|
18
|
+
readonly bindableAs: readonly CapabilityBindingRole[];
|
|
19
|
+
};
|
|
20
|
+
readonly label?: string;
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
readonly input?: DataSchemaSlot;
|
|
23
|
+
readonly output?: DataSchemaSlot;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC;AAElF,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,GACR,KAAK,GACL,MAAM,GACN,eAAe,GACf,SAAS,GACT,OAAO,GACP,YAAY,GACZ,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;QACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;KACvD,CAAC;IACF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"","sourcesContent":["import type { DataSchemaSlot } from './data/schemas.js';\n\nexport type CapabilityAccess = 'emit' | 'invoke' | 'read' | 'subscribe' | 'write';\n\nexport type CapabilityBindingKind =\n | 'action'\n | 'api'\n | 'auth'\n | 'authorization'\n | 'context'\n | 'event'\n | 'permission'\n | 'state'\n | 'storage';\n\nexport type CapabilityBindingRole = 'source' | 'target';\n\n/**\n * Portable description of one bindable or executable Ankhorage capability.\n *\n * Packages publish capability catalogs from `src/capabilities/index.ts`. Runtime registries,\n * handlers, adapters, transport details, and framework objects remain package-owned and are not\n * part of this serializable contract.\n */\nexport interface Capability {\n readonly id: `${string}.${string}`;\n readonly owner: string;\n readonly access: readonly CapabilityAccess[];\n readonly binding: {\n readonly kind: CapabilityBindingKind;\n readonly bindableAs: readonly CapabilityBindingRole[];\n };\n readonly label?: string;\n readonly description?: string;\n readonly input?: DataSchemaSlot;\n readonly output?: DataSchemaSlot;\n}\n"]}
|
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEzC,MAAM,MAAM,qBAAqB,GAAG,KAAK,MAAM,EAAE,CAAC;AAElD,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,qBAAqB,CAAC;CAC5C"}
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"","sourcesContent":["import type { Capability } from '../
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"","sourcesContent":["import type { Capability } from '../capability';\n\nexport type AnkhCommandCategory = string;\n\nexport type AnkhProviderReference = `./${string}`;\n\nexport interface AnkhCommandDescriptor {\n /**\n * Command path relative to the provider category.\n *\n * An empty path declares the command at the category root.\n */\n readonly path: readonly string[];\n readonly summary: string;\n readonly capability: Capability['id'];\n readonly aliases?: readonly string[];\n readonly examples?: readonly string[];\n}\n\nexport interface AnkhCommandProviderManifest {\n readonly id: string;\n readonly category: AnkhCommandCategory;\n readonly version: string;\n readonly capabilities: readonly Capability[];\n readonly commands: readonly AnkhCommandDescriptor[];\n}\n\nexport interface AnkhStructureRootMetadata {\n readonly source: string;\n readonly export: string;\n}\n\nexport interface AnkhStructureMetadata {\n readonly output: string;\n readonly roots: Readonly<Record<string, AnkhStructureRootMetadata>>;\n}\n\nexport interface AnkhPackageMetadata {\n readonly category: AnkhCommandCategory;\n readonly provider: AnkhProviderReference | null;\n readonly capabilities: readonly Capability[];\n readonly structure?: AnkhStructureMetadata;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC","sourcesContent":["export * from './appManifest';\nexport * from './auth';\nexport * from './bindings';\nexport * from './cli';\nexport * from './collections';\nexport * from './data';\nexport * from './db';\nexport * from './deploy';\nexport * from './deployProvider';\nexport * from './environments';\nexport * from './infra';\nexport * from './media';\nexport * from './navigator';\nexport * from './repository';\nexport * from './requirements';\nexport * from './runtimeCallbacks';\nexport * from './secrets';\nexport * from './serializable';\nexport * from './state';\nexport * from './storage';\nexport * from './structure';\nexport * from './theme';\nexport * from './types';\nexport * from './ui';\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare const STRUCTURE_DESCRIPTOR_COMPILER_VERSION = "6.0.3";
|
|
2
|
-
export declare const STRUCTURE_DESCRIPTOR_FINGERPRINT = "sha256:
|
|
2
|
+
export declare const STRUCTURE_DESCRIPTOR_FINGERPRINT = "sha256:ae107775b095cd601a0336a3369c6af308068a5796224278dfb503f482a41bbb";
|
|
3
3
|
export declare const STRUCTURE_DESCRIPTOR: {
|
|
4
4
|
readonly protocolVersion: 1;
|
|
5
5
|
readonly packageName: "@ankhorage/contracts";
|
|
6
|
-
readonly packageVersion: "
|
|
6
|
+
readonly packageVersion: "25.0.0";
|
|
7
7
|
readonly roots: {
|
|
8
8
|
readonly "auth-flow": "AuthFlowConfig";
|
|
9
9
|
readonly "auth-profile": "AuthProfileSpec";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const STRUCTURE_DESCRIPTOR_COMPILER_VERSION = '6.0.3';
|
|
2
|
-
export const STRUCTURE_DESCRIPTOR_FINGERPRINT = 'sha256:
|
|
2
|
+
export const STRUCTURE_DESCRIPTOR_FINGERPRINT = 'sha256:ae107775b095cd601a0336a3369c6af308068a5796224278dfb503f482a41bbb';
|
|
3
3
|
export const STRUCTURE_DESCRIPTOR = {
|
|
4
4
|
"protocolVersion": 1,
|
|
5
5
|
"packageName": "@ankhorage/contracts",
|
|
6
|
-
"packageVersion": "
|
|
6
|
+
"packageVersion": "25.0.0",
|
|
7
7
|
"roots": {
|
|
8
8
|
"auth-flow": "AuthFlowConfig",
|
|
9
9
|
"auth-profile": "AuthProfileSpec",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generated.js","sourceRoot":"","sources":["../../src/structure/generated.ts"],"names":[],"mappings":"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","sourcesContent":["/* This file is generated by @ankhorage/devtools. Do not edit manually. */\nimport type { StructureDescriptorDocument } from '@ankhorage/contracts/structure';\n\nexport const STRUCTURE_DESCRIPTOR_COMPILER_VERSION = '6.0.3';\nexport const STRUCTURE_DESCRIPTOR_FINGERPRINT = 'sha256:0d25fa7afb8f91adbae34b489d092f0758aeddce4e6bf23401e3f111a3b9129b';\n\nexport const STRUCTURE_DESCRIPTOR = {\n \"protocolVersion\": 1,\n \"packageName\": \"@ankhorage/contracts\",\n \"packageVersion\": \"24.2.1\",\n \"roots\": {\n \"auth-flow\": \"AuthFlowConfig\",\n \"auth-profile\": \"AuthProfileSpec\",\n \"auth-sign-in\": \"AuthSignInSpec\",\n \"auth-sign-up\": \"AuthSignUpSpec\",\n \"screen-metadata\": \"ScreenMetadataSpec\",\n \"screen-requirements\": \"ScreenRequirements\",\n \"theme-config\": \"ThemeConfig\"\n },\n \"descriptors\": {\n \"AuthFlowConfig\": {\n \"id\": \"AuthFlowConfig\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"forgotPasswordRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"otpRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"postSignInRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"signInRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"signOutRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"signUpRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"unauthorizedRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"AuthProfileField\": {\n \"id\": \"AuthProfileField\",\n \"descriptor\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"AuthProfileSpec\": {\n \"id\": \"AuthProfileSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"createStrategy\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"api\",\n \"app\",\n \"trigger\"\n ]\n },\n \"optional\": true\n },\n \"fields\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"ref\",\n \"id\": \"AuthProfileField\"\n }\n }\n },\n \"primaryKey\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"authUserId\"\n ]\n },\n \"optional\": true\n },\n \"table\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"updateStrategy\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"api\",\n \"app\"\n ]\n },\n \"optional\": true\n }\n }\n }\n },\n \"AuthSignInSpec\": {\n \"id\": \"AuthSignInSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"identifiers\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"enum\",\n \"values\": [\n \"email\",\n \"phone\",\n \"username\"\n ]\n }\n }\n }\n }\n }\n },\n \"AuthSignUpField\": {\n \"id\": \"AuthSignUpField\",\n \"descriptor\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"AuthSignUpSpec\": {\n \"id\": \"AuthSignUpSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"optionalFields\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"ref\",\n \"id\": \"AuthSignUpField\"\n }\n },\n \"optional\": true\n },\n \"requiredFields\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"ref\",\n \"id\": \"AuthSignUpField\"\n }\n }\n },\n \"signUpPolicy\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"autoSignIn\",\n \"requireVerification\"\n ]\n },\n \"optional\": true\n }\n }\n }\n },\n \"ScreenMetadataSpec\": {\n \"id\": \"ScreenMetadataSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"description\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"id\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"name\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"title\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ScreenRequirements\": {\n \"id\": \"ScreenRequirements\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"capabilities\": {\n \"value\": {\n \"kind\": \"set\",\n \"member\": {\n \"kind\": \"enum\",\n \"values\": [\n \"barcodeScanner\",\n \"cameraPreview\",\n \"clipboard\",\n \"ebookReader\",\n \"filePicker\",\n \"location\",\n \"mediaPicker\",\n \"notifications\"\n ]\n }\n },\n \"optional\": true\n },\n \"permissions\": {\n \"value\": {\n \"kind\": \"set\",\n \"member\": {\n \"kind\": \"enum\",\n \"values\": [\n \"camera\",\n \"clipboard\",\n \"locationBackground\",\n \"locationForeground\",\n \"mediaLibrary\",\n \"mediaLibraryWrite\",\n \"microphone\",\n \"notifications\"\n ]\n }\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeConfig\": {\n \"id\": \"ThemeConfig\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"dark\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeModeConfig\"\n }\n },\n \"id\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"light\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeModeConfig\"\n }\n },\n \"name\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"recipes\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeRecipeOverrides\"\n },\n \"optional\": true\n },\n \"tokens\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeGlobalTokenOverrides\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeGlobalTokenOverrides\": {\n \"id\": \"ThemeGlobalTokenOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"radii\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"shadows\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"spacing\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"typography\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeTypographyTokenOverrides\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeModeConfig\": {\n \"id\": \"ThemeModeConfig\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"harmony\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"analogous\",\n \"complementary\",\n \"monochromatic\",\n \"splitComplementary\",\n \"square\",\n \"tetradic\",\n \"triadic\"\n ]\n }\n },\n \"primaryColor\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n }\n }\n }\n },\n \"ThemeRecipeOverrides\": {\n \"id\": \"ThemeRecipeOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"components\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"ref\",\n \"packageName\": \"typescript\",\n \"id\": \"Readonly\"\n }\n },\n \"optional\": true\n },\n \"patterns\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"ref\",\n \"packageName\": \"typescript\",\n \"id\": \"Readonly\"\n }\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeTypographyHeadingOverrides\": {\n \"id\": \"ThemeTypographyHeadingOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"lineHeight\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n },\n \"optional\": true\n },\n \"size\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n },\n \"optional\": true\n },\n \"weight\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeTypographyTokenOverrides\": {\n \"id\": \"ThemeTypographyTokenOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"headings\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeTypographyHeadingOverrides\"\n }\n },\n \"optional\": true\n },\n \"sizes\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"weights\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"optional\": true\n }\n }\n }\n }\n }\n} as const satisfies StructureDescriptorDocument;\n"]}
|
|
1
|
+
{"version":3,"file":"generated.js","sourceRoot":"","sources":["../../src/structure/generated.ts"],"names":[],"mappings":"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","sourcesContent":["/* This file is generated by @ankhorage/devtools. Do not edit manually. */\nimport type { StructureDescriptorDocument } from '@ankhorage/contracts/structure';\n\nexport const STRUCTURE_DESCRIPTOR_COMPILER_VERSION = '6.0.3';\nexport const STRUCTURE_DESCRIPTOR_FINGERPRINT = 'sha256:ae107775b095cd601a0336a3369c6af308068a5796224278dfb503f482a41bbb';\n\nexport const STRUCTURE_DESCRIPTOR = {\n \"protocolVersion\": 1,\n \"packageName\": \"@ankhorage/contracts\",\n \"packageVersion\": \"25.0.0\",\n \"roots\": {\n \"auth-flow\": \"AuthFlowConfig\",\n \"auth-profile\": \"AuthProfileSpec\",\n \"auth-sign-in\": \"AuthSignInSpec\",\n \"auth-sign-up\": \"AuthSignUpSpec\",\n \"screen-metadata\": \"ScreenMetadataSpec\",\n \"screen-requirements\": \"ScreenRequirements\",\n \"theme-config\": \"ThemeConfig\"\n },\n \"descriptors\": {\n \"AuthFlowConfig\": {\n \"id\": \"AuthFlowConfig\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"forgotPasswordRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"otpRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"postSignInRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"signInRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"signOutRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"signUpRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"unauthorizedRoute\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"AuthProfileField\": {\n \"id\": \"AuthProfileField\",\n \"descriptor\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"AuthProfileSpec\": {\n \"id\": \"AuthProfileSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"createStrategy\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"api\",\n \"app\",\n \"trigger\"\n ]\n },\n \"optional\": true\n },\n \"fields\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"ref\",\n \"id\": \"AuthProfileField\"\n }\n }\n },\n \"primaryKey\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"authUserId\"\n ]\n },\n \"optional\": true\n },\n \"table\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"updateStrategy\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"api\",\n \"app\"\n ]\n },\n \"optional\": true\n }\n }\n }\n },\n \"AuthSignInSpec\": {\n \"id\": \"AuthSignInSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"identifiers\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"enum\",\n \"values\": [\n \"email\",\n \"phone\",\n \"username\"\n ]\n }\n }\n }\n }\n }\n },\n \"AuthSignUpField\": {\n \"id\": \"AuthSignUpField\",\n \"descriptor\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"AuthSignUpSpec\": {\n \"id\": \"AuthSignUpSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"optionalFields\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"ref\",\n \"id\": \"AuthSignUpField\"\n }\n },\n \"optional\": true\n },\n \"requiredFields\": {\n \"value\": {\n \"kind\": \"ordered-list\",\n \"item\": {\n \"kind\": \"ref\",\n \"id\": \"AuthSignUpField\"\n }\n }\n },\n \"signUpPolicy\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"autoSignIn\",\n \"requireVerification\"\n ]\n },\n \"optional\": true\n }\n }\n }\n },\n \"ScreenMetadataSpec\": {\n \"id\": \"ScreenMetadataSpec\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"description\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n },\n \"id\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"name\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"title\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ScreenRequirements\": {\n \"id\": \"ScreenRequirements\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"capabilities\": {\n \"value\": {\n \"kind\": \"set\",\n \"member\": {\n \"kind\": \"enum\",\n \"values\": [\n \"barcodeScanner\",\n \"cameraPreview\",\n \"clipboard\",\n \"ebookReader\",\n \"filePicker\",\n \"location\",\n \"mediaPicker\",\n \"notifications\"\n ]\n }\n },\n \"optional\": true\n },\n \"permissions\": {\n \"value\": {\n \"kind\": \"set\",\n \"member\": {\n \"kind\": \"enum\",\n \"values\": [\n \"camera\",\n \"clipboard\",\n \"locationBackground\",\n \"locationForeground\",\n \"mediaLibrary\",\n \"mediaLibraryWrite\",\n \"microphone\",\n \"notifications\"\n ]\n }\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeConfig\": {\n \"id\": \"ThemeConfig\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"dark\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeModeConfig\"\n }\n },\n \"id\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"light\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeModeConfig\"\n }\n },\n \"name\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"recipes\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeRecipeOverrides\"\n },\n \"optional\": true\n },\n \"tokens\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeGlobalTokenOverrides\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeGlobalTokenOverrides\": {\n \"id\": \"ThemeGlobalTokenOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"radii\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"shadows\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"spacing\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"typography\": {\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeTypographyTokenOverrides\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeModeConfig\": {\n \"id\": \"ThemeModeConfig\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"harmony\": {\n \"value\": {\n \"kind\": \"enum\",\n \"values\": [\n \"analogous\",\n \"complementary\",\n \"monochromatic\",\n \"splitComplementary\",\n \"square\",\n \"tetradic\",\n \"triadic\"\n ]\n }\n },\n \"primaryColor\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n }\n }\n }\n },\n \"ThemeRecipeOverrides\": {\n \"id\": \"ThemeRecipeOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"components\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"ref\",\n \"packageName\": \"typescript\",\n \"id\": \"Readonly\"\n }\n },\n \"optional\": true\n },\n \"patterns\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"ref\",\n \"packageName\": \"typescript\",\n \"id\": \"Readonly\"\n }\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeTypographyHeadingOverrides\": {\n \"id\": \"ThemeTypographyHeadingOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"lineHeight\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n },\n \"optional\": true\n },\n \"size\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n },\n \"optional\": true\n },\n \"weight\": {\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"optional\": true\n }\n }\n }\n },\n \"ThemeTypographyTokenOverrides\": {\n \"id\": \"ThemeTypographyTokenOverrides\",\n \"descriptor\": {\n \"kind\": \"object\",\n \"fields\": {\n \"headings\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"ref\",\n \"id\": \"ThemeTypographyHeadingOverrides\"\n }\n },\n \"optional\": true\n },\n \"sizes\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"number\"\n }\n },\n \"optional\": true\n },\n \"weights\": {\n \"value\": {\n \"kind\": \"value-map\",\n \"key\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n },\n \"value\": {\n \"kind\": \"scalar\",\n \"type\": \"string\"\n }\n },\n \"optional\": true\n }\n }\n }\n }\n }\n} as const satisfies StructureDescriptorDocument;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/contracts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "25.0.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"ankh": {
|
|
6
6
|
"category": "contracts",
|
|
@@ -130,9 +130,9 @@
|
|
|
130
130
|
"types": "./dist/structure/index.d.ts",
|
|
131
131
|
"default": "./dist/structure/index.js"
|
|
132
132
|
},
|
|
133
|
-
"./
|
|
134
|
-
"types": "./dist/
|
|
135
|
-
"default": "./dist/
|
|
133
|
+
"./capability": {
|
|
134
|
+
"types": "./dist/capability.d.ts",
|
|
135
|
+
"default": "./dist/capability.js"
|
|
136
136
|
}
|
|
137
137
|
},
|
|
138
138
|
"description": "Serializable app, capability, binding, theme, auth, and secret-store contracts for Ankhorage.",
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
Capability,
|
|
5
|
+
CapabilityAccess,
|
|
6
|
+
CapabilityBindingKind,
|
|
7
|
+
CapabilityBindingRole,
|
|
8
|
+
} from './capability';
|
|
9
|
+
|
|
10
|
+
const CAPABILITIES = [
|
|
11
|
+
{
|
|
12
|
+
id: 'state.value',
|
|
13
|
+
owner: '@ankhorage/runtime',
|
|
14
|
+
access: ['read', 'write', 'subscribe'],
|
|
15
|
+
binding: { kind: 'state', bindableAs: ['source', 'target'] },
|
|
16
|
+
label: 'Runtime state value',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'button.press',
|
|
20
|
+
owner: '@ankhorage/zora',
|
|
21
|
+
access: ['emit'],
|
|
22
|
+
binding: { kind: 'event', bindableAs: ['source'] },
|
|
23
|
+
output: {
|
|
24
|
+
schema: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: { sourceNodeId: { type: 'string' } },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'navigator.navigate',
|
|
32
|
+
owner: '@ankhorage/navigator',
|
|
33
|
+
access: ['invoke'],
|
|
34
|
+
binding: { kind: 'action', bindableAs: ['target'] },
|
|
35
|
+
label: 'Navigate',
|
|
36
|
+
input: {
|
|
37
|
+
schema: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
required: ['route'],
|
|
40
|
+
properties: {
|
|
41
|
+
route: { type: 'string' },
|
|
42
|
+
params: { type: 'object', additionalProperties: true },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'api.catalog.product.create',
|
|
49
|
+
owner: '@ankhorage/api',
|
|
50
|
+
access: ['invoke'],
|
|
51
|
+
binding: { kind: 'api', bindableAs: ['target'] },
|
|
52
|
+
input: {
|
|
53
|
+
schema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
required: ['name'],
|
|
56
|
+
properties: { name: { type: 'string' } },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
output: {
|
|
60
|
+
schema: {
|
|
61
|
+
type: 'object',
|
|
62
|
+
required: ['id'],
|
|
63
|
+
properties: { id: { type: 'string' } },
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'auth.user',
|
|
69
|
+
owner: '@ankhorage/auth',
|
|
70
|
+
access: ['read', 'subscribe'],
|
|
71
|
+
binding: { kind: 'auth', bindableAs: ['source'] },
|
|
72
|
+
output: {
|
|
73
|
+
schema: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: { id: { type: 'string' } },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'permission.camera.request',
|
|
81
|
+
owner: '@ankhorage/permissions',
|
|
82
|
+
access: ['invoke'],
|
|
83
|
+
binding: { kind: 'permission', bindableAs: ['target'] },
|
|
84
|
+
output: {
|
|
85
|
+
schema: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: { granted: { type: 'boolean' } },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'storage.upload',
|
|
93
|
+
owner: '@ankhorage/storage',
|
|
94
|
+
access: ['invoke'],
|
|
95
|
+
binding: { kind: 'storage', bindableAs: [] },
|
|
96
|
+
label: 'Upload storage object',
|
|
97
|
+
},
|
|
98
|
+
] as const satisfies readonly Capability[];
|
|
99
|
+
|
|
100
|
+
describe('Capability serialization', () => {
|
|
101
|
+
it('serializes bindable and executable package capabilities through one contract', () => {
|
|
102
|
+
expect(JSON.parse(JSON.stringify(CAPABILITIES))).toEqual(CAPABILITIES);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('Capability declarations', () => {
|
|
107
|
+
it('models the portable capability vocabulary without runtime behavior', () => {
|
|
108
|
+
const access: CapabilityAccess = 'invoke';
|
|
109
|
+
const bindingKind: CapabilityBindingKind = 'action';
|
|
110
|
+
const bindingRole: CapabilityBindingRole = 'target';
|
|
111
|
+
|
|
112
|
+
expect({ access, bindingKind, bindingRole }).toEqual({
|
|
113
|
+
access: 'invoke',
|
|
114
|
+
bindingKind: 'action',
|
|
115
|
+
bindingRole: 'target',
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DataSchemaSlot } from './data/schemas.js';
|
|
2
|
+
|
|
3
|
+
export type CapabilityAccess = 'emit' | 'invoke' | 'read' | 'subscribe' | 'write';
|
|
4
|
+
|
|
5
|
+
export type CapabilityBindingKind =
|
|
6
|
+
| 'action'
|
|
7
|
+
| 'api'
|
|
8
|
+
| 'auth'
|
|
9
|
+
| 'authorization'
|
|
10
|
+
| 'context'
|
|
11
|
+
| 'event'
|
|
12
|
+
| 'permission'
|
|
13
|
+
| 'state'
|
|
14
|
+
| 'storage';
|
|
15
|
+
|
|
16
|
+
export type CapabilityBindingRole = 'source' | 'target';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Portable description of one bindable or executable Ankhorage capability.
|
|
20
|
+
*
|
|
21
|
+
* Packages publish capability catalogs from `src/capabilities/index.ts`. Runtime registries,
|
|
22
|
+
* handlers, adapters, transport details, and framework objects remain package-owned and are not
|
|
23
|
+
* part of this serializable contract.
|
|
24
|
+
*/
|
|
25
|
+
export interface Capability {
|
|
26
|
+
readonly id: `${string}.${string}`;
|
|
27
|
+
readonly owner: string;
|
|
28
|
+
readonly access: readonly CapabilityAccess[];
|
|
29
|
+
readonly binding: {
|
|
30
|
+
readonly kind: CapabilityBindingKind;
|
|
31
|
+
readonly bindableAs: readonly CapabilityBindingRole[];
|
|
32
|
+
};
|
|
33
|
+
readonly label?: string;
|
|
34
|
+
readonly description?: string;
|
|
35
|
+
readonly input?: DataSchemaSlot;
|
|
36
|
+
readonly output?: DataSchemaSlot;
|
|
37
|
+
}
|
package/src/cli/index.ts
CHANGED
package/src/cli.test.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, expect, it } from 'bun:test';
|
|
2
2
|
|
|
3
|
+
import type { Capability } from './capability';
|
|
3
4
|
import type {
|
|
4
5
|
AnkhCommandDescriptor,
|
|
5
6
|
AnkhCommandProviderManifest,
|
|
6
7
|
AnkhPackageMetadata,
|
|
7
|
-
Capability,
|
|
8
8
|
} from './index';
|
|
9
9
|
|
|
10
10
|
const INFRA_CAPABILITIES = [
|
package/src/index.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import type { StructureDescriptorDocument } from '@ankhorage/contracts/structure';
|
|
3
3
|
|
|
4
4
|
export const STRUCTURE_DESCRIPTOR_COMPILER_VERSION = '6.0.3';
|
|
5
|
-
export const STRUCTURE_DESCRIPTOR_FINGERPRINT = 'sha256:
|
|
5
|
+
export const STRUCTURE_DESCRIPTOR_FINGERPRINT = 'sha256:ae107775b095cd601a0336a3369c6af308068a5796224278dfb503f482a41bbb';
|
|
6
6
|
|
|
7
7
|
export const STRUCTURE_DESCRIPTOR = {
|
|
8
8
|
"protocolVersion": 1,
|
|
9
9
|
"packageName": "@ankhorage/contracts",
|
|
10
|
-
"packageVersion": "
|
|
10
|
+
"packageVersion": "25.0.0",
|
|
11
11
|
"roots": {
|
|
12
12
|
"auth-flow": "AuthFlowConfig",
|
|
13
13
|
"auth-profile": "AuthProfileSpec",
|
package/dist/capabilities.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { DataSchemaSlot } from './data/schemas.js';
|
|
2
|
-
/*** Enumerate the operations a capability exposes to other packages. */
|
|
3
|
-
export declare const CAPABILITY_ACCESS: readonly ["emit", "invoke", "read", "subscribe", "write"];
|
|
4
|
-
export type CapabilityAccess = (typeof CAPABILITY_ACCESS)[number];
|
|
5
|
-
/*** Enumerate the portable runtime families supported by capability bindings. */
|
|
6
|
-
export declare const CAPABILITY_BINDING_KINDS: readonly ["action", "api", "auth", "authorization", "context", "event", "permission", "state", "storage"];
|
|
7
|
-
export type CapabilityBindingKind = (typeof CAPABILITY_BINDING_KINDS)[number];
|
|
8
|
-
/*** Enumerate the directions in which a capability can participate in a binding. */
|
|
9
|
-
export declare const CAPABILITY_BINDING_ROLES: readonly ["source", "target"];
|
|
10
|
-
export type CapabilityBindingRole = (typeof CAPABILITY_BINDING_ROLES)[number];
|
|
11
|
-
/**
|
|
12
|
-
* Portable description of one bindable or executable Ankhorage capability.
|
|
13
|
-
*
|
|
14
|
-
* Packages publish capability catalogs from `src/capabilities/index.ts`. Runtime registries,
|
|
15
|
-
* handlers, adapters, transport details, and framework objects remain package-owned and are not
|
|
16
|
-
* part of this serializable contract.
|
|
17
|
-
*/
|
|
18
|
-
export interface Capability {
|
|
19
|
-
readonly id: `${string}.${string}`;
|
|
20
|
-
readonly owner: string;
|
|
21
|
-
readonly access: readonly CapabilityAccess[];
|
|
22
|
-
readonly binding: {
|
|
23
|
-
readonly kind: CapabilityBindingKind;
|
|
24
|
-
readonly bindableAs: readonly CapabilityBindingRole[];
|
|
25
|
-
};
|
|
26
|
-
readonly label?: string;
|
|
27
|
-
readonly description?: string;
|
|
28
|
-
readonly input?: DataSchemaSlot;
|
|
29
|
-
readonly output?: DataSchemaSlot;
|
|
30
|
-
}
|
|
31
|
-
/*** Validate a stable dot-separated identifier for one capability. */
|
|
32
|
-
export declare function isCapabilityId(value: unknown): value is Capability['id'];
|
|
33
|
-
/*** Validate an untrusted value as one complete portable capability descriptor. */
|
|
34
|
-
export declare function isCapability(value: unknown): value is Capability;
|
|
35
|
-
/*** Return a capability with access and binding-role collections sorted and deduplicated. */
|
|
36
|
-
export declare function normalizeCapability(capability: Capability): Capability;
|
|
37
|
-
/*** Compare capability descriptors independent of object property and unordered collection ordering. */
|
|
38
|
-
export declare function areCapabilitiesEqual(left: Capability, right: Capability): boolean;
|
|
39
|
-
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,2DAA4D,CAAC;AAE3F,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,2GAU3B,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,+BAAgC,CAAC;AAEtE,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;QACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;KACvD,CAAC;IACF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,CAMxE;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAYhE;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CActE;AAED,wGAAwG;AACxG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAEjF"}
|
package/dist/capabilities.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { uniqueSortedStrings } from '@ankhorage/utility/array';
|
|
2
|
-
import { isRecord } from '@ankhorage/utility/object';
|
|
3
|
-
import { isNonEmptyString, isOptionalString } from '@ankhorage/utility/string';
|
|
4
|
-
import { isDataSchemaSlot } from './data/dataValidation.js';
|
|
5
|
-
/*** Enumerate the operations a capability exposes to other packages. */
|
|
6
|
-
export const CAPABILITY_ACCESS = ['emit', 'invoke', 'read', 'subscribe', 'write'];
|
|
7
|
-
/*** Enumerate the portable runtime families supported by capability bindings. */
|
|
8
|
-
export const CAPABILITY_BINDING_KINDS = [
|
|
9
|
-
'action',
|
|
10
|
-
'api',
|
|
11
|
-
'auth',
|
|
12
|
-
'authorization',
|
|
13
|
-
'context',
|
|
14
|
-
'event',
|
|
15
|
-
'permission',
|
|
16
|
-
'state',
|
|
17
|
-
'storage',
|
|
18
|
-
];
|
|
19
|
-
/*** Enumerate the directions in which a capability can participate in a binding. */
|
|
20
|
-
export const CAPABILITY_BINDING_ROLES = ['source', 'target'];
|
|
21
|
-
/*** Validate a stable dot-separated identifier for one capability. */
|
|
22
|
-
export function isCapabilityId(value) {
|
|
23
|
-
return (isNonEmptyString(value) &&
|
|
24
|
-
value.split('.').length >= 2 &&
|
|
25
|
-
value.split('.').every(isNonEmptyString));
|
|
26
|
-
}
|
|
27
|
-
/*** Validate an untrusted value as one complete portable capability descriptor. */
|
|
28
|
-
export function isCapability(value) {
|
|
29
|
-
return (isRecord(value) &&
|
|
30
|
-
isCapabilityId(value.id) &&
|
|
31
|
-
isNonEmptyString(value.owner) &&
|
|
32
|
-
isCapabilityAccessList(value.access) &&
|
|
33
|
-
isCapabilityBinding(value.binding) &&
|
|
34
|
-
isOptionalString(value.label) &&
|
|
35
|
-
isOptionalString(value.description) &&
|
|
36
|
-
(value.input === undefined || isDataSchemaSlot(value.input)) &&
|
|
37
|
-
(value.output === undefined || isDataSchemaSlot(value.output)));
|
|
38
|
-
}
|
|
39
|
-
/*** Return a capability with access and binding-role collections sorted and deduplicated. */
|
|
40
|
-
export function normalizeCapability(capability) {
|
|
41
|
-
return {
|
|
42
|
-
id: capability.id,
|
|
43
|
-
owner: capability.owner,
|
|
44
|
-
access: normalizeCapabilityAccess(capability.access),
|
|
45
|
-
binding: {
|
|
46
|
-
kind: capability.binding.kind,
|
|
47
|
-
bindableAs: normalizeCapabilityBindingRoles(capability.binding.bindableAs),
|
|
48
|
-
},
|
|
49
|
-
...(capability.label === undefined ? {} : { label: capability.label }),
|
|
50
|
-
...(capability.description === undefined ? {} : { description: capability.description }),
|
|
51
|
-
...(capability.input === undefined ? {} : { input: capability.input }),
|
|
52
|
-
...(capability.output === undefined ? {} : { output: capability.output }),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
/*** Compare capability descriptors independent of object property and unordered collection ordering. */
|
|
56
|
-
export function areCapabilitiesEqual(left, right) {
|
|
57
|
-
return areCapabilityValuesEqual(normalizeCapability(left), normalizeCapability(right));
|
|
58
|
-
}
|
|
59
|
-
/*** Validate a non-empty collection of supported capability access operations. */
|
|
60
|
-
function isCapabilityAccessList(value) {
|
|
61
|
-
return (Array.isArray(value) && value.length > 0 && value.every((entry) => isCapabilityAccess(entry)));
|
|
62
|
-
}
|
|
63
|
-
/*** Validate a portable capability binding descriptor. */
|
|
64
|
-
function isCapabilityBinding(value) {
|
|
65
|
-
return (isRecord(value) &&
|
|
66
|
-
isCapabilityBindingKind(value.kind) &&
|
|
67
|
-
Array.isArray(value.bindableAs) &&
|
|
68
|
-
value.bindableAs.every((entry) => isCapabilityBindingRole(entry)));
|
|
69
|
-
}
|
|
70
|
-
/*** Validate one supported capability access operation. */
|
|
71
|
-
function isCapabilityAccess(value) {
|
|
72
|
-
return typeof value === 'string' && CAPABILITY_ACCESS.some((access) => access === value);
|
|
73
|
-
}
|
|
74
|
-
/*** Validate one supported capability binding family. */
|
|
75
|
-
function isCapabilityBindingKind(value) {
|
|
76
|
-
return (typeof value === 'string' &&
|
|
77
|
-
CAPABILITY_BINDING_KINDS.some((bindingKind) => bindingKind === value));
|
|
78
|
-
}
|
|
79
|
-
/*** Validate one supported capability binding direction. */
|
|
80
|
-
function isCapabilityBindingRole(value) {
|
|
81
|
-
return (typeof value === 'string' &&
|
|
82
|
-
CAPABILITY_BINDING_ROLES.some((bindingRole) => bindingRole === value));
|
|
83
|
-
}
|
|
84
|
-
/*** Sort and deduplicate supported access operations using the canonical Utility collection helper. */
|
|
85
|
-
function normalizeCapabilityAccess(access) {
|
|
86
|
-
return uniqueSortedStrings(access).filter(isCapabilityAccess);
|
|
87
|
-
}
|
|
88
|
-
/*** Sort and deduplicate supported binding directions using the canonical Utility collection helper. */
|
|
89
|
-
function normalizeCapabilityBindingRoles(bindingRoles) {
|
|
90
|
-
return uniqueSortedStrings(bindingRoles).filter(isCapabilityBindingRole);
|
|
91
|
-
}
|
|
92
|
-
/*** Compare the serializable values contained by two normalized capability descriptors. */
|
|
93
|
-
function areCapabilityValuesEqual(left, right) {
|
|
94
|
-
if (Object.is(left, right))
|
|
95
|
-
return true;
|
|
96
|
-
if (Array.isArray(left) || Array.isArray(right))
|
|
97
|
-
return areCapabilityArraysEqual(left, right);
|
|
98
|
-
if (isRecord(left) && isRecord(right))
|
|
99
|
-
return areCapabilityRecordsEqual(left, right);
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
/*** Compare two serializable arrays in their authored order. */
|
|
103
|
-
function areCapabilityArraysEqual(left, right) {
|
|
104
|
-
return (Array.isArray(left) &&
|
|
105
|
-
Array.isArray(right) &&
|
|
106
|
-
left.length === right.length &&
|
|
107
|
-
left.every((value, index) => areCapabilityValuesEqual(value, right.at(index))));
|
|
108
|
-
}
|
|
109
|
-
/*** Compare two serializable records independent of their authored property order. */
|
|
110
|
-
function areCapabilityRecordsEqual(left, right) {
|
|
111
|
-
const leftEntries = Object.entries(left);
|
|
112
|
-
const rightEntries = Object.entries(right);
|
|
113
|
-
return (leftEntries.length === rightEntries.length &&
|
|
114
|
-
leftEntries.every(([leftKey, leftValue]) => rightEntries.some(([rightKey, rightValue]) => leftKey === rightKey && areCapabilityValuesEqual(leftValue, rightValue))));
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=capabilities.js.map
|
package/dist/capabilities.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["import { uniqueSortedStrings } from '@ankhorage/utility/array';\nimport { isRecord } from '@ankhorage/utility/object';\nimport { isNonEmptyString, isOptionalString } from '@ankhorage/utility/string';\n\nimport { isDataSchemaSlot } from './data/dataValidation.js';\nimport type { DataSchemaSlot } from './data/schemas.js';\n\n/*** Enumerate the operations a capability exposes to other packages. */\nexport const CAPABILITY_ACCESS = ['emit', 'invoke', 'read', 'subscribe', 'write'] as const;\n\nexport type CapabilityAccess = (typeof CAPABILITY_ACCESS)[number];\n\n/*** Enumerate the portable runtime families supported by capability bindings. */\nexport const CAPABILITY_BINDING_KINDS = [\n 'action',\n 'api',\n 'auth',\n 'authorization',\n 'context',\n 'event',\n 'permission',\n 'state',\n 'storage',\n] as const;\n\nexport type CapabilityBindingKind = (typeof CAPABILITY_BINDING_KINDS)[number];\n\n/*** Enumerate the directions in which a capability can participate in a binding. */\nexport const CAPABILITY_BINDING_ROLES = ['source', 'target'] as const;\n\nexport type CapabilityBindingRole = (typeof CAPABILITY_BINDING_ROLES)[number];\n\n/**\n * Portable description of one bindable or executable Ankhorage capability.\n *\n * Packages publish capability catalogs from `src/capabilities/index.ts`. Runtime registries,\n * handlers, adapters, transport details, and framework objects remain package-owned and are not\n * part of this serializable contract.\n */\nexport interface Capability {\n readonly id: `${string}.${string}`;\n readonly owner: string;\n readonly access: readonly CapabilityAccess[];\n readonly binding: {\n readonly kind: CapabilityBindingKind;\n readonly bindableAs: readonly CapabilityBindingRole[];\n };\n readonly label?: string;\n readonly description?: string;\n readonly input?: DataSchemaSlot;\n readonly output?: DataSchemaSlot;\n}\n\n/*** Validate a stable dot-separated identifier for one capability. */\nexport function isCapabilityId(value: unknown): value is Capability['id'] {\n return (\n isNonEmptyString(value) &&\n value.split('.').length >= 2 &&\n value.split('.').every(isNonEmptyString)\n );\n}\n\n/*** Validate an untrusted value as one complete portable capability descriptor. */\nexport function isCapability(value: unknown): value is Capability {\n return (\n isRecord(value) &&\n isCapabilityId(value.id) &&\n isNonEmptyString(value.owner) &&\n isCapabilityAccessList(value.access) &&\n isCapabilityBinding(value.binding) &&\n isOptionalString(value.label) &&\n isOptionalString(value.description) &&\n (value.input === undefined || isDataSchemaSlot(value.input)) &&\n (value.output === undefined || isDataSchemaSlot(value.output))\n );\n}\n\n/*** Return a capability with access and binding-role collections sorted and deduplicated. */\nexport function normalizeCapability(capability: Capability): Capability {\n return {\n id: capability.id,\n owner: capability.owner,\n access: normalizeCapabilityAccess(capability.access),\n binding: {\n kind: capability.binding.kind,\n bindableAs: normalizeCapabilityBindingRoles(capability.binding.bindableAs),\n },\n ...(capability.label === undefined ? {} : { label: capability.label }),\n ...(capability.description === undefined ? {} : { description: capability.description }),\n ...(capability.input === undefined ? {} : { input: capability.input }),\n ...(capability.output === undefined ? {} : { output: capability.output }),\n };\n}\n\n/*** Compare capability descriptors independent of object property and unordered collection ordering. */\nexport function areCapabilitiesEqual(left: Capability, right: Capability): boolean {\n return areCapabilityValuesEqual(normalizeCapability(left), normalizeCapability(right));\n}\n\n/*** Validate a non-empty collection of supported capability access operations. */\nfunction isCapabilityAccessList(value: unknown): value is readonly CapabilityAccess[] {\n return (\n Array.isArray(value) && value.length > 0 && value.every((entry) => isCapabilityAccess(entry))\n );\n}\n\n/*** Validate a portable capability binding descriptor. */\nfunction isCapabilityBinding(value: unknown): value is Capability['binding'] {\n return (\n isRecord(value) &&\n isCapabilityBindingKind(value.kind) &&\n Array.isArray(value.bindableAs) &&\n value.bindableAs.every((entry) => isCapabilityBindingRole(entry))\n );\n}\n\n/*** Validate one supported capability access operation. */\nfunction isCapabilityAccess(value: unknown): value is CapabilityAccess {\n return typeof value === 'string' && CAPABILITY_ACCESS.some((access) => access === value);\n}\n\n/*** Validate one supported capability binding family. */\nfunction isCapabilityBindingKind(value: unknown): value is CapabilityBindingKind {\n return (\n typeof value === 'string' &&\n CAPABILITY_BINDING_KINDS.some((bindingKind) => bindingKind === value)\n );\n}\n\n/*** Validate one supported capability binding direction. */\nfunction isCapabilityBindingRole(value: unknown): value is CapabilityBindingRole {\n return (\n typeof value === 'string' &&\n CAPABILITY_BINDING_ROLES.some((bindingRole) => bindingRole === value)\n );\n}\n\n/*** Sort and deduplicate supported access operations using the canonical Utility collection helper. */\nfunction normalizeCapabilityAccess(\n access: readonly CapabilityAccess[],\n): readonly CapabilityAccess[] {\n return uniqueSortedStrings(access).filter(isCapabilityAccess);\n}\n\n/*** Sort and deduplicate supported binding directions using the canonical Utility collection helper. */\nfunction normalizeCapabilityBindingRoles(\n bindingRoles: readonly CapabilityBindingRole[],\n): readonly CapabilityBindingRole[] {\n return uniqueSortedStrings(bindingRoles).filter(isCapabilityBindingRole);\n}\n\n/*** Compare the serializable values contained by two normalized capability descriptors. */\nfunction areCapabilityValuesEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) || Array.isArray(right)) return areCapabilityArraysEqual(left, right);\n if (isRecord(left) && isRecord(right)) return areCapabilityRecordsEqual(left, right);\n return false;\n}\n\n/*** Compare two serializable arrays in their authored order. */\nfunction areCapabilityArraysEqual(left: unknown, right: unknown): boolean {\n return (\n Array.isArray(left) &&\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((value, index) => areCapabilityValuesEqual(value, right.at(index)))\n );\n}\n\n/*** Compare two serializable records independent of their authored property order. */\nfunction areCapabilityRecordsEqual(\n left: Record<string, unknown>,\n right: Record<string, unknown>,\n): boolean {\n const leftEntries = Object.entries(left);\n const rightEntries = Object.entries(right);\n return (\n leftEntries.length === rightEntries.length &&\n leftEntries.every(([leftKey, leftValue]) =>\n rightEntries.some(\n ([rightKey, rightValue]) =>\n leftKey === rightKey && areCapabilityValuesEqual(leftValue, rightValue),\n ),\n )\n );\n}\n"]}
|
package/src/capabilities.test.ts
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
|
|
3
|
-
import type { Capability } from './capabilities';
|
|
4
|
-
import {
|
|
5
|
-
areCapabilitiesEqual,
|
|
6
|
-
CAPABILITY_ACCESS,
|
|
7
|
-
CAPABILITY_BINDING_KINDS,
|
|
8
|
-
CAPABILITY_BINDING_ROLES,
|
|
9
|
-
isCapability,
|
|
10
|
-
isCapabilityId,
|
|
11
|
-
normalizeCapability,
|
|
12
|
-
} from './capabilities';
|
|
13
|
-
import { isDataSchema, isDataSchemaSlot } from './data';
|
|
14
|
-
|
|
15
|
-
const CAPABILITIES = [
|
|
16
|
-
{
|
|
17
|
-
id: 'state.value',
|
|
18
|
-
owner: '@ankhorage/runtime',
|
|
19
|
-
access: ['read', 'write', 'subscribe'],
|
|
20
|
-
binding: { kind: 'state', bindableAs: ['source', 'target'] },
|
|
21
|
-
label: 'Runtime state value',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: 'button.press',
|
|
25
|
-
owner: '@ankhorage/zora',
|
|
26
|
-
access: ['emit'],
|
|
27
|
-
binding: { kind: 'event', bindableAs: ['source'] },
|
|
28
|
-
output: {
|
|
29
|
-
schema: {
|
|
30
|
-
type: 'object',
|
|
31
|
-
properties: { sourceNodeId: { type: 'string' } },
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
id: 'navigator.navigate',
|
|
37
|
-
owner: '@ankhorage/navigator',
|
|
38
|
-
access: ['invoke'],
|
|
39
|
-
binding: { kind: 'action', bindableAs: ['target'] },
|
|
40
|
-
label: 'Navigate',
|
|
41
|
-
input: {
|
|
42
|
-
schema: {
|
|
43
|
-
type: 'object',
|
|
44
|
-
required: ['route'],
|
|
45
|
-
properties: {
|
|
46
|
-
route: { type: 'string' },
|
|
47
|
-
params: { type: 'object', additionalProperties: true },
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: 'api.catalog.product.create',
|
|
54
|
-
owner: '@ankhorage/api',
|
|
55
|
-
access: ['invoke'],
|
|
56
|
-
binding: { kind: 'api', bindableAs: ['target'] },
|
|
57
|
-
input: {
|
|
58
|
-
schema: {
|
|
59
|
-
type: 'object',
|
|
60
|
-
required: ['name'],
|
|
61
|
-
properties: { name: { type: 'string' } },
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
output: {
|
|
65
|
-
schema: {
|
|
66
|
-
type: 'object',
|
|
67
|
-
required: ['id'],
|
|
68
|
-
properties: { id: { type: 'string' } },
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
id: 'auth.user',
|
|
74
|
-
owner: '@ankhorage/auth',
|
|
75
|
-
access: ['read', 'subscribe'],
|
|
76
|
-
binding: { kind: 'auth', bindableAs: ['source'] },
|
|
77
|
-
output: {
|
|
78
|
-
schema: {
|
|
79
|
-
type: 'object',
|
|
80
|
-
properties: { id: { type: 'string' } },
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
id: 'permission.camera.request',
|
|
86
|
-
owner: '@ankhorage/permissions',
|
|
87
|
-
access: ['invoke'],
|
|
88
|
-
binding: { kind: 'permission', bindableAs: ['target'] },
|
|
89
|
-
output: {
|
|
90
|
-
schema: {
|
|
91
|
-
type: 'object',
|
|
92
|
-
properties: { granted: { type: 'boolean' } },
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
id: 'storage.upload',
|
|
98
|
-
owner: '@ankhorage/storage',
|
|
99
|
-
access: ['invoke'],
|
|
100
|
-
binding: { kind: 'storage', bindableAs: [] },
|
|
101
|
-
label: 'Upload storage object',
|
|
102
|
-
},
|
|
103
|
-
] as const satisfies readonly Capability[];
|
|
104
|
-
|
|
105
|
-
describe('Capability serialization', () => {
|
|
106
|
-
it('serializes bindable and executable package capabilities through one contract', () => {
|
|
107
|
-
expect(JSON.parse(JSON.stringify(CAPABILITIES))).toEqual(CAPABILITIES);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('Capability runtime API', () => {
|
|
112
|
-
it('exports the canonical runtime literals that derive the public contract unions', () => {
|
|
113
|
-
expect(CAPABILITY_ACCESS).toEqual(['emit', 'invoke', 'read', 'subscribe', 'write']);
|
|
114
|
-
expect(CAPABILITY_BINDING_KINDS).toEqual([
|
|
115
|
-
'action',
|
|
116
|
-
'api',
|
|
117
|
-
'auth',
|
|
118
|
-
'authorization',
|
|
119
|
-
'context',
|
|
120
|
-
'event',
|
|
121
|
-
'permission',
|
|
122
|
-
'state',
|
|
123
|
-
'storage',
|
|
124
|
-
]);
|
|
125
|
-
expect(CAPABILITY_BINDING_ROLES).toEqual(['source', 'target']);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('validates canonical capability identifiers', () => {
|
|
129
|
-
expect(isCapabilityId('state.profile')).toBeTrue();
|
|
130
|
-
expect(isCapabilityId('api.catalog.product.create')).toBeTrue();
|
|
131
|
-
expect(isCapabilityId('state')).toBeFalse();
|
|
132
|
-
expect(isCapabilityId('state.')).toBeFalse();
|
|
133
|
-
expect(isCapabilityId('.state')).toBeFalse();
|
|
134
|
-
expect(isCapabilityId('state..profile')).toBeFalse();
|
|
135
|
-
expect(isCapabilityId(' .profile')).toBeFalse();
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('publishes DataSchema and DataSchemaSlot validation for capability input and output', () => {
|
|
139
|
-
expect(isDataSchema({ type: 'object', properties: { id: { type: 'string' } } })).toBeTrue();
|
|
140
|
-
expect(isDataSchemaSlot({ schemaRef: { id: 'customer' } })).toBeTrue();
|
|
141
|
-
expect(isDataSchema({ type: 'date' })).toBeFalse();
|
|
142
|
-
expect(isDataSchemaSlot({ schema: { type: 'date' } })).toBeFalse();
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('validates complete capability descriptors through the shared schema validators', () => {
|
|
146
|
-
expect(isCapability(CAPABILITIES[3])).toBeTrue();
|
|
147
|
-
expect(isCapability(CAPABILITIES[6])).toBeTrue();
|
|
148
|
-
expect(
|
|
149
|
-
isCapability({
|
|
150
|
-
...CAPABILITIES[3],
|
|
151
|
-
binding: { kind: 'command', bindableAs: ['target'] },
|
|
152
|
-
}),
|
|
153
|
-
).toBeFalse();
|
|
154
|
-
expect(
|
|
155
|
-
isCapability({
|
|
156
|
-
...CAPABILITIES[3],
|
|
157
|
-
binding: { kind: 'api', bindableAs: ['bidirectional'] },
|
|
158
|
-
}),
|
|
159
|
-
).toBeFalse();
|
|
160
|
-
expect(isCapability({ ...CAPABILITIES[3], access: ['delete'] })).toBeFalse();
|
|
161
|
-
expect(isCapability({ ...CAPABILITIES[3], input: { schema: { type: 'date' } } })).toBeFalse();
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
describe('Capability packed Node ESM boundary', () => {
|
|
166
|
-
it('imports the built public capabilities entrypoint with Node ESM resolution', async () => {
|
|
167
|
-
const subprocess = Bun.spawn(['node', '-e', "import('./dist/capabilities.js')"], {
|
|
168
|
-
cwd: process.cwd(),
|
|
169
|
-
stderr: 'pipe',
|
|
170
|
-
stdout: 'pipe',
|
|
171
|
-
});
|
|
172
|
-
const [exitCode, stderr] = await Promise.all([
|
|
173
|
-
subprocess.exited,
|
|
174
|
-
new Response(subprocess.stderr).text(),
|
|
175
|
-
]);
|
|
176
|
-
|
|
177
|
-
expect(stderr).toBe('');
|
|
178
|
-
expect(exitCode).toBe(0);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
describe('Capability canonical projection', () => {
|
|
183
|
-
it('projects accepted runtime capabilities to their canonical descriptor', () => {
|
|
184
|
-
const runtimeCapability = {
|
|
185
|
-
...CAPABILITIES[3],
|
|
186
|
-
access: ['invoke', 'invoke'],
|
|
187
|
-
binding: {
|
|
188
|
-
kind: 'api',
|
|
189
|
-
bindableAs: ['target', 'target'],
|
|
190
|
-
runtimeBindingMetadata: { generatedBy: 'runtime' },
|
|
191
|
-
},
|
|
192
|
-
label: undefined,
|
|
193
|
-
description: undefined,
|
|
194
|
-
runtimeMetadata: { transport: 'local' },
|
|
195
|
-
};
|
|
196
|
-
const canonicalCapability: Capability = {
|
|
197
|
-
id: 'api.catalog.product.create',
|
|
198
|
-
owner: '@ankhorage/api',
|
|
199
|
-
access: ['invoke'],
|
|
200
|
-
binding: { kind: 'api', bindableAs: ['target'] },
|
|
201
|
-
input: CAPABILITIES[3].input,
|
|
202
|
-
output: CAPABILITIES[3].output,
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
expect(isCapability(runtimeCapability)).toBeTrue();
|
|
206
|
-
expect(normalizeCapability(runtimeCapability)).toEqual(canonicalCapability);
|
|
207
|
-
expect(areCapabilitiesEqual(runtimeCapability, canonicalCapability)).toBeTrue();
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
describe('Capability canonicalization', () => {
|
|
212
|
-
it('normalizes unordered access and binding roles', () => {
|
|
213
|
-
const normalized = normalizeCapability({
|
|
214
|
-
...CAPABILITIES[0],
|
|
215
|
-
access: ['write', 'read', 'write', 'subscribe'],
|
|
216
|
-
binding: { kind: 'state', bindableAs: ['target', 'source', 'target'] },
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
expect(normalized.access).toEqual(['read', 'subscribe', 'write']);
|
|
220
|
-
expect(normalized.binding.bindableAs).toEqual(['source', 'target']);
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it('preserves trusted-only storage capabilities without a generic UI binding role', () => {
|
|
224
|
-
const normalized = normalizeCapability({
|
|
225
|
-
...CAPABILITIES[6],
|
|
226
|
-
access: ['invoke', 'invoke'],
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
expect(normalized).toEqual(CAPABILITIES[6]);
|
|
230
|
-
expect(normalized.binding.bindableAs).toEqual([]);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('compares normalized capability descriptors semantically', () => {
|
|
234
|
-
const equivalent: Capability = {
|
|
235
|
-
id: 'state.value',
|
|
236
|
-
owner: '@ankhorage/runtime',
|
|
237
|
-
access: ['read', 'subscribe', 'write'],
|
|
238
|
-
binding: { kind: 'state', bindableAs: ['source', 'target'] },
|
|
239
|
-
label: 'Runtime state value',
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
expect(
|
|
243
|
-
areCapabilitiesEqual(
|
|
244
|
-
normalizeCapability({
|
|
245
|
-
...CAPABILITIES[0],
|
|
246
|
-
access: ['write', 'read', 'write', 'subscribe'],
|
|
247
|
-
binding: { kind: 'state', bindableAs: ['target', 'source', 'target'] },
|
|
248
|
-
}),
|
|
249
|
-
equivalent,
|
|
250
|
-
),
|
|
251
|
-
).toBeTrue();
|
|
252
|
-
expect(
|
|
253
|
-
areCapabilitiesEqual(equivalent, {
|
|
254
|
-
...equivalent,
|
|
255
|
-
binding: { kind: 'event', bindableAs: ['source', 'target'] },
|
|
256
|
-
}),
|
|
257
|
-
).toBeFalse();
|
|
258
|
-
});
|
|
259
|
-
});
|
package/src/capabilities.ts
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { uniqueSortedStrings } from '@ankhorage/utility/array';
|
|
2
|
-
import { isRecord } from '@ankhorage/utility/object';
|
|
3
|
-
import { isNonEmptyString, isOptionalString } from '@ankhorage/utility/string';
|
|
4
|
-
|
|
5
|
-
import { isDataSchemaSlot } from './data/dataValidation.js';
|
|
6
|
-
import type { DataSchemaSlot } from './data/schemas.js';
|
|
7
|
-
|
|
8
|
-
/*** Enumerate the operations a capability exposes to other packages. */
|
|
9
|
-
export const CAPABILITY_ACCESS = ['emit', 'invoke', 'read', 'subscribe', 'write'] as const;
|
|
10
|
-
|
|
11
|
-
export type CapabilityAccess = (typeof CAPABILITY_ACCESS)[number];
|
|
12
|
-
|
|
13
|
-
/*** Enumerate the portable runtime families supported by capability bindings. */
|
|
14
|
-
export const CAPABILITY_BINDING_KINDS = [
|
|
15
|
-
'action',
|
|
16
|
-
'api',
|
|
17
|
-
'auth',
|
|
18
|
-
'authorization',
|
|
19
|
-
'context',
|
|
20
|
-
'event',
|
|
21
|
-
'permission',
|
|
22
|
-
'state',
|
|
23
|
-
'storage',
|
|
24
|
-
] as const;
|
|
25
|
-
|
|
26
|
-
export type CapabilityBindingKind = (typeof CAPABILITY_BINDING_KINDS)[number];
|
|
27
|
-
|
|
28
|
-
/*** Enumerate the directions in which a capability can participate in a binding. */
|
|
29
|
-
export const CAPABILITY_BINDING_ROLES = ['source', 'target'] as const;
|
|
30
|
-
|
|
31
|
-
export type CapabilityBindingRole = (typeof CAPABILITY_BINDING_ROLES)[number];
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Portable description of one bindable or executable Ankhorage capability.
|
|
35
|
-
*
|
|
36
|
-
* Packages publish capability catalogs from `src/capabilities/index.ts`. Runtime registries,
|
|
37
|
-
* handlers, adapters, transport details, and framework objects remain package-owned and are not
|
|
38
|
-
* part of this serializable contract.
|
|
39
|
-
*/
|
|
40
|
-
export interface Capability {
|
|
41
|
-
readonly id: `${string}.${string}`;
|
|
42
|
-
readonly owner: string;
|
|
43
|
-
readonly access: readonly CapabilityAccess[];
|
|
44
|
-
readonly binding: {
|
|
45
|
-
readonly kind: CapabilityBindingKind;
|
|
46
|
-
readonly bindableAs: readonly CapabilityBindingRole[];
|
|
47
|
-
};
|
|
48
|
-
readonly label?: string;
|
|
49
|
-
readonly description?: string;
|
|
50
|
-
readonly input?: DataSchemaSlot;
|
|
51
|
-
readonly output?: DataSchemaSlot;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/*** Validate a stable dot-separated identifier for one capability. */
|
|
55
|
-
export function isCapabilityId(value: unknown): value is Capability['id'] {
|
|
56
|
-
return (
|
|
57
|
-
isNonEmptyString(value) &&
|
|
58
|
-
value.split('.').length >= 2 &&
|
|
59
|
-
value.split('.').every(isNonEmptyString)
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/*** Validate an untrusted value as one complete portable capability descriptor. */
|
|
64
|
-
export function isCapability(value: unknown): value is Capability {
|
|
65
|
-
return (
|
|
66
|
-
isRecord(value) &&
|
|
67
|
-
isCapabilityId(value.id) &&
|
|
68
|
-
isNonEmptyString(value.owner) &&
|
|
69
|
-
isCapabilityAccessList(value.access) &&
|
|
70
|
-
isCapabilityBinding(value.binding) &&
|
|
71
|
-
isOptionalString(value.label) &&
|
|
72
|
-
isOptionalString(value.description) &&
|
|
73
|
-
(value.input === undefined || isDataSchemaSlot(value.input)) &&
|
|
74
|
-
(value.output === undefined || isDataSchemaSlot(value.output))
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/*** Return a capability with access and binding-role collections sorted and deduplicated. */
|
|
79
|
-
export function normalizeCapability(capability: Capability): Capability {
|
|
80
|
-
return {
|
|
81
|
-
id: capability.id,
|
|
82
|
-
owner: capability.owner,
|
|
83
|
-
access: normalizeCapabilityAccess(capability.access),
|
|
84
|
-
binding: {
|
|
85
|
-
kind: capability.binding.kind,
|
|
86
|
-
bindableAs: normalizeCapabilityBindingRoles(capability.binding.bindableAs),
|
|
87
|
-
},
|
|
88
|
-
...(capability.label === undefined ? {} : { label: capability.label }),
|
|
89
|
-
...(capability.description === undefined ? {} : { description: capability.description }),
|
|
90
|
-
...(capability.input === undefined ? {} : { input: capability.input }),
|
|
91
|
-
...(capability.output === undefined ? {} : { output: capability.output }),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/*** Compare capability descriptors independent of object property and unordered collection ordering. */
|
|
96
|
-
export function areCapabilitiesEqual(left: Capability, right: Capability): boolean {
|
|
97
|
-
return areCapabilityValuesEqual(normalizeCapability(left), normalizeCapability(right));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/*** Validate a non-empty collection of supported capability access operations. */
|
|
101
|
-
function isCapabilityAccessList(value: unknown): value is readonly CapabilityAccess[] {
|
|
102
|
-
return (
|
|
103
|
-
Array.isArray(value) && value.length > 0 && value.every((entry) => isCapabilityAccess(entry))
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/*** Validate a portable capability binding descriptor. */
|
|
108
|
-
function isCapabilityBinding(value: unknown): value is Capability['binding'] {
|
|
109
|
-
return (
|
|
110
|
-
isRecord(value) &&
|
|
111
|
-
isCapabilityBindingKind(value.kind) &&
|
|
112
|
-
Array.isArray(value.bindableAs) &&
|
|
113
|
-
value.bindableAs.every((entry) => isCapabilityBindingRole(entry))
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/*** Validate one supported capability access operation. */
|
|
118
|
-
function isCapabilityAccess(value: unknown): value is CapabilityAccess {
|
|
119
|
-
return typeof value === 'string' && CAPABILITY_ACCESS.some((access) => access === value);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/*** Validate one supported capability binding family. */
|
|
123
|
-
function isCapabilityBindingKind(value: unknown): value is CapabilityBindingKind {
|
|
124
|
-
return (
|
|
125
|
-
typeof value === 'string' &&
|
|
126
|
-
CAPABILITY_BINDING_KINDS.some((bindingKind) => bindingKind === value)
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/*** Validate one supported capability binding direction. */
|
|
131
|
-
function isCapabilityBindingRole(value: unknown): value is CapabilityBindingRole {
|
|
132
|
-
return (
|
|
133
|
-
typeof value === 'string' &&
|
|
134
|
-
CAPABILITY_BINDING_ROLES.some((bindingRole) => bindingRole === value)
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/*** Sort and deduplicate supported access operations using the canonical Utility collection helper. */
|
|
139
|
-
function normalizeCapabilityAccess(
|
|
140
|
-
access: readonly CapabilityAccess[],
|
|
141
|
-
): readonly CapabilityAccess[] {
|
|
142
|
-
return uniqueSortedStrings(access).filter(isCapabilityAccess);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/*** Sort and deduplicate supported binding directions using the canonical Utility collection helper. */
|
|
146
|
-
function normalizeCapabilityBindingRoles(
|
|
147
|
-
bindingRoles: readonly CapabilityBindingRole[],
|
|
148
|
-
): readonly CapabilityBindingRole[] {
|
|
149
|
-
return uniqueSortedStrings(bindingRoles).filter(isCapabilityBindingRole);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/*** Compare the serializable values contained by two normalized capability descriptors. */
|
|
153
|
-
function areCapabilityValuesEqual(left: unknown, right: unknown): boolean {
|
|
154
|
-
if (Object.is(left, right)) return true;
|
|
155
|
-
if (Array.isArray(left) || Array.isArray(right)) return areCapabilityArraysEqual(left, right);
|
|
156
|
-
if (isRecord(left) && isRecord(right)) return areCapabilityRecordsEqual(left, right);
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/*** Compare two serializable arrays in their authored order. */
|
|
161
|
-
function areCapabilityArraysEqual(left: unknown, right: unknown): boolean {
|
|
162
|
-
return (
|
|
163
|
-
Array.isArray(left) &&
|
|
164
|
-
Array.isArray(right) &&
|
|
165
|
-
left.length === right.length &&
|
|
166
|
-
left.every((value, index) => areCapabilityValuesEqual(value, right.at(index)))
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/*** Compare two serializable records independent of their authored property order. */
|
|
171
|
-
function areCapabilityRecordsEqual(
|
|
172
|
-
left: Record<string, unknown>,
|
|
173
|
-
right: Record<string, unknown>,
|
|
174
|
-
): boolean {
|
|
175
|
-
const leftEntries = Object.entries(left);
|
|
176
|
-
const rightEntries = Object.entries(right);
|
|
177
|
-
return (
|
|
178
|
-
leftEntries.length === rightEntries.length &&
|
|
179
|
-
leftEntries.every(([leftKey, leftValue]) =>
|
|
180
|
-
rightEntries.some(
|
|
181
|
-
([rightKey, rightValue]) =>
|
|
182
|
-
leftKey === rightKey && areCapabilityValuesEqual(leftValue, rightValue),
|
|
183
|
-
),
|
|
184
|
-
)
|
|
185
|
-
);
|
|
186
|
-
}
|