@ankhorage/permissions 0.2.64 → 0.3.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ankhorage/permissions
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 253d7f3: Publish canonical Capability descriptors for the Permissions Ankh provider.
8
+
3
9
  ## 0.2.64
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # PERMISSIONS
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v0.2.64](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![paradox: canonical](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v0.3.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![paradox: canonical](././paradox/badges/docs.svg)
7
7
 
8
8
  Cross-platform permission registry and runtime helpers for Expo, React Native, and React Native Web apps, with unified request/check APIs for camera, media, location, notifications, microphone, and other web/native capabilities.
9
9
 
@@ -1,9 +1,49 @@
1
1
  declare const provider: {
2
- id: string;
3
- category: string;
4
- version: string;
5
- capabilities: readonly ["permissions.inspect", "permissions.check", "permissions.request", "permissions.manifest"];
6
- commands: readonly [{
2
+ readonly id: "@ankhorage/permissions";
3
+ readonly category: "permissions";
4
+ readonly version: string;
5
+ readonly capabilities: readonly [{
6
+ readonly id: "permissions.inspect";
7
+ readonly owner: "@ankhorage/permissions";
8
+ readonly access: readonly ["invoke"];
9
+ readonly binding: {
10
+ readonly kind: "action";
11
+ readonly bindableAs: readonly ["target"];
12
+ };
13
+ readonly label: "Inspect permissions";
14
+ readonly description: "List known permission identifiers and registry metadata.";
15
+ }, {
16
+ readonly id: "permissions.check";
17
+ readonly owner: "@ankhorage/permissions";
18
+ readonly access: readonly ["invoke"];
19
+ readonly binding: {
20
+ readonly kind: "action";
21
+ readonly bindableAs: readonly ["target"];
22
+ };
23
+ readonly label: "Check permission";
24
+ readonly description: "Check a permission state through a host-provided permission client.";
25
+ }, {
26
+ readonly id: "permissions.request";
27
+ readonly owner: "@ankhorage/permissions";
28
+ readonly access: readonly ["invoke"];
29
+ readonly binding: {
30
+ readonly kind: "action";
31
+ readonly bindableAs: readonly ["target"];
32
+ };
33
+ readonly label: "Request permission";
34
+ readonly description: "Request a permission through a host-provided permission client.";
35
+ }, {
36
+ readonly id: "permissions.manifest";
37
+ readonly owner: "@ankhorage/permissions";
38
+ readonly access: readonly ["invoke"];
39
+ readonly binding: {
40
+ readonly kind: "action";
41
+ readonly bindableAs: readonly ["target"];
42
+ };
43
+ readonly label: "Inspect permission manifest";
44
+ readonly description: "Show native and web manifest metadata required by registered permissions.";
45
+ }];
46
+ readonly commands: readonly [{
7
47
  readonly path: readonly ["list"];
8
48
  readonly summary: "List known permission identifiers and registry metadata.";
9
49
  readonly capability: "permissions.inspect";
@@ -25,7 +65,7 @@ declare const provider: {
25
65
  readonly capability: "permissions.manifest";
26
66
  readonly examples: readonly ["ankh permissions manifest camera"];
27
67
  }];
28
- handlers: {
68
+ readonly handlers: {
29
69
  path: readonly ["list"] | readonly ["check"] | readonly ["request"] | readonly ["manifest"];
30
70
  handler(request: {
31
71
  readonly context: {
@@ -1 +1 @@
1
- {"version":3,"file":"ankh.provider.d.ts","sourceRoot":"","sources":["../src/ankh.provider.ts"],"names":[],"mappings":"AAwDA,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAbK;YACf,QAAQ,CAAC,OAAO,EAAE;gBAChB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;aACjC,CAAC;SACH;;;;CAgBF,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"ankh.provider.d.ts","sourceRoot":"","sources":["../src/ankh.provider.ts"],"names":[],"mappings":"AAwDA,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAbK;YACf,QAAQ,CAAC,OAAO,EAAE;gBAChB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;aACjC,CAAC;SACH;;;;CAgB4C,CAAC;AAEhD,eAAe,QAAQ,CAAC"}
@@ -1,13 +1,8 @@
1
+ import packageJson from '../package.json';
2
+ import { CAPABILITIES } from './capabilities/index';
1
3
  import { PERMISSIONS } from './registry/permissions';
2
4
  const PERMISSIONS_PACKAGE_NAME = '@ankhorage/permissions';
3
- const PERMISSIONS_PACKAGE_VERSION = '0.2.0';
4
5
  const PERMISSIONS_COMMAND_CATEGORY = 'permissions';
5
- const PERMISSIONS_CAPABILITIES = [
6
- 'permissions.inspect',
7
- 'permissions.check',
8
- 'permissions.request',
9
- 'permissions.manifest',
10
- ];
11
6
  const commands = [
12
7
  {
13
8
  path: ['list'],
@@ -46,8 +41,8 @@ const handlers = commands.map((command) => ({
46
41
  const provider = {
47
42
  id: PERMISSIONS_PACKAGE_NAME,
48
43
  category: PERMISSIONS_COMMAND_CATEGORY,
49
- version: PERMISSIONS_PACKAGE_VERSION,
50
- capabilities: PERMISSIONS_CAPABILITIES,
44
+ version: packageJson.version,
45
+ capabilities: CAPABILITIES,
51
46
  commands,
52
47
  handlers,
53
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ankh.provider.js","sourceRoot":"","sources":["../src/ankh.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,2BAA2B,GAAG,OAAO,CAAC;AAC5C,MAAM,4BAA4B,GAAG,aAAa,CAAC;AAEnD,MAAM,wBAAwB,GAAG;IAC/B,qBAAqB;IACrB,mBAAmB;IACnB,qBAAqB;IACrB,sBAAsB;CACd,CAAC;AAEX,MAAM,QAAQ,GAAG;IACf;QACE,IAAI,EAAE,CAAC,MAAM,CAAC;QACd,OAAO,EAAE,0DAA0D;QACnE,UAAU,EAAE,qBAAqB;QACjC,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,QAAQ,EAAE,CAAC,uBAAuB,CAAC;KACpC;IACD;QACE,IAAI,EAAE,CAAC,OAAO,CAAC;QACf,OAAO,EAAE,qEAAqE;QAC9E,UAAU,EAAE,mBAAmB;QAC/B,QAAQ,EAAE,CAAC,+BAA+B,CAAC;KAC5C;IACD;QACE,IAAI,EAAE,CAAC,SAAS,CAAC;QACjB,OAAO,EAAE,iEAAiE;QAC1E,UAAU,EAAE,qBAAqB;QACjC,QAAQ,EAAE,CAAC,iCAAiC,CAAC;KAC9C;IACD;QACE,IAAI,EAAE,CAAC,UAAU,CAAC;QAClB,OAAO,EAAE,uEAAuE;QAChF,UAAU,EAAE,sBAAsB;QAClC,QAAQ,EAAE,CAAC,kCAAkC,CAAC;KAC/C;CACO,CAAC;AAEX,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,EAAE,OAAO,CAAC,IAAI;IAClB,OAAO,CAAC,OAIP;QACC,OAAO,CAAC,OAAO,CAAC,WAAW,CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,wBAAwB,IAAI;YACtE,sBAAsB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CACpD,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,MAAM,QAAQ,GAAG;IACf,EAAE,EAAE,wBAAwB;IAC5B,QAAQ,EAAE,4BAA4B;IACtC,OAAO,EAAE,2BAA2B;IACpC,YAAY,EAAE,wBAAwB;IACtC,QAAQ;IACR,QAAQ;CACT,CAAC;AAEF,eAAe,QAAQ,CAAC","sourcesContent":["import { PERMISSIONS } from './registry/permissions';\n\nconst PERMISSIONS_PACKAGE_NAME = '@ankhorage/permissions';\nconst PERMISSIONS_PACKAGE_VERSION = '0.2.0';\nconst PERMISSIONS_COMMAND_CATEGORY = 'permissions';\n\nconst PERMISSIONS_CAPABILITIES = [\n 'permissions.inspect',\n 'permissions.check',\n 'permissions.request',\n 'permissions.manifest',\n] as const;\n\nconst commands = [\n {\n path: ['list'],\n summary: 'List known permission identifiers and registry metadata.',\n capability: 'permissions.inspect',\n aliases: ['registry'],\n examples: ['ankh permissions list'],\n },\n {\n path: ['check'],\n summary: 'Check a permission state through a host-provided permission client.',\n capability: 'permissions.check',\n examples: ['ankh permissions check camera'],\n },\n {\n path: ['request'],\n summary: 'Request a permission through a host-provided permission client.',\n capability: 'permissions.request',\n examples: ['ankh permissions request camera'],\n },\n {\n path: ['manifest'],\n summary: 'Show native/web manifest metadata required by registered permissions.',\n capability: 'permissions.manifest',\n examples: ['ankh permissions manifest camera'],\n },\n] as const;\n\nconst handlers = commands.map((command) => ({\n path: command.path,\n handler(request: {\n readonly context: {\n writeStdout(text: string): void;\n };\n }) {\n request.context.writeStdout(\n `${command.path.join(' ')} is provided by ${PERMISSIONS_PACKAGE_NAME}. ` +\n `Known permissions: ${PERMISSIONS.join(', ')}.\\n`,\n );\n return { exitCode: 0 };\n },\n}));\n\nconst provider = {\n id: PERMISSIONS_PACKAGE_NAME,\n category: PERMISSIONS_COMMAND_CATEGORY,\n version: PERMISSIONS_PACKAGE_VERSION,\n capabilities: PERMISSIONS_CAPABILITIES,\n commands,\n handlers,\n};\n\nexport default provider;\n"]}
1
+ {"version":3,"file":"ankh.provider.js","sourceRoot":"","sources":["../src/ankh.provider.ts"],"names":[],"mappings":"AAIA,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAC1D,MAAM,4BAA4B,GAAG,aAAa,CAAC;AAEnD,MAAM,QAAQ,GAAG;IACf;QACE,IAAI,EAAE,CAAC,MAAM,CAAC;QACd,OAAO,EAAE,0DAA0D;QACnE,UAAU,EAAE,qBAAgD;QAC5D,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,QAAQ,EAAE,CAAC,uBAAuB,CAAC;KACpC;IACD;QACE,IAAI,EAAE,CAAC,OAAO,CAAC;QACf,OAAO,EAAE,qEAAqE;QAC9E,UAAU,EAAE,mBAA8C;QAC1D,QAAQ,EAAE,CAAC,+BAA+B,CAAC;KAC5C;IACD;QACE,IAAI,EAAE,CAAC,SAAS,CAAC;QACjB,OAAO,EAAE,iEAAiE;QAC1E,UAAU,EAAE,qBAAgD;QAC5D,QAAQ,EAAE,CAAC,iCAAiC,CAAC;KAC9C;IACD;QACE,IAAI,EAAE,CAAC,UAAU,CAAC;QAClB,OAAO,EAAE,uEAAuE;QAChF,UAAU,EAAE,sBAAiD;QAC7D,QAAQ,EAAE,CAAC,kCAAkC,CAAC;KAC/C;CAGC,CAAC;AAEL,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,EAAE,OAAO,CAAC,IAAI;IAClB,OAAO,CAAC,OAIP;QACC,OAAO,CAAC,OAAO,CAAC,WAAW,CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,wBAAwB,IAAI;YACtE,sBAAsB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CACpD,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,MAAM,QAAQ,GAAG;IACf,EAAE,EAAE,wBAAwB;IAC5B,QAAQ,EAAE,4BAA4B;IACtC,OAAO,EAAE,WAAW,CAAC,OAAO;IAC5B,YAAY,EAAE,YAAY;IAC1B,QAAQ;IACR,QAAQ;CACqC,CAAC;AAEhD,eAAe,QAAQ,CAAC","sourcesContent":["import type { AnkhRuntimeCommandProvider } from '@ankhorage/ankh';\nimport type { Capability } from '@ankhorage/contracts/capabilities';\nimport type { AnkhCommandDescriptor } from '@ankhorage/contracts/cli';\n\nimport packageJson from '../package.json';\nimport { CAPABILITIES } from './capabilities/index';\nimport { PERMISSIONS } from './registry/permissions';\n\nconst PERMISSIONS_PACKAGE_NAME = '@ankhorage/permissions';\nconst PERMISSIONS_COMMAND_CATEGORY = 'permissions';\n\nconst commands = [\n {\n path: ['list'],\n summary: 'List known permission identifiers and registry metadata.',\n capability: 'permissions.inspect' satisfies Capability['id'],\n aliases: ['registry'],\n examples: ['ankh permissions list'],\n },\n {\n path: ['check'],\n summary: 'Check a permission state through a host-provided permission client.',\n capability: 'permissions.check' satisfies Capability['id'],\n examples: ['ankh permissions check camera'],\n },\n {\n path: ['request'],\n summary: 'Request a permission through a host-provided permission client.',\n capability: 'permissions.request' satisfies Capability['id'],\n examples: ['ankh permissions request camera'],\n },\n {\n path: ['manifest'],\n summary: 'Show native/web manifest metadata required by registered permissions.',\n capability: 'permissions.manifest' satisfies Capability['id'],\n examples: ['ankh permissions manifest camera'],\n },\n] as const satisfies readonly (AnkhCommandDescriptor & {\n readonly capability: Capability['id'];\n})[];\n\nconst handlers = commands.map((command) => ({\n path: command.path,\n handler(request: {\n readonly context: {\n writeStdout(text: string): void;\n };\n }) {\n request.context.writeStdout(\n `${command.path.join(' ')} is provided by ${PERMISSIONS_PACKAGE_NAME}. ` +\n `Known permissions: ${PERMISSIONS.join(', ')}.\\n`,\n );\n return { exitCode: 0 };\n },\n}));\n\nconst provider = {\n id: PERMISSIONS_PACKAGE_NAME,\n category: PERMISSIONS_COMMAND_CATEGORY,\n version: packageJson.version,\n capabilities: CAPABILITIES,\n commands,\n handlers,\n} as const satisfies AnkhRuntimeCommandProvider;\n\nexport default provider;\n"]}
@@ -0,0 +1,43 @@
1
+ /*** Define the executable permission operations published by this package. */
2
+ export declare const CAPABILITIES: readonly [{
3
+ readonly id: "permissions.inspect";
4
+ readonly owner: "@ankhorage/permissions";
5
+ readonly access: readonly ["invoke"];
6
+ readonly binding: {
7
+ readonly kind: "action";
8
+ readonly bindableAs: readonly ["target"];
9
+ };
10
+ readonly label: "Inspect permissions";
11
+ readonly description: "List known permission identifiers and registry metadata.";
12
+ }, {
13
+ readonly id: "permissions.check";
14
+ readonly owner: "@ankhorage/permissions";
15
+ readonly access: readonly ["invoke"];
16
+ readonly binding: {
17
+ readonly kind: "action";
18
+ readonly bindableAs: readonly ["target"];
19
+ };
20
+ readonly label: "Check permission";
21
+ readonly description: "Check a permission state through a host-provided permission client.";
22
+ }, {
23
+ readonly id: "permissions.request";
24
+ readonly owner: "@ankhorage/permissions";
25
+ readonly access: readonly ["invoke"];
26
+ readonly binding: {
27
+ readonly kind: "action";
28
+ readonly bindableAs: readonly ["target"];
29
+ };
30
+ readonly label: "Request permission";
31
+ readonly description: "Request a permission through a host-provided permission client.";
32
+ }, {
33
+ readonly id: "permissions.manifest";
34
+ readonly owner: "@ankhorage/permissions";
35
+ readonly access: readonly ["invoke"];
36
+ readonly binding: {
37
+ readonly kind: "action";
38
+ readonly bindableAs: readonly ["target"];
39
+ };
40
+ readonly label: "Inspect permission manifest";
41
+ readonly description: "Show native and web manifest metadata required by registered permissions.";
42
+ }];
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capabilities/index.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCiB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /*** Define the executable permission operations published by this package. */
2
+ export const CAPABILITIES = [
3
+ {
4
+ id: 'permissions.inspect',
5
+ owner: '@ankhorage/permissions',
6
+ access: ['invoke'],
7
+ binding: { kind: 'action', bindableAs: ['target'] },
8
+ label: 'Inspect permissions',
9
+ description: 'List known permission identifiers and registry metadata.',
10
+ },
11
+ {
12
+ id: 'permissions.check',
13
+ owner: '@ankhorage/permissions',
14
+ access: ['invoke'],
15
+ binding: { kind: 'action', bindableAs: ['target'] },
16
+ label: 'Check permission',
17
+ description: 'Check a permission state through a host-provided permission client.',
18
+ },
19
+ {
20
+ id: 'permissions.request',
21
+ owner: '@ankhorage/permissions',
22
+ access: ['invoke'],
23
+ binding: { kind: 'action', bindableAs: ['target'] },
24
+ label: 'Request permission',
25
+ description: 'Request a permission through a host-provided permission client.',
26
+ },
27
+ {
28
+ id: 'permissions.manifest',
29
+ owner: '@ankhorage/permissions',
30
+ access: ['invoke'],
31
+ binding: { kind: 'action', bindableAs: ['target'] },
32
+ label: 'Inspect permission manifest',
33
+ description: 'Show native and web manifest metadata required by registered permissions.',
34
+ },
35
+ ];
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capabilities/index.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;QACE,EAAE,EAAE,qBAAqB;QACzB,KAAK,EAAE,wBAAwB;QAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;QACnD,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,0DAA0D;KACxE;IACD;QACE,EAAE,EAAE,mBAAmB;QACvB,KAAK,EAAE,wBAAwB;QAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;QACnD,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,qEAAqE;KACnF;IACD;QACE,EAAE,EAAE,qBAAqB;QACzB,KAAK,EAAE,wBAAwB;QAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;QACnD,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,iEAAiE;KAC/E;IACD;QACE,EAAE,EAAE,sBAAsB;QAC1B,KAAK,EAAE,wBAAwB;QAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;QACnD,KAAK,EAAE,6BAA6B;QACpC,WAAW,EAAE,2EAA2E;KACzF;CACuC,CAAC","sourcesContent":["import type { Capability } from '@ankhorage/contracts/capabilities';\n\n/*** Define the executable permission operations published by this package. */\nexport const CAPABILITIES = [\n {\n id: 'permissions.inspect',\n owner: '@ankhorage/permissions',\n access: ['invoke'],\n binding: { kind: 'action', bindableAs: ['target'] },\n label: 'Inspect permissions',\n description: 'List known permission identifiers and registry metadata.',\n },\n {\n id: 'permissions.check',\n owner: '@ankhorage/permissions',\n access: ['invoke'],\n binding: { kind: 'action', bindableAs: ['target'] },\n label: 'Check permission',\n description: 'Check a permission state through a host-provided permission client.',\n },\n {\n id: 'permissions.request',\n owner: '@ankhorage/permissions',\n access: ['invoke'],\n binding: { kind: 'action', bindableAs: ['target'] },\n label: 'Request permission',\n description: 'Request a permission through a host-provided permission client.',\n },\n {\n id: 'permissions.manifest',\n owner: '@ankhorage/permissions',\n access: ['invoke'],\n binding: { kind: 'action', bindableAs: ['target'] },\n label: 'Inspect permission manifest',\n description: 'Show native and web manifest metadata required by registered permissions.',\n },\n] as const satisfies readonly Capability[];\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/permissions",
3
3
  "type": "module",
4
- "version": "0.2.64",
4
+ "version": "0.3.0",
5
5
  "description": "Cross-platform permission registry and runtime helpers for Expo, React Native, and React Native Web apps, with unified request/check APIs for camera, media, location, notifications, microphone, and other web/native capabilities.",
6
6
  "homepage": "https://github.com/ankhorage/permissions#readme",
7
7
  "bugs": {
@@ -34,7 +34,10 @@
34
34
  "typescript",
35
35
  "web"
36
36
  ],
37
- "dependencies": {},
37
+ "dependencies": {
38
+ "@ankhorage/ankh": "^0.12.0",
39
+ "@ankhorage/contracts": "^24.1.0"
40
+ },
38
41
  "peerDependencies": {
39
42
  "react": ">=18.2.0 || >=19.0.0"
40
43
  },
@@ -42,10 +45,66 @@
42
45
  "category": "permissions",
43
46
  "provider": "./dist/cli/index.js",
44
47
  "capabilities": [
45
- "permissions.inspect",
46
- "permissions.check",
47
- "permissions.request",
48
- "permissions.manifest"
48
+ {
49
+ "id": "permissions.inspect",
50
+ "owner": "@ankhorage/permissions",
51
+ "access": [
52
+ "invoke"
53
+ ],
54
+ "binding": {
55
+ "kind": "action",
56
+ "bindableAs": [
57
+ "target"
58
+ ]
59
+ },
60
+ "label": "Inspect permissions",
61
+ "description": "List known permission identifiers and registry metadata."
62
+ },
63
+ {
64
+ "id": "permissions.check",
65
+ "owner": "@ankhorage/permissions",
66
+ "access": [
67
+ "invoke"
68
+ ],
69
+ "binding": {
70
+ "kind": "action",
71
+ "bindableAs": [
72
+ "target"
73
+ ]
74
+ },
75
+ "label": "Check permission",
76
+ "description": "Check a permission state through a host-provided permission client."
77
+ },
78
+ {
79
+ "id": "permissions.request",
80
+ "owner": "@ankhorage/permissions",
81
+ "access": [
82
+ "invoke"
83
+ ],
84
+ "binding": {
85
+ "kind": "action",
86
+ "bindableAs": [
87
+ "target"
88
+ ]
89
+ },
90
+ "label": "Request permission",
91
+ "description": "Request a permission through a host-provided permission client."
92
+ },
93
+ {
94
+ "id": "permissions.manifest",
95
+ "owner": "@ankhorage/permissions",
96
+ "access": [
97
+ "invoke"
98
+ ],
99
+ "binding": {
100
+ "kind": "action",
101
+ "bindableAs": [
102
+ "target"
103
+ ]
104
+ },
105
+ "label": "Inspect permission manifest",
106
+ "description": "Show native and web manifest metadata required by registered permissions."
107
+ }
49
108
  ]
50
109
  },
51
110
  "files": [
@@ -69,6 +128,11 @@
69
128
  "import": "./dist/cli/index.js",
70
129
  "default": "./dist/cli/index.js"
71
130
  },
131
+ "./capabilities": {
132
+ "types": "./dist/capabilities/index.d.ts",
133
+ "import": "./dist/capabilities/index.js",
134
+ "default": "./dist/capabilities/index.js"
135
+ },
72
136
  "./react": {
73
137
  "react-native": "./dist/react/index.js",
74
138
  "browser": "./dist/react/index.js",
@@ -136,8 +200,8 @@
136
200
  "knip:check": "ankhorage-knip"
137
201
  },
138
202
  "devDependencies": {
139
- "@ankhorage/devtools": "^2.1.2",
140
- "@ankhorage/paradox": "^0.2.27",
203
+ "@ankhorage/devtools": "^2.1.19",
204
+ "@ankhorage/paradox": "^0.2.28",
141
205
  "@types/bun": "^1.4.2",
142
206
  "@types/node": "^26.6.4",
143
207
  "@types/react": "^19.3.0",
@@ -1,43 +1,43 @@
1
+ import type { AnkhRuntimeCommandProvider } from '@ankhorage/ankh';
2
+ import type { Capability } from '@ankhorage/contracts/capabilities';
3
+ import type { AnkhCommandDescriptor } from '@ankhorage/contracts/cli';
4
+
5
+ import packageJson from '../package.json';
6
+ import { CAPABILITIES } from './capabilities/index';
1
7
  import { PERMISSIONS } from './registry/permissions';
2
8
 
3
9
  const PERMISSIONS_PACKAGE_NAME = '@ankhorage/permissions';
4
- const PERMISSIONS_PACKAGE_VERSION = '0.2.0';
5
10
  const PERMISSIONS_COMMAND_CATEGORY = 'permissions';
6
11
 
7
- const PERMISSIONS_CAPABILITIES = [
8
- 'permissions.inspect',
9
- 'permissions.check',
10
- 'permissions.request',
11
- 'permissions.manifest',
12
- ] as const;
13
-
14
12
  const commands = [
15
13
  {
16
14
  path: ['list'],
17
15
  summary: 'List known permission identifiers and registry metadata.',
18
- capability: 'permissions.inspect',
16
+ capability: 'permissions.inspect' satisfies Capability['id'],
19
17
  aliases: ['registry'],
20
18
  examples: ['ankh permissions list'],
21
19
  },
22
20
  {
23
21
  path: ['check'],
24
22
  summary: 'Check a permission state through a host-provided permission client.',
25
- capability: 'permissions.check',
23
+ capability: 'permissions.check' satisfies Capability['id'],
26
24
  examples: ['ankh permissions check camera'],
27
25
  },
28
26
  {
29
27
  path: ['request'],
30
28
  summary: 'Request a permission through a host-provided permission client.',
31
- capability: 'permissions.request',
29
+ capability: 'permissions.request' satisfies Capability['id'],
32
30
  examples: ['ankh permissions request camera'],
33
31
  },
34
32
  {
35
33
  path: ['manifest'],
36
34
  summary: 'Show native/web manifest metadata required by registered permissions.',
37
- capability: 'permissions.manifest',
35
+ capability: 'permissions.manifest' satisfies Capability['id'],
38
36
  examples: ['ankh permissions manifest camera'],
39
37
  },
40
- ] as const;
38
+ ] as const satisfies readonly (AnkhCommandDescriptor & {
39
+ readonly capability: Capability['id'];
40
+ })[];
41
41
 
42
42
  const handlers = commands.map((command) => ({
43
43
  path: command.path,
@@ -57,10 +57,10 @@ const handlers = commands.map((command) => ({
57
57
  const provider = {
58
58
  id: PERMISSIONS_PACKAGE_NAME,
59
59
  category: PERMISSIONS_COMMAND_CATEGORY,
60
- version: PERMISSIONS_PACKAGE_VERSION,
61
- capabilities: PERMISSIONS_CAPABILITIES,
60
+ version: packageJson.version,
61
+ capabilities: CAPABILITIES,
62
62
  commands,
63
63
  handlers,
64
- };
64
+ } as const satisfies AnkhRuntimeCommandProvider;
65
65
 
66
66
  export default provider;
@@ -0,0 +1,15 @@
1
+ import { isCapability } from '@ankhorage/contracts/capabilities';
2
+ import { describe, expect, test } from 'bun:test';
3
+
4
+ import { CAPABILITIES } from './index';
5
+
6
+ describe('CAPABILITIES', () => {
7
+ test('publishes canonical executable action targets', () => {
8
+ expect(CAPABILITIES).toHaveLength(4);
9
+ for (const capability of CAPABILITIES) {
10
+ expect(isCapability(capability)).toBeTrue();
11
+ expect(capability.access).toEqual(['invoke']);
12
+ expect(capability.binding).toEqual({ kind: 'action', bindableAs: ['target'] });
13
+ }
14
+ });
15
+ });
@@ -0,0 +1,37 @@
1
+ import type { Capability } from '@ankhorage/contracts/capabilities';
2
+
3
+ /*** Define the executable permission operations published by this package. */
4
+ export const CAPABILITIES = [
5
+ {
6
+ id: 'permissions.inspect',
7
+ owner: '@ankhorage/permissions',
8
+ access: ['invoke'],
9
+ binding: { kind: 'action', bindableAs: ['target'] },
10
+ label: 'Inspect permissions',
11
+ description: 'List known permission identifiers and registry metadata.',
12
+ },
13
+ {
14
+ id: 'permissions.check',
15
+ owner: '@ankhorage/permissions',
16
+ access: ['invoke'],
17
+ binding: { kind: 'action', bindableAs: ['target'] },
18
+ label: 'Check permission',
19
+ description: 'Check a permission state through a host-provided permission client.',
20
+ },
21
+ {
22
+ id: 'permissions.request',
23
+ owner: '@ankhorage/permissions',
24
+ access: ['invoke'],
25
+ binding: { kind: 'action', bindableAs: ['target'] },
26
+ label: 'Request permission',
27
+ description: 'Request a permission through a host-provided permission client.',
28
+ },
29
+ {
30
+ id: 'permissions.manifest',
31
+ owner: '@ankhorage/permissions',
32
+ access: ['invoke'],
33
+ binding: { kind: 'action', bindableAs: ['target'] },
34
+ label: 'Inspect permission manifest',
35
+ description: 'Show native and web manifest metadata required by registered permissions.',
36
+ },
37
+ ] as const satisfies readonly Capability[];
@@ -1,6 +1,8 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
2
 
3
+ import packageJson from '../package.json';
3
4
  import provider from './ankh.provider';
5
+ import { CAPABILITIES } from './capabilities/index';
4
6
 
5
7
  describe('provider', () => {
6
8
  test('declares permission command metadata', () => {
@@ -10,4 +12,32 @@ describe('provider', () => {
10
12
  provider.commands.map((entry) => entry.path.join(' ')),
11
13
  );
12
14
  });
15
+
16
+ test('keeps package metadata, provider metadata, and catalog aligned', () => {
17
+ expect(packageJson.ankh.capabilities).toEqual(
18
+ CAPABILITIES.map((capability) => ({
19
+ ...capability,
20
+ access: [...capability.access],
21
+ binding: {
22
+ ...capability.binding,
23
+ bindableAs: [...capability.binding.bindableAs],
24
+ },
25
+ })),
26
+ );
27
+ expect(provider.capabilities).toEqual(CAPABILITIES);
28
+ expect(provider.version).toBe(packageJson.version);
29
+ });
30
+
31
+ test('maps every command to its canonical capability by ID', () => {
32
+ expect(provider.commands.map(({ path, capability }) => ({ path, capability }))).toEqual([
33
+ { path: ['list'], capability: 'permissions.inspect' },
34
+ { path: ['check'], capability: 'permissions.check' },
35
+ { path: ['request'], capability: 'permissions.request' },
36
+ { path: ['manifest'], capability: 'permissions.manifest' },
37
+ ]);
38
+
39
+ expect([...provider.commands.map(({ capability }) => capability)].sort()).toEqual(
40
+ [...CAPABILITIES.map(({ id }) => id)].sort(),
41
+ );
42
+ });
13
43
  });