@parlor/capabilities 0.0.0-stage → 0.1.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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -2
  3. package/dist/adapters/capacitor.d.ts +3 -0
  4. package/dist/adapters/capacitor.d.ts.map +1 -0
  5. package/dist/adapters/capacitor.js +21 -0
  6. package/dist/adapters/capacitor.js.map +1 -0
  7. package/dist/adapters/tauri.d.ts +3 -0
  8. package/dist/adapters/tauri.d.ts.map +1 -0
  9. package/dist/adapters/tauri.js +21 -0
  10. package/dist/adapters/tauri.js.map +1 -0
  11. package/dist/adapters/types.d.ts +16 -0
  12. package/dist/adapters/types.d.ts.map +1 -0
  13. package/dist/adapters/types.js +2 -0
  14. package/dist/adapters/types.js.map +1 -0
  15. package/dist/adapters/web.d.ts +3 -0
  16. package/dist/adapters/web.d.ts.map +1 -0
  17. package/dist/adapters/web.js +15 -0
  18. package/dist/adapters/web.js.map +1 -0
  19. package/dist/capability.d.ts +21 -0
  20. package/dist/capability.d.ts.map +1 -0
  21. package/dist/capability.js +21 -0
  22. package/dist/capability.js.map +1 -0
  23. package/dist/deep-link/capacitor.d.ts +16 -0
  24. package/dist/deep-link/capacitor.d.ts.map +1 -0
  25. package/dist/deep-link/capacitor.js +28 -0
  26. package/dist/deep-link/capacitor.js.map +1 -0
  27. package/dist/deep-link/index.d.ts +7 -0
  28. package/dist/deep-link/index.d.ts.map +1 -0
  29. package/dist/deep-link/index.js +10 -0
  30. package/dist/deep-link/index.js.map +1 -0
  31. package/dist/deep-link/interface.d.ts +5 -0
  32. package/dist/deep-link/interface.d.ts.map +1 -0
  33. package/dist/deep-link/interface.js +2 -0
  34. package/dist/deep-link/interface.js.map +1 -0
  35. package/dist/deep-link/tauri.d.ts +8 -0
  36. package/dist/deep-link/tauri.d.ts.map +1 -0
  37. package/dist/deep-link/tauri.js +28 -0
  38. package/dist/deep-link/tauri.js.map +1 -0
  39. package/dist/deep-link/web.d.ts +4 -0
  40. package/dist/deep-link/web.d.ts.map +1 -0
  41. package/dist/deep-link/web.js +20 -0
  42. package/dist/deep-link/web.js.map +1 -0
  43. package/dist/device-key/capacitor.d.ts +32 -0
  44. package/dist/device-key/capacitor.d.ts.map +1 -0
  45. package/dist/device-key/capacitor.js +9 -0
  46. package/dist/device-key/capacitor.js.map +1 -0
  47. package/dist/device-key/encoding.d.ts +12 -0
  48. package/dist/device-key/encoding.d.ts.map +1 -0
  49. package/dist/device-key/encoding.js +45 -0
  50. package/dist/device-key/encoding.js.map +1 -0
  51. package/dist/device-key/index.d.ts +8 -0
  52. package/dist/device-key/index.d.ts.map +1 -0
  53. package/dist/device-key/index.js +11 -0
  54. package/dist/device-key/index.js.map +1 -0
  55. package/dist/device-key/interface.d.ts +74 -0
  56. package/dist/device-key/interface.d.ts.map +1 -0
  57. package/dist/device-key/interface.js +7 -0
  58. package/dist/device-key/interface.js.map +1 -0
  59. package/dist/device-key/native.d.ts +38 -0
  60. package/dist/device-key/native.d.ts.map +1 -0
  61. package/dist/device-key/native.js +67 -0
  62. package/dist/device-key/native.js.map +1 -0
  63. package/dist/device-key/tauri.d.ts +8 -0
  64. package/dist/device-key/tauri.d.ts.map +1 -0
  65. package/dist/device-key/tauri.js +16 -0
  66. package/dist/device-key/tauri.js.map +1 -0
  67. package/dist/device-key/web.d.ts +11 -0
  68. package/dist/device-key/web.d.ts.map +1 -0
  69. package/dist/device-key/web.js +210 -0
  70. package/dist/device-key/web.js.map +1 -0
  71. package/dist/files/capacitor.d.ts +19 -0
  72. package/dist/files/capacitor.d.ts.map +1 -0
  73. package/dist/files/capacitor.js +47 -0
  74. package/dist/files/capacitor.js.map +1 -0
  75. package/dist/files/index.d.ts +7 -0
  76. package/dist/files/index.d.ts.map +1 -0
  77. package/dist/files/index.js +10 -0
  78. package/dist/files/index.js.map +1 -0
  79. package/dist/files/interface.d.ts +29 -0
  80. package/dist/files/interface.d.ts.map +1 -0
  81. package/dist/files/interface.js +2 -0
  82. package/dist/files/interface.js.map +1 -0
  83. package/dist/files/mime.d.ts +11 -0
  84. package/dist/files/mime.d.ts.map +1 -0
  85. package/dist/files/mime.js +56 -0
  86. package/dist/files/mime.js.map +1 -0
  87. package/dist/files/tauri.d.ts +27 -0
  88. package/dist/files/tauri.d.ts.map +1 -0
  89. package/dist/files/tauri.js +46 -0
  90. package/dist/files/tauri.js.map +1 -0
  91. package/dist/files/web.d.ts +21 -0
  92. package/dist/files/web.d.ts.map +1 -0
  93. package/dist/files/web.js +82 -0
  94. package/dist/files/web.js.map +1 -0
  95. package/dist/index.d.ts +11 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +9 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/local-agent-host/capacitor.d.ts +5 -0
  100. package/dist/local-agent-host/capacitor.d.ts.map +1 -0
  101. package/dist/local-agent-host/capacitor.js +11 -0
  102. package/dist/local-agent-host/capacitor.js.map +1 -0
  103. package/dist/local-agent-host/index.d.ts +7 -0
  104. package/dist/local-agent-host/index.d.ts.map +1 -0
  105. package/dist/local-agent-host/index.js +10 -0
  106. package/dist/local-agent-host/index.js.map +1 -0
  107. package/dist/local-agent-host/interface.d.ts +62 -0
  108. package/dist/local-agent-host/interface.d.ts.map +1 -0
  109. package/dist/local-agent-host/interface.js +2 -0
  110. package/dist/local-agent-host/interface.js.map +1 -0
  111. package/dist/local-agent-host/tauri.d.ts +10 -0
  112. package/dist/local-agent-host/tauri.d.ts.map +1 -0
  113. package/dist/local-agent-host/tauri.js +38 -0
  114. package/dist/local-agent-host/tauri.js.map +1 -0
  115. package/dist/local-agent-host/web.d.ts +5 -0
  116. package/dist/local-agent-host/web.d.ts.map +1 -0
  117. package/dist/local-agent-host/web.js +11 -0
  118. package/dist/local-agent-host/web.js.map +1 -0
  119. package/dist/notifications/capacitor.d.ts +28 -0
  120. package/dist/notifications/capacitor.d.ts.map +1 -0
  121. package/dist/notifications/capacitor.js +39 -0
  122. package/dist/notifications/capacitor.js.map +1 -0
  123. package/dist/notifications/index.d.ts +7 -0
  124. package/dist/notifications/index.d.ts.map +1 -0
  125. package/dist/notifications/index.js +10 -0
  126. package/dist/notifications/index.js.map +1 -0
  127. package/dist/notifications/interface.d.ts +14 -0
  128. package/dist/notifications/interface.d.ts.map +1 -0
  129. package/dist/notifications/interface.js +2 -0
  130. package/dist/notifications/interface.js.map +1 -0
  131. package/dist/notifications/tauri.d.ts +12 -0
  132. package/dist/notifications/tauri.d.ts.map +1 -0
  133. package/dist/notifications/tauri.js +28 -0
  134. package/dist/notifications/tauri.js.map +1 -0
  135. package/dist/notifications/web.d.ts +15 -0
  136. package/dist/notifications/web.d.ts.map +1 -0
  137. package/dist/notifications/web.js +23 -0
  138. package/dist/notifications/web.js.map +1 -0
  139. package/dist/runtime.d.ts +3 -0
  140. package/dist/runtime.d.ts.map +1 -0
  141. package/dist/runtime.js +9 -0
  142. package/dist/runtime.js.map +1 -0
  143. package/dist/session-store/capacitor.d.ts +17 -0
  144. package/dist/session-store/capacitor.d.ts.map +1 -0
  145. package/dist/session-store/capacitor.js +21 -0
  146. package/dist/session-store/capacitor.js.map +1 -0
  147. package/dist/session-store/index.d.ts +8 -0
  148. package/dist/session-store/index.d.ts.map +1 -0
  149. package/dist/session-store/index.js +11 -0
  150. package/dist/session-store/index.js.map +1 -0
  151. package/dist/session-store/interface.d.ts +9 -0
  152. package/dist/session-store/interface.d.ts.map +1 -0
  153. package/dist/session-store/interface.js +2 -0
  154. package/dist/session-store/interface.js.map +1 -0
  155. package/dist/session-store/keychain.d.ts +13 -0
  156. package/dist/session-store/keychain.d.ts.map +1 -0
  157. package/dist/session-store/keychain.js +36 -0
  158. package/dist/session-store/keychain.js.map +1 -0
  159. package/dist/session-store/local.d.ts +10 -0
  160. package/dist/session-store/local.d.ts.map +1 -0
  161. package/dist/session-store/local.js +15 -0
  162. package/dist/session-store/local.js.map +1 -0
  163. package/dist/session-store/tauri.d.ts +10 -0
  164. package/dist/session-store/tauri.d.ts.map +1 -0
  165. package/dist/session-store/tauri.js +24 -0
  166. package/dist/session-store/tauri.js.map +1 -0
  167. package/dist/session-store/web.d.ts +5 -0
  168. package/dist/session-store/web.d.ts.map +1 -0
  169. package/dist/session-store/web.js +11 -0
  170. package/dist/session-store/web.js.map +1 -0
  171. package/package.json +95 -3
