@wix/himalaya-cli 0.1591.0 → 0.1593.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/contacts/src/index.d.ts +52 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/files/src/index.d.ts +77 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/sdk-types/src/capabilities.generated.d.ts +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/audio-record.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/calendar.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/calls.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/contacts.mjs +91 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/files.mjs +58 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/location.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/motion.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/photos.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdk-types.mjs +2 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/tasks.mjs +2 -2
- package/dist/cli.mjs +63 -47
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/sdk-reference.json +122 -2
- package/guides/web-page-sdk-reference.md +2 -2
- package/package.json +2 -2
|
@@ -13,4 +13,56 @@ export declare function getPermissionStatus(): Promise<PermissionStatus>;
|
|
|
13
13
|
export declare function requestPermission(): Promise<PermissionStatus>;
|
|
14
14
|
/** Search contacts by name (requires read permission). [] when denied/no match. */
|
|
15
15
|
export declare function search(query: string, limit?: number): Promise<Contact[]>;
|
|
16
|
+
/** One labelled phone number or email address. `label` is free text ("work", "mobile"…);
|
|
17
|
+
* each host maps the common ones to its native label and keeps the rest as a custom label. */
|
|
18
|
+
export interface ContactField {
|
|
19
|
+
label?: string;
|
|
20
|
+
value: string;
|
|
21
|
+
}
|
|
22
|
+
/** A contact to create. At least one of `givenName`, `familyName` or `organization` must be
|
|
23
|
+
* non-blank; every list holds at most {@link MAX_CONTACT_ENTRIES} entries. */
|
|
24
|
+
export interface NewContact {
|
|
25
|
+
givenName?: string;
|
|
26
|
+
familyName?: string;
|
|
27
|
+
organization?: string;
|
|
28
|
+
phones?: ContactField[];
|
|
29
|
+
emails?: ContactField[];
|
|
30
|
+
urls?: string[];
|
|
31
|
+
note?: string;
|
|
32
|
+
}
|
|
33
|
+
/** The most entries `phones`, `emails` or `urls` may carry. */
|
|
34
|
+
export declare const MAX_CONTACT_ENTRIES = 20;
|
|
35
|
+
/** Why a create verb rejected. */
|
|
36
|
+
export type ContactsErrorCode = "invalid_contact" | "permission_denied" | "unavailable";
|
|
37
|
+
/** A create-verb rejection: an `Error` named "ContactsError" carrying a stable `code`. (A plain
|
|
38
|
+
* Error, not a subclass — Tier-5 bundles target an engine without class syntax.) Branch on
|
|
39
|
+
* `isContactsError(e) && e.code === "permission_denied"`. */
|
|
40
|
+
export interface ContactsError extends Error {
|
|
41
|
+
name: "ContactsError";
|
|
42
|
+
code: ContactsErrorCode;
|
|
43
|
+
}
|
|
44
|
+
/** Build a coded contacts rejection. */
|
|
45
|
+
export declare function contactsError(code: ContactsErrorCode, message?: string): ContactsError;
|
|
46
|
+
/** Whether `e` is a coded contacts rejection. */
|
|
47
|
+
export declare function isContactsError(e: unknown): e is ContactsError;
|
|
48
|
+
/** Validate and normalize a {@link NewContact}: strings trimmed, blank entries dropped, blank
|
|
49
|
+
* fields omitted. Throws `invalid_contact` when there is no name or organization, or a list
|
|
50
|
+
* holds more than {@link MAX_CONTACT_ENTRIES} entries. Every host re-checks the same rules. */
|
|
51
|
+
export declare function normalizeNewContact(contact: NewContact): NewContact;
|
|
52
|
+
/** Open the OS new-contact sheet prefilled with `contact` — the recommended way to save a
|
|
53
|
+
* contact: it needs NO contacts permission, because the user reviews and confirms the save.
|
|
54
|
+
* Resolves `{ saved: true }` when the user saved it, `{ saved: false }` on cancel. Web
|
|
55
|
+
* downloads a `.vcf` instead (and resolves `saved: true` once the download is handed off).
|
|
56
|
+
* Rejects `invalid_contact` (see {@link normalizeNewContact}) or `unavailable`. */
|
|
57
|
+
export declare function presentNewContact(contact: NewContact): Promise<{
|
|
58
|
+
saved: boolean;
|
|
59
|
+
}>;
|
|
60
|
+
/** Write `contact` straight into the address book and resolve its new `id`. Needs contacts
|
|
61
|
+
* WRITE permission — ask with {@link requestPermission} first; without it this rejects
|
|
62
|
+
* `permission_denied` (it never prompts). Rejects `invalid_contact`, or `unavailable` where
|
|
63
|
+
* the host has no address book (web). Prefer {@link presentNewContact} unless the app already
|
|
64
|
+
* holds the permission. */
|
|
65
|
+
export declare function add(contact: NewContact): Promise<{
|
|
66
|
+
id: string;
|
|
67
|
+
}>;
|
|
16
68
|
export declare const version = 1;
|
package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/files/src/index.d.ts
CHANGED
|
@@ -36,5 +36,80 @@ export declare function list(dirPath?: string): Promise<FileStat[]>;
|
|
|
36
36
|
export declare function remove(ref: FileHandle | string): Promise<void>;
|
|
37
37
|
/** Stat a path, or `null` if it doesn't exist (the existence check for handles). */
|
|
38
38
|
export declare function stat(path: string): Promise<FileStat | null>;
|
|
39
|
-
/**
|
|
40
|
-
|
|
39
|
+
/** Stable failure codes for the v3 verbs. Branch on `FilesError.code` (see `isFilesError`), never on
|
|
40
|
+
* the message text.
|
|
41
|
+
* - `invalid_url` — not an absolute `https:` URL, carries userinfo, or names a
|
|
42
|
+
* loopback / private-network / link-local host (checked on every
|
|
43
|
+
* redirect hop; natively also on the resolved DNS records).
|
|
44
|
+
* - `too_large` — the response is (or announces it will be) over `maxBytes`.
|
|
45
|
+
* - `http_error` — the server answered a non-2xx status (`status` is set).
|
|
46
|
+
* - `network` — the transfer failed (DNS, TLS, reset, CORS on web, …).
|
|
47
|
+
* - `unavailable` — this host cannot do it: no implementation for the verb, no save
|
|
48
|
+
* picker or volume reading to hand, or (`download`) the account signed
|
|
49
|
+
* out mid-transfer, so the file was not kept. */
|
|
50
|
+
export type FilesErrorCode = "invalid_url" | "too_large" | "http_error" | "network" | "unavailable";
|
|
51
|
+
/** A v3 verb failure: an `Error` whose `code` is stable and `message` is for humans.
|
|
52
|
+
* (A plain Error with fields, not a subclass — worker bundles target a syntax level
|
|
53
|
+
* without `class`.) Narrow with {@link isFilesError}. */
|
|
54
|
+
export interface FilesError extends Error {
|
|
55
|
+
name: "FilesError";
|
|
56
|
+
code: FilesErrorCode;
|
|
57
|
+
status?: number;
|
|
58
|
+
}
|
|
59
|
+
/** Build a FilesError. */
|
|
60
|
+
export declare function filesError(code: FilesErrorCode, message: string, status?: number): FilesError;
|
|
61
|
+
/** Whether `e` is a FilesError thrown by a v3 verb. */
|
|
62
|
+
export declare function isFilesError(e: unknown): e is FilesError;
|
|
63
|
+
/** The download cap when `maxBytes` is omitted: 100 MiB. */
|
|
64
|
+
export declare const DEFAULT_DOWNLOAD_MAX_BYTES: number;
|
|
65
|
+
/** The hard ceiling every arm clamps `maxBytes` to: 1 GiB. */
|
|
66
|
+
export declare const MAX_DOWNLOAD_BYTES: number;
|
|
67
|
+
/**
|
|
68
|
+
* Stream an `https:` URL straight into the sandbox and resolve with its FileHandle —
|
|
69
|
+
* the same shape `write` returns. The bytes never cross the worker bridge.
|
|
70
|
+
*
|
|
71
|
+
* - No credentials are attached: a fresh cookie-less session, no auth provider (the
|
|
72
|
+
* `presigned_upload` rule). Use it for public / pre-signed URLs.
|
|
73
|
+
* - `http:`, userinfo, and loopback / private-network / link-local hosts are refused
|
|
74
|
+
* (`invalid_url`); every redirect hop is re-checked before it is followed, and the
|
|
75
|
+
* native arms validate the resolved DNS records too.
|
|
76
|
+
* - `name` is the destination path relative to the files root (like `write`'s
|
|
77
|
+
* `path`); default `downloads/<last URL path segment>`. An existing file is replaced.
|
|
78
|
+
* - `maxBytes` defaults to 100 MiB (clamped to 1 GiB); over it the transfer is aborted (`too_large`) and
|
|
79
|
+
* nothing is left behind.
|
|
80
|
+
*/
|
|
81
|
+
export declare function download(url: string, opts?: {
|
|
82
|
+
name?: string;
|
|
83
|
+
maxBytes?: number;
|
|
84
|
+
}): Promise<FileHandle>;
|
|
85
|
+
/**
|
|
86
|
+
* Let the user save a sandbox file OUTSIDE the app through the OS save picker: the
|
|
87
|
+
* Files app on iOS, `NSSavePanel` on macOS, the Storage Access Framework on Android
|
|
88
|
+
* (no storage permission — the user picks the folder), a download on web. Resolves
|
|
89
|
+
* `{ exported: false }` when the user cancels.
|
|
90
|
+
*
|
|
91
|
+
* Exported as `export`, so call it as `files.export(handle)` (namespace import) or
|
|
92
|
+
* `import { export as exportFile } from "@wix/himalaya/files"`.
|
|
93
|
+
*/
|
|
94
|
+
declare function exportFile(file: FileHandle | string, opts?: {
|
|
95
|
+
suggestedName?: string;
|
|
96
|
+
mimeType?: string;
|
|
97
|
+
}): Promise<{
|
|
98
|
+
exported: boolean;
|
|
99
|
+
}>;
|
|
100
|
+
export { exportFile as export };
|
|
101
|
+
/** Storage figures, in bytes. `source` says what they measure:
|
|
102
|
+
* - `"device"` — the device volume (iOS `volumeAvailableCapacityForImportantUsage`,
|
|
103
|
+
* Android `StatFs`) and the bytes in this app's files root.
|
|
104
|
+
* - `"estimate"` — web: the origin's `navigator.storage.estimate()` quota/usage. */
|
|
105
|
+
export interface StorageInfo {
|
|
106
|
+
freeBytes: number;
|
|
107
|
+
totalBytes: number;
|
|
108
|
+
appBytes: number;
|
|
109
|
+
source: "device" | "estimate";
|
|
110
|
+
}
|
|
111
|
+
/** How much space is left before a large write, and how much this app's files use. */
|
|
112
|
+
export declare function storageInfo(): Promise<StorageInfo>;
|
|
113
|
+
/** Capability version, for bundles that gate on min binary version.
|
|
114
|
+
* 3 — `download`, `export`, `storageInfo`. */
|
|
115
|
+
export declare const version = 3;
|
|
@@ -9,9 +9,9 @@ export declare const CAPABILITY_REGISTRY: {
|
|
|
9
9
|
readonly calls: readonly ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"];
|
|
10
10
|
readonly camera: readonly ["capture", "pickDocument", "prepareImage", "scanQR"];
|
|
11
11
|
readonly clipboard: readonly ["hasImage", "hasText", "readText", "writeImage", "writeText"];
|
|
12
|
-
readonly contacts: readonly ["getPermissionStatus", "pick", "requestPermission", "search"];
|
|
12
|
+
readonly contacts: readonly ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"];
|
|
13
13
|
readonly file_picker: readonly ["pick", "pickDirectoryForExport"];
|
|
14
|
-
readonly files: readonly ["list", "readText", "remove", "stat", "write"];
|
|
14
|
+
readonly files: readonly ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"];
|
|
15
15
|
readonly godot: readonly ["loadPack", "release", "send"];
|
|
16
16
|
readonly haptic: readonly ["play", "sequence", "vibrate"];
|
|
17
17
|
readonly health: readonly ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"];
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -86,10 +86,99 @@ async function search(query, limit) {
|
|
|
86
86
|
const r = await dispatch("capability.contacts.search", params);
|
|
87
87
|
return Array.isArray(r?.items) ? r.items : [];
|
|
88
88
|
}
|
|
89
|
+
var MAX_CONTACT_ENTRIES = 20;
|
|
90
|
+
var CODES = ["invalid_contact", "permission_denied", "unavailable"];
|
|
91
|
+
function contactsError(code, message) {
|
|
92
|
+
const text = !message ? code : message.startsWith(code) ? message : `${code}: ${message}`;
|
|
93
|
+
const err = new Error(text);
|
|
94
|
+
err.name = "ContactsError";
|
|
95
|
+
err.code = code;
|
|
96
|
+
return err;
|
|
97
|
+
}
|
|
98
|
+
function isContactsError(e) {
|
|
99
|
+
return e instanceof Error && e.name === "ContactsError" && CODES.includes(e.code);
|
|
100
|
+
}
|
|
101
|
+
function codeOf(err) {
|
|
102
|
+
const msg = err instanceof Error ? err.message : String(err ?? "");
|
|
103
|
+
let best = null;
|
|
104
|
+
for (const c of CODES) {
|
|
105
|
+
const m = new RegExp(`(^|[^a-z_])${c}([^a-z_]|$)`).exec(msg);
|
|
106
|
+
if (!m) continue;
|
|
107
|
+
const at = m.index + m[1].length;
|
|
108
|
+
if (!best || at < best.at) best = { code: c, at };
|
|
109
|
+
}
|
|
110
|
+
return best?.code ?? null;
|
|
111
|
+
}
|
|
112
|
+
var trimmed = (v) => typeof v === "string" ? v.trim() : "";
|
|
113
|
+
function fields(list, name) {
|
|
114
|
+
if (list == null) return [];
|
|
115
|
+
if (!Array.isArray(list)) throw contactsError("invalid_contact", `${name} must be an array`);
|
|
116
|
+
if (list.length > MAX_CONTACT_ENTRIES) throw contactsError("invalid_contact", `${name} holds more than ${MAX_CONTACT_ENTRIES} entries`);
|
|
117
|
+
const out = [];
|
|
118
|
+
for (const entry of list) {
|
|
119
|
+
const value = trimmed(entry?.value);
|
|
120
|
+
if (!value) continue;
|
|
121
|
+
const label = trimmed(entry.label);
|
|
122
|
+
out.push(label ? { label, value } : { value });
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
function normalizeNewContact(contact) {
|
|
127
|
+
if (contact == null || typeof contact !== "object") throw contactsError("invalid_contact", "contact must be an object");
|
|
128
|
+
const out = {};
|
|
129
|
+
const givenName = trimmed(contact.givenName);
|
|
130
|
+
const familyName = trimmed(contact.familyName);
|
|
131
|
+
const organization = trimmed(contact.organization);
|
|
132
|
+
if (!givenName && !familyName && !organization) {
|
|
133
|
+
throw contactsError("invalid_contact", "a contact needs a givenName, familyName or organization");
|
|
134
|
+
}
|
|
135
|
+
if (givenName) out.givenName = givenName;
|
|
136
|
+
if (familyName) out.familyName = familyName;
|
|
137
|
+
if (organization) out.organization = organization;
|
|
138
|
+
const phones = fields(contact.phones, "phones");
|
|
139
|
+
if (phones.length) out.phones = phones;
|
|
140
|
+
const emails = fields(contact.emails, "emails");
|
|
141
|
+
if (emails.length) out.emails = emails;
|
|
142
|
+
if (contact.urls != null) {
|
|
143
|
+
if (!Array.isArray(contact.urls)) throw contactsError("invalid_contact", "urls must be an array");
|
|
144
|
+
if (contact.urls.length > MAX_CONTACT_ENTRIES) throw contactsError("invalid_contact", `urls holds more than ${MAX_CONTACT_ENTRIES} entries`);
|
|
145
|
+
const urls = contact.urls.map(trimmed).filter((u) => u.length > 0);
|
|
146
|
+
if (urls.length) out.urls = urls;
|
|
147
|
+
}
|
|
148
|
+
const note = trimmed(contact.note);
|
|
149
|
+
if (note) out.note = note;
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
async function coded(call) {
|
|
153
|
+
try {
|
|
154
|
+
return await call();
|
|
155
|
+
} catch (err) {
|
|
156
|
+
const code = codeOf(err);
|
|
157
|
+
if (code) throw contactsError(code, err instanceof Error ? err.message : String(err));
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function presentNewContact(contact) {
|
|
162
|
+
const wire = { contact: JSON.stringify(normalizeNewContact(contact)) };
|
|
163
|
+
const r = await coded(() => dispatch("capability.contacts.presentNewContact", wire));
|
|
164
|
+
return { saved: r?.saved === true };
|
|
165
|
+
}
|
|
166
|
+
async function add(contact) {
|
|
167
|
+
const wire = { contact: JSON.stringify(normalizeNewContact(contact)) };
|
|
168
|
+
const r = await coded(() => dispatch("capability.contacts.add", wire));
|
|
169
|
+
if (typeof r?.id !== "string" || r.id.length === 0) throw contactsError("unavailable", "the host returned no contact id");
|
|
170
|
+
return { id: r.id };
|
|
171
|
+
}
|
|
89
172
|
var version = 1;
|
|
90
173
|
export {
|
|
174
|
+
MAX_CONTACT_ENTRIES,
|
|
175
|
+
add,
|
|
176
|
+
contactsError,
|
|
91
177
|
getPermissionStatus,
|
|
178
|
+
isContactsError,
|
|
179
|
+
normalizeNewContact,
|
|
92
180
|
pick,
|
|
181
|
+
presentNewContact,
|
|
93
182
|
requestPermission,
|
|
94
183
|
search,
|
|
95
184
|
version
|
|
@@ -61,13 +61,70 @@ async function stat(path) {
|
|
|
61
61
|
const r = await dispatch("capability.files.stat", { path });
|
|
62
62
|
return r?.stat ?? null;
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
function filesError(code, message, status) {
|
|
65
|
+
const e = new Error(message);
|
|
66
|
+
e.name = "FilesError";
|
|
67
|
+
e.code = code;
|
|
68
|
+
if (typeof status === "number") e.status = status;
|
|
69
|
+
return e;
|
|
70
|
+
}
|
|
71
|
+
function isFilesError(e) {
|
|
72
|
+
return e instanceof Error && e.name === "FilesError" && typeof e.code === "string";
|
|
73
|
+
}
|
|
74
|
+
var ERROR_CODES = ["invalid_url", "too_large", "http_error", "network", "unavailable"];
|
|
75
|
+
function throwIfError(verb, r) {
|
|
76
|
+
const e = r?.error;
|
|
77
|
+
if (e == null) return;
|
|
78
|
+
const obj = typeof e === "object" ? e : { message: e };
|
|
79
|
+
const code = ERROR_CODES.includes(obj.code) ? obj.code : "network";
|
|
80
|
+
const message = typeof obj.message === "string" && obj.message ? obj.message : code;
|
|
81
|
+
throw filesError(code, `files.${verb}: ${message}`, typeof obj.status === "number" ? obj.status : void 0);
|
|
82
|
+
}
|
|
83
|
+
var DEFAULT_DOWNLOAD_MAX_BYTES = 100 * 1024 * 1024;
|
|
84
|
+
var MAX_DOWNLOAD_BYTES = 1024 * 1024 * 1024;
|
|
85
|
+
async function download(url, opts) {
|
|
86
|
+
const params = { url };
|
|
87
|
+
if (opts?.name) params.name = opts.name;
|
|
88
|
+
if (typeof opts?.maxBytes === "number" && opts.maxBytes > 0) params.maxBytes = String(Math.floor(opts.maxBytes));
|
|
89
|
+
const r = await dispatch("capability.files.download", params);
|
|
90
|
+
throwIfError("download", r);
|
|
91
|
+
return toHandle(r, opts?.name ?? "download");
|
|
92
|
+
}
|
|
93
|
+
async function exportFile(file, opts) {
|
|
94
|
+
const params = { uri: refToPath(file) };
|
|
95
|
+
if (typeof file !== "string" && file.ownerScope) params.ownerScope = file.ownerScope;
|
|
96
|
+
if (opts?.suggestedName) params.suggestedName = opts.suggestedName;
|
|
97
|
+
const mimeType = opts?.mimeType ?? (typeof file !== "string" ? file.mimeType : void 0);
|
|
98
|
+
if (mimeType) params.mimeType = mimeType;
|
|
99
|
+
const r = await dispatch("capability.files.export", params);
|
|
100
|
+
throwIfError("export", r);
|
|
101
|
+
return { exported: r?.exported === true };
|
|
102
|
+
}
|
|
103
|
+
async function storageInfo() {
|
|
104
|
+
const r = await dispatch("capability.files.storageInfo", {});
|
|
105
|
+
throwIfError("storageInfo", r);
|
|
106
|
+
const n = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0;
|
|
107
|
+
return {
|
|
108
|
+
freeBytes: n(r?.freeBytes),
|
|
109
|
+
totalBytes: n(r?.totalBytes),
|
|
110
|
+
appBytes: n(r?.appBytes),
|
|
111
|
+
source: r?.source === "estimate" ? "estimate" : "device"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
var version = 3;
|
|
65
115
|
export {
|
|
116
|
+
DEFAULT_DOWNLOAD_MAX_BYTES,
|
|
117
|
+
MAX_DOWNLOAD_BYTES,
|
|
118
|
+
download,
|
|
119
|
+
exportFile as export,
|
|
120
|
+
filesError,
|
|
121
|
+
isFilesError,
|
|
66
122
|
list,
|
|
67
123
|
readBase64,
|
|
68
124
|
readText,
|
|
69
125
|
remove,
|
|
70
126
|
stat,
|
|
127
|
+
storageInfo,
|
|
71
128
|
version,
|
|
72
129
|
write
|
|
73
130
|
};
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -9,9 +9,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
9
9
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
10
10
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
11
11
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
12
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
12
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
13
13
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
14
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
14
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
15
15
|
"godot": ["loadPack", "release", "send"],
|
|
16
16
|
"haptic": ["play", "sequence", "vibrate"],
|
|
17
17
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|
|
@@ -24,9 +24,9 @@ var CAPABILITY_REGISTRY = {
|
|
|
24
24
|
"calls": ["answer", "availability", "getPermissionStatus", "getState", "hangup", "listCalls", "offer", "receiveSignal", "reject", "requestPermission", "setMuted", "setRingback", "setSpeaker", "signalNext", "signalStart", "signalStop", "start", "subscribeEvents"],
|
|
25
25
|
"camera": ["capture", "pickDocument", "prepareImage", "scanQR"],
|
|
26
26
|
"clipboard": ["hasImage", "hasText", "readText", "writeImage", "writeText"],
|
|
27
|
-
"contacts": ["getPermissionStatus", "pick", "requestPermission", "search"],
|
|
27
|
+
"contacts": ["add", "getPermissionStatus", "pick", "presentNewContact", "requestPermission", "search"],
|
|
28
28
|
"file_picker": ["pick", "pickDirectoryForExport"],
|
|
29
|
-
"files": ["list", "readText", "remove", "stat", "write"],
|
|
29
|
+
"files": ["download", "export", "list", "readText", "remove", "stat", "storageInfo", "write"],
|
|
30
30
|
"godot": ["loadPack", "release", "send"],
|
|
31
31
|
"haptic": ["play", "sequence", "vibrate"],
|
|
32
32
|
"health": ["availability", "getPermissionStatus", "query", "requestPermission", "saveWorkout"],
|