@@ -0,0 +1,74 @@
1
+ /**
2
+ * A device's signing identity; its private keys never leave the platform keystore. The
3
+ * signing key signs prompts with no user present. The presence key signs answers to an
4
+ * agent's own permission prompts and always needs Touch ID, Face ID or a passkey.
5
+ */
6
+ export interface DeviceKey {
7
+ /**
8
+ * Creates the keys on first use; stable afterwards. `presence: false` settles this device
9
+ * without a presence key. Throws `PresenceSetupCancelled`, keeping nothing, when the user
10
+ * dismisses the platform's prompt, so a later call can ask again.
11
+ */
12
+ publicKeys(enrollment: PresenceEnrollment, options?: {
13
+ readonly presence?: boolean;
14
+ }): Promise<DevicePublicKeys>;
15
+ /**
16
+ * `needed` while the next `publicKeys` would show a platform prompt (a passkey on the web),
17
+ * so the app can explain it first. Absent where creating the keys never prompts.
18
+ */
19
+ presenceSetup?(): Promise<"needed" | "done">;
20
+ sign(payload: Uint8Array, options: {
21
+ readonly presence: false;
22
+ }): Promise<DeviceSignature>;
23
+ sign(payload: Uint8Array, options: {
24
+ readonly presence: true;
25
+ }): Promise<PresenceSignature>;
26
+ }
27
+ export declare class PresenceSetupCancelled extends Error {
28
+ readonly name = "PresenceSetupCancelled";
29
+ constructor();
30
+ }
31
+ export interface PresenceEnrollment {
32
+ readonly rpId: string;
33
+ readonly userId: string;
34
+ readonly userName: string;
35
+ /** Server-issued, single use; the proof of possession signs it. */
36
+ readonly challenge: Uint8Array;
37
+ }
38
+ export interface DevicePublicKeys {
39
+ readonly signing: {
40
+ readonly keyId: string;
41
+ readonly publicKey: JsonWebKey;
42
+ };
43
+ /** Absent where the platform has no presence authenticator. */
44
+ readonly presence?: PresencePublicKey | undefined;
45
+ readonly proof: DeviceSignature;
46
+ }
47
+ export type PresencePublicKey = {
48
+ readonly format: "webauthn";
49
+ readonly credentialId: string;
50
+ readonly publicKey: JsonWebKey;
51
+ /** The attestation object, verified by the server once at enrollment. */
52
+ readonly attestation: string;
53
+ } | {
54
+ readonly format: "es256-raw";
55
+ readonly keyId: string;
56
+ readonly publicKey: JsonWebKey;
57
+ };
58
+ export interface DeviceSignature {
59
+ readonly keyId: string;
60
+ readonly presence: "none" | "user";
61
+ readonly format: "es256-raw" | "webauthn";
62
+ /** base64url */
63
+ readonly signature: string;
64
+ readonly authenticatorData?: string | undefined;
65
+ readonly clientDataJSON?: string | undefined;
66
+ }
67
+ declare const presenceBrand: unique symbol;
68
+ /** Only `sign(..., { presence: true })` produces one, so an ordinary signature never passes for it. */
69
+ export type PresenceSignature = DeviceSignature & {
70
+ readonly presence: "user";
71
+ readonly [presenceBrand]: true;
72
+ };
73
+ export {};
74
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/device-key/interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,UAAU,CACR,UAAU,EAAE,kBAAkB,EAC9B,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GACxC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7B;;;OAGG;IACH,aAAa,CAAC,IAAI,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC;IAC7C,IAAI,CACF,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;KAAE,GACpC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5B,IAAI,CACF,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,SAAkB,IAAI,4BAA4B;IAClD,cAEC;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC;IAC7E,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;CACjC;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAChC,CAAC;AAEN,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAAC;IAC1C,gBAAgB;IAChB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAE3C,uGAAuG;AACvG,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;CAChC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export class PresenceSetupCancelled extends Error {
2
+ name = "PresenceSetupCancelled";
3
+ constructor() {
4
+ super("The passkey was not created.");
5
+ }
6
+ }
7
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/device-key/interface.ts"],"names":[],"mappings":"AA8BA,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC7B,IAAI,GAAG,wBAAwB,CAAC;IAClD;QACE,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,38 @@
1
+ import type { DeviceKey } from "./interface.js";
2
+ export interface NativePublicKeys {
3
+ readonly signing: {
4
+ readonly keyId: string;
5
+ readonly publicKey: JsonWebKey;
6
+ };
7
+ readonly presence?: {
8
+ readonly keyId: string;
9
+ readonly publicKey: JsonWebKey;
10
+ };
11
+ readonly proof: {
12
+ readonly signature: string;
13
+ };
14
+ }
15
+ export interface NativeKeystore {
16
+ publicKeys(options: {
17
+ readonly presence: boolean;
18
+ readonly challenge: string;
19
+ }): Promise<NativePublicKeys>;
20
+ sign(options: {
21
+ readonly keyId: string;
22
+ readonly payload: string;
23
+ }): Promise<{
24
+ readonly signature: string;
25
+ }>;
26
+ }
27
+ export declare function nativeDeviceKey(keystore: NativeKeystore): DeviceKey;
28
+ interface Invoker {
29
+ invoke<T>(command: string, args?: Record<string, unknown>): Promise<T>;
30
+ }
31
+ /**
32
+ * Whether the shell carries a working native command: one an older generated project lacks
33
+ * ("not found") or a platform without a keystore refuses ("unsupported") is unavailable.
34
+ */
35
+ export declare function hasNativeCommand(load: () => Promise<Invoker>, command: string, args?: Record<string, unknown>): Promise<boolean>;
36
+ export declare function hasIosPlugin(): boolean;
37
+ export {};
38
+ //# sourceMappingURL=native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/device-key/native.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EAIV,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC;IAC/E,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,OAAO,EAAE;QAClB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE;QACZ,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7C;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,CAwDnE;AAED,UAAU,OAAO;IACf,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACxE;AAID;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAgB,YAAY,IAAI,OAAO,CAGtC"}
@@ -0,0 +1,67 @@
1
+ import { detectPlatform } from "../runtime.js";
2
+ import { encodeBase64url } from "./encoding.js";
3
+ export function nativeDeviceKey(keystore) {
4
+ let known;
5
+ const keysOf = () => (known ??= keystore.publicKeys({ presence: true, challenge: "" }));
6
+ const signature = async (keyId, presence, payload) => ({
7
+ keyId,
8
+ presence,
9
+ format: "es256-raw",
10
+ signature: (await keystore.sign({ keyId, payload: encodeBase64url(payload) }))
11
+ .signature,
12
+ });
13
+ async function sign(payload, options) {
14
+ const keys = await keysOf();
15
+ if (!options.presence)
16
+ return signature(keys.signing.keyId, "none", payload);
17
+ if (!keys.presence)
18
+ throw new Error("This device has no presence key.");
19
+ return (await signature(keys.presence.keyId, "user", payload));
20
+ }
21
+ return {
22
+ async publicKeys(enrollment) {
23
+ const pending = keystore.publicKeys({
24
+ presence: true,
25
+ challenge: encodeBase64url(enrollment.challenge),
26
+ });
27
+ known = pending;
28
+ const keys = await pending;
29
+ return {
30
+ signing: keys.signing,
31
+ presence: keys.presence && {
32
+ format: "es256-raw",
33
+ keyId: keys.presence.keyId,
34
+ publicKey: keys.presence.publicKey,
35
+ },
36
+ proof: {
37
+ keyId: keys.signing.keyId,
38
+ presence: "none",
39
+ format: "es256-raw",
40
+ signature: keys.proof.signature,
41
+ },
42
+ };
43
+ },
44
+ sign,
45
+ };
46
+ }
47
+ const UNAVAILABLE = /not found|unsupported/i;
48
+ /**
49
+ * Whether the shell carries a working native command: one an older generated project lacks
50
+ * ("not found") or a platform without a keystore refuses ("unsupported") is unavailable.
51
+ */
52
+ export async function hasNativeCommand(load, command, args) {
53
+ if (detectPlatform() !== "tauri")
54
+ return false;
55
+ try {
56
+ await (await load()).invoke(command, args);
57
+ return true;
58
+ }
59
+ catch (error) {
60
+ return !UNAVAILABLE.test(error instanceof Error ? error.message : String(error));
61
+ }
62
+ }
63
+ export function hasIosPlugin() {
64
+ const { Capacitor } = globalThis;
65
+ return detectPlatform() === "capacitor" && Capacitor?.getPlatform?.() === "ios";
66
+ }
67
+ //# sourceMappingURL=native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../../src/device-key/native.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { CapabilityAdapter } from "../capability.js";
2
+ import type { DeviceKey } from "./interface.js";
3
+ export interface TauriInvoke {
4
+ invoke<T>(command: string, args?: Record<string, unknown>): Promise<T>;
5
+ }
6
+ /** The generated `parlor_device_key_public` and `parlor_device_key_sign` commands, probed with a sign request for a key that cannot exist. */
7
+ export declare function tauriDeviceKey(load?: () => Promise<TauriInvoke>): CapabilityAdapter<DeviceKey>;
8
+ //# sourceMappingURL=tauri.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tauri.d.ts","sourceRoot":"","sources":["../../src/device-key/tauri.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACxE;AAED,8IAA8I;AAC9I,wBAAgB,cAAc,CAC5B,IAAI,GAAE,MAAM,OAAO,CAAC,WAAW,CAAwC,GACtE,iBAAiB,CAAC,SAAS,CAAC,CAe9B"}
@@ -0,0 +1,16 @@
1
+ import { hasNativeCommand, nativeDeviceKey } from "./native.js";
2
+ /** The generated `parlor_device_key_public` and `parlor_device_key_sign` commands, probed with a sign request for a key that cannot exist. */
3
+ export function tauriDeviceKey(load = () => import("@tauri-apps/api/core")) {
4
+ return {
5
+ platform: "tauri",
6
+ available: () => hasNativeCommand(load, "parlor_device_key_sign", { keyId: "", payload: "" }),
7
+ create: async () => {
8
+ const { invoke } = await load();
9
+ return nativeDeviceKey({
10
+ publicKeys: (options) => invoke("parlor_device_key_public", { ...options }),
11
+ sign: (options) => invoke("parlor_device_key_sign", { ...options }),
12
+ });
13
+ },
14
+ };
15
+ }
16
+ //# sourceMappingURL=tauri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tauri.js","sourceRoot":"","sources":["../../src/device-key/tauri.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAyB,MAAM,aAAa,CAAC;AAMvF,8IAA8I;AAC9I,MAAM,UAAU,cAAc,CAC5B,IAAI,GAA+B,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC;IAEvE,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,GAAG,EAAE,CACd,gBAAgB,CAAC,IAAI,EAAE,wBAAwB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC9E,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;YAChC,OAAO,eAAe,CAAC;gBACrB,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CACtB,MAAM,CAAmB,0BAA0B,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;gBACtE,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAChB,MAAM,CAAwB,wBAAwB,EAAE,EAAE,GAAG,OAAO,EAAE,CAAC;aAC1E,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { CapabilityAdapter } from "../capability.js";
2
+ import { type DeviceKey } from "./interface.js";
3
+ export interface WebDeviceKeyApis {
4
+ readonly subtle: SubtleCrypto | undefined;
5
+ readonly indexedDB: IDBFactory | undefined;
6
+ readonly credentials: CredentialsContainer | undefined;
7
+ /** Whether a platform authenticator (Touch ID, Windows Hello) can make the passkey. */
8
+ readonly platformAuthenticator?: (() => Promise<boolean>) | undefined;
9
+ }
10
+ export declare function webDeviceKey(apis?: () => WebDeviceKeyApis): CapabilityAdapter<DeviceKey>;
11
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/device-key/web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAO1D,OAAO,EACL,KAAK,SAAS,EAOf,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,uFAAuF;IACvF,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACvE;AAmQD,wBAAgB,YAAY,CAC1B,IAAI,GAAE,MAAM,gBAKV,GACD,iBAAiB,CAAC,SAAS,CAAC,CAoB9B"}
@@ -0,0 +1,210 @@
1
+ import { decodeBase64url, encodeBase64url, enrollmentBytes, publicPoint, } from "./encoding.js";
2
+ import { PresenceSetupCancelled, } from "./interface.js";
3
+ const hasPlatformAuthenticator = async () => {
4
+ try {
5
+ return ((await globalThis.PublicKeyCredential?.isUserVerifyingPlatformAuthenticatorAvailable?.()) ??
6
+ false);
7
+ }
8
+ catch {
9
+ return false;
10
+ }
11
+ };
12
+ const DATABASE = "parlor";
13
+ const STORE = "parlor-device";
14
+ const SIGNING = "signing";
15
+ const PRESENCE = "presence";
16
+ const CEREMONY_TIMEOUT_MS = 60_000;
17
+ const COSE_ES256 = -7;
18
+ const P256 = { name: "ECDSA", namedCurve: "P-256" };
19
+ const ES256 = { name: "ECDSA", hash: "SHA-256" };
20
+ function settled(request) {
21
+ return new Promise((resolve, reject) => {
22
+ request.onsuccess = () => resolve(request.result);
23
+ request.onerror = () => reject(request.error);
24
+ });
25
+ }
26
+ function openKeyStore(factory) {
27
+ const database = new Promise((resolve, reject) => {
28
+ const request = factory.open(DATABASE, 1);
29
+ request.onupgradeneeded = () => void request.result.createObjectStore(STORE);
30
+ request.onsuccess = () => resolve(request.result);
31
+ request.onerror = () => reject(request.error);
32
+ });
33
+ return {
34
+ async read(key) {
35
+ const tx = (await database).transaction(STORE, "readonly");
36
+ return (await settled(tx.objectStore(STORE).get(key)));
37
+ },
38
+ async keepFirst(key, value) {
39
+ const tx = (await database).transaction(STORE, "readwrite");
40
+ const store = tx.objectStore(STORE);
41
+ const existing = (await settled(store.get(key)));
42
+ if (existing !== undefined)
43
+ return existing;
44
+ await settled(store.put(value, key));
45
+ return value;
46
+ },
47
+ };
48
+ }
49
+ const isPublicKeyCredential = (credential) => credential?.type === "public-key";
50
+ const isAttestation = (response) => "attestationObject" in response;
51
+ const isAssertion = (response) => "signature" in response;
52
+ const NO_PRESENCE = { unavailable: true };
53
+ function createWebDeviceKey(subtle, factory, credentials, platformAuthenticator) {
54
+ const store = openKeyStore(factory);
55
+ const thumbprint = async (key) => {
56
+ const { crv, kty, x, y } = key;
57
+ const digest = await subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify({ crv, kty, x, y })));
58
+ return encodeBase64url(new Uint8Array(digest));
59
+ };
60
+ const signingIdentity = async () => {
61
+ const stored = await store.read(SIGNING);
62
+ const pair = stored ??
63
+ (await store.keepFirst(SIGNING, await subtle.generateKey(P256, false, ["sign", "verify"])));
64
+ const publicKey = publicPoint(await subtle.exportKey("jwk", pair.publicKey));
65
+ return { privateKey: pair.privateKey, publicKey, keyId: await thumbprint(publicKey) };
66
+ };
67
+ const signRaw = async (payload) => {
68
+ const { privateKey, keyId } = await signingIdentity();
69
+ const signature = await subtle.sign(ES256, privateKey, new Uint8Array(payload));
70
+ return {
71
+ keyId,
72
+ presence: "none",
73
+ format: "es256-raw",
74
+ signature: encodeBase64url(new Uint8Array(signature)),
75
+ };
76
+ };
77
+ const createPresence = async (container, enrollment) => {
78
+ try {
79
+ const credential = await container.create({
80
+ publicKey: {
81
+ rp: { id: enrollment.rpId, name: enrollment.rpId },
82
+ user: {
83
+ id: new TextEncoder().encode(enrollment.userId),
84
+ name: enrollment.userName,
85
+ displayName: enrollment.userName,
86
+ },
87
+ challenge: new Uint8Array(enrollment.challenge),
88
+ pubKeyCredParams: [{ type: "public-key", alg: COSE_ES256 }],
89
+ authenticatorSelection: {
90
+ authenticatorAttachment: "platform",
91
+ residentKey: "preferred",
92
+ userVerification: "required",
93
+ },
94
+ attestation: "none",
95
+ timeout: CEREMONY_TIMEOUT_MS,
96
+ },
97
+ });
98
+ if (!isPublicKeyCredential(credential) || !isAttestation(credential.response)) {
99
+ return { unavailable: true };
100
+ }
101
+ const spki = credential.response.getPublicKey();
102
+ if (spki === null)
103
+ return { unavailable: true };
104
+ const key = await subtle.importKey("spki", spki, P256, true, ["verify"]);
105
+ return {
106
+ credentialId: encodeBase64url(new Uint8Array(credential.rawId)),
107
+ rpId: enrollment.rpId,
108
+ publicKey: publicPoint(await subtle.exportKey("jwk", key)),
109
+ attestation: encodeBase64url(new Uint8Array(credential.response.attestationObject)),
110
+ };
111
+ }
112
+ catch (error) {
113
+ if (error instanceof Error && error.name === "NotAllowedError") {
114
+ throw new PresenceSetupCancelled();
115
+ }
116
+ return NO_PRESENCE;
117
+ }
118
+ };
119
+ const canCreatePresence = async () => credentials !== undefined && (await platformAuthenticator());
120
+ const presenceOf = async (enrollment, wanted) => {
121
+ const stored = (await store.read(PRESENCE)) ??
122
+ (await store.keepFirst(PRESENCE, credentials && wanted && (await canCreatePresence())
123
+ ? await createPresence(credentials, enrollment)
124
+ : NO_PRESENCE));
125
+ if ("unavailable" in stored)
126
+ return undefined;
127
+ return {
128
+ format: "webauthn",
129
+ credentialId: stored.credentialId,
130
+ publicKey: stored.publicKey,
131
+ attestation: stored.attestation,
132
+ };
133
+ };
134
+ const signPresence = async (payload) => {
135
+ const stored = await store.read(PRESENCE);
136
+ if (!credentials || !stored || "unavailable" in stored) {
137
+ throw new Error("This device has no presence key.");
138
+ }
139
+ const challenge = new Uint8Array(await subtle.digest("SHA-256", new Uint8Array(payload)));
140
+ const assertion = await credentials.get({
141
+ publicKey: {
142
+ challenge,
143
+ rpId: stored.rpId,
144
+ allowCredentials: [
145
+ { type: "public-key", id: decodeBase64url(stored.credentialId) },
146
+ ],
147
+ userVerification: "required",
148
+ timeout: CEREMONY_TIMEOUT_MS,
149
+ },
150
+ });
151
+ if (!isPublicKeyCredential(assertion) || !isAssertion(assertion.response)) {
152
+ throw new Error("The presence check did not complete.");
153
+ }
154
+ const { authenticatorData, clientDataJSON, signature } = assertion.response;
155
+ return {
156
+ keyId: stored.credentialId,
157
+ presence: "user",
158
+ format: "webauthn",
159
+ signature: encodeBase64url(new Uint8Array(signature)),
160
+ authenticatorData: encodeBase64url(new Uint8Array(authenticatorData)),
161
+ clientDataJSON: encodeBase64url(new Uint8Array(clientDataJSON)),
162
+ };
163
+ };
164
+ async function sign(payload, options) {
165
+ return options.presence ? signPresence(payload) : signRaw(payload);
166
+ }
167
+ return {
168
+ async publicKeys(enrollment, options) {
169
+ const { publicKey, keyId } = await signingIdentity();
170
+ const presence = await presenceOf(enrollment, options?.presence ?? true);
171
+ return {
172
+ signing: { keyId, publicKey },
173
+ presence,
174
+ proof: await signRaw(enrollmentBytes({
175
+ challenge: enrollment.challenge,
176
+ signing: publicKey,
177
+ presence,
178
+ })),
179
+ };
180
+ },
181
+ sign,
182
+ async presenceSetup() {
183
+ if (await store.read(PRESENCE))
184
+ return "done";
185
+ return (await canCreatePresence()) ? "needed" : "done";
186
+ },
187
+ };
188
+ }
189
+ export function webDeviceKey(apis = () => ({
190
+ subtle: globalThis.crypto?.subtle,
191
+ indexedDB: globalThis.indexedDB,
192
+ credentials: globalThis.navigator?.credentials,
193
+ platformAuthenticator: hasPlatformAuthenticator,
194
+ })) {
195
+ return {
196
+ platform: "web",
197
+ available: () => {
198
+ const { subtle, indexedDB } = apis();
199
+ return subtle !== undefined && indexedDB !== undefined;
200
+ },
201
+ create: () => {
202
+ const { subtle, indexedDB, credentials, platformAuthenticator } = apis();
203
+ if (!subtle || !indexedDB) {
204
+ throw new Error("This browser cannot keep a device key.");
205
+ }
206
+ return createWebDeviceKey(subtle, indexedDB, credentials, platformAuthenticator ?? hasPlatformAuthenticator);
207
+ },
208
+ };
209
+ }
210
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/device-key/web.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { CapabilityAdapter } from "../capability.js";
2
+ import type { Files } from "./interface.js";
3
+ /** `@capacitor/filesystem`, narrowed to writing base64 into the app's cache. */
4
+ export interface CapacitorCacheWriter {
5
+ writeToCache(path: string, base64: string): Promise<{
6
+ uri: string;
7
+ }>;
8
+ }
9
+ export interface CapacitorShareModule {
10
+ Share: {
11
+ share(options: {
12
+ title?: string;
13
+ files: string[];
14
+ }): Promise<unknown>;
15
+ };
16
+ }
17
+ /** Picks with the webview's own file input; saves through the share sheet ("Save to Files"). */
18
+ export declare function capacitorFiles(loadCache?: () => Promise<CapacitorCacheWriter>, loadShare?: () => Promise<CapacitorShareModule>, getDocument?: () => Document | undefined): CapabilityAdapter<Files>;
19
+ //# sourceMappingURL=capacitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capacitor.d.ts","sourceRoot":"","sources":["../../src/files/capacitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAI5C,gFAAgF;AAChF,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAUD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,EAAE,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;CAClF;AAcD,gGAAgG;AAChG,wBAAgB,cAAc,CAC5B,SAAS,GAAE,MAAM,OAAO,CAAC,oBAAoB,CAAmB,EAChE,SAAS,GAAE,MAAM,OAAO,CAAC,oBAAoB,CAAoC,EACjF,WAAW,GAAE,MAAM,QAAQ,GAAG,SAAqC,GAClE,iBAAiB,CAAC,KAAK,CAAC,CA0B1B"}
@@ -0,0 +1,47 @@
1
+ import { detectPlatform } from "../runtime.js";
2
+ import { bytesOf } from "./mime.js";
3
+ import { pickWithInput } from "./web.js";
4
+ const filesystemCache = async () => {
5
+ const { Filesystem, Directory } = await import("@capacitor/filesystem");
6
+ return {
7
+ writeToCache: (path, data) => Filesystem.writeFile({ path, data, directory: Directory.Cache, recursive: true }),
8
+ };
9
+ };
10
+ function base64Of(bytes) {
11
+ let binary = "";
12
+ for (let at = 0; at < bytes.length; at += 0x8000) {
13
+ binary += String.fromCharCode(...bytes.subarray(at, at + 0x8000));
14
+ }
15
+ return btoa(binary);
16
+ }
17
+ /** The share sheet reports a dismissal as an error whose message says it was canceled. */
18
+ const wasCancelled = (error) => error instanceof Error && /cancel/i.test(error.message);
19
+ /** Picks with the webview's own file input; saves through the share sheet ("Save to Files"). */
20
+ export function capacitorFiles(loadCache = filesystemCache, loadShare = () => import("@capacitor/share"), getDocument = () => globalThis.document) {
21
+ return {
22
+ platform: "capacitor",
23
+ available: () => detectPlatform() === "capacitor" && getDocument() !== undefined,
24
+ create: async () => {
25
+ const document = getDocument();
26
+ if (!document)
27
+ throw new Error("Files need a document");
28
+ const [cache, { Share }] = await Promise.all([loadCache(), loadShare()]);
29
+ return {
30
+ pick: (options) => pickWithInput(document, options),
31
+ save: async (data, options) => {
32
+ const { uri } = await cache.writeToCache(`parlor-save/${options.name}`, base64Of(await bytesOf(data)));
33
+ try {
34
+ await Share.share({ title: options.name, files: [uri] });
35
+ return "saved";
36
+ }
37
+ catch (error) {
38
+ if (wasCancelled(error))
39
+ return "cancelled";
40
+ throw error;
41
+ }
42
+ },
43
+ };
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=capacitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capacitor.js","sourceRoot":"","sources":["../../src/files/capacitor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAOzC,MAAM,eAAe,GAAG,KAAK,IAAmC,EAAE;IAChE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IACxE,OAAO;QACL,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAC3B,UAAU,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACpF,CAAC;AACJ,CAAC,CAAC;AAMF,SAAS,QAAQ,CAAC,KAAiB;IACjC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC;QACjD,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,0FAA0F;AAC1F,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,EAAE,CACtC,KAAK,YAAY,KAAK,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAE1D,gGAAgG;AAChG,MAAM,UAAU,cAAc,CAC5B,SAAS,GAAwC,eAAe,EAChE,SAAS,GAAwC,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,EACjF,WAAW,GAA+B,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ;IAEnE,OAAO;QACL,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,GAAG,EAAE,CAAC,cAAc,EAAE,KAAK,WAAW,IAAI,WAAW,EAAE,KAAK,SAAS;QAChF,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACxD,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;YACzE,OAAO;gBACL,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC;gBACnD,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;oBAC5B,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,KAAK,CAAC,YAAY,CACtC,eAAe,OAAO,CAAC,IAAI,EAAE,EAC7B,QAAQ,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAC9B,CAAC;oBACF,IAAI,CAAC;wBACH,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACzD,OAAO,OAAO,CAAC;oBACjB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,IAAI,YAAY,CAAC,KAAK,CAAC;4BAAE,OAAO,WAAW,CAAC;wBAC5C,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Files } from "./interface.js";
2
+ export type { Files, PickedFile, PickOptions, SaveOptions, SaveOutcome, } from "./interface.js";
3
+ export { capacitorFiles, type CapacitorCacheWriter, type CapacitorShareModule, } from "./capacitor.js";
4
+ export { tauriFiles, type TauriDialogModule, type TauriFsModule } from "./tauri.js";
5
+ export { webFiles, type WebFilesApis } from "./web.js";
6
+ export declare const files: import("../capability.js").CapabilityDefinition<Files>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,YAAY,EACV,KAAK,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAEvD,eAAO,MAAM,KAAK,wDAGhB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { platformAdapters } from "#adapters";
2
+ import { defineCapability } from "../capability.js";
3
+ export { capacitorFiles, } from "./capacitor.js";
4
+ export { tauriFiles } from "./tauri.js";
5
+ export { webFiles } from "./web.js";
6
+ export const files = defineCapability({
7
+ name: "files",
8
+ adapters: platformAdapters.files,
9
+ });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAUpD,OAAO,EACL,cAAc,GAGf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAA8C,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAqB,MAAM,UAAU,CAAC;AAEvD,MAAM,CAAC,MAAM,KAAK,GAAG,gBAAgB,CAAQ;IAC3C,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,gBAAgB,CAAC,KAAK;CACjC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface PickOptions {
2
+ /** What may be chosen, as an `<input accept>` takes it: `["image/*", ".pdf"]`. */
3
+ readonly accept?: readonly string[] | undefined;
4
+ readonly multiple?: boolean | undefined;
5
+ }
6
+ export interface PickedFile {
7
+ readonly name: string;
8
+ /** The MIME type, or `""` when the platform cannot tell. */
9
+ readonly type: string;
10
+ readonly size: number;
11
+ bytes(): Promise<Uint8Array>;
12
+ text(): Promise<string>;
13
+ }
14
+ export interface SaveOptions {
15
+ /** The file name to suggest. */
16
+ readonly name: string;
17
+ readonly type?: string | undefined;
18
+ }
19
+ export type SaveOutcome = "saved" | "cancelled";
20
+ export interface Files {
21
+ /** Asks the user for files; an empty list when they cancel. */
22
+ pick(options?: PickOptions): Promise<readonly PickedFile[]>;
23
+ /**
24
+ * Asks the user where to keep `data`: a save dialog where there is one, a download in a
25
+ * browser without, the share sheet on a phone.
26
+ */
27
+ save(data: Blob | Uint8Array | string, options: SaveOptions): Promise<SaveOutcome>;
28
+ }
29
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/files/interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7B,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhD,MAAM,WAAW,KAAK;IACpB,+DAA+D;IAC/D,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IAC5D;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACpF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/files/interface.ts"],"names":[],"mappings":""}