@monimesl/dot-dash 0.1.0-alpha.21 → 0.1.0-alpha.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +384 -56
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +487 -60
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,11 +1,124 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_DASH_API_VERSION, HostError, HostError as DashError, callHost, createHostRequest, offersDashApiVersion } from "@monimesl/dot-core";
|
|
3
|
+
//#region src/api-versions.ts
|
|
4
|
+
const DASH_API_VERSION = "1.0";
|
|
5
|
+
const DASH_API_SINCE = {
|
|
6
|
+
"account.readProfile": "1.0",
|
|
7
|
+
"contacts.pickPhone": "1.0",
|
|
8
|
+
"crypto.hmac": "1.0",
|
|
9
|
+
"crypto.randomBytes": "1.0",
|
|
10
|
+
"crypto.randomUUID": "1.0",
|
|
11
|
+
"crypto.sha256": "1.0",
|
|
12
|
+
"crypto.sha512": "1.0",
|
|
13
|
+
"dot.close": "1.0",
|
|
14
|
+
"media.pickFile": "1.0",
|
|
15
|
+
"media.pickPhoto": "1.0",
|
|
16
|
+
"media.scanCode": "1.0",
|
|
17
|
+
"network.http.download": "1.0",
|
|
18
|
+
"network.http.request": "1.0",
|
|
19
|
+
"network.http.upload": "1.0",
|
|
20
|
+
"network.status": "1.0",
|
|
21
|
+
"storage.cache.clear": "1.0",
|
|
22
|
+
"storage.cache.exists": "1.0",
|
|
23
|
+
"storage.cache.get": "1.0",
|
|
24
|
+
"storage.cache.keys": "1.0",
|
|
25
|
+
"storage.cache.remove": "1.0",
|
|
26
|
+
"storage.cache.set": "1.0",
|
|
27
|
+
"storage.file.copy": "1.0",
|
|
28
|
+
"storage.file.createFolder": "1.0",
|
|
29
|
+
"storage.file.list": "1.0",
|
|
30
|
+
"storage.file.move": "1.0",
|
|
31
|
+
"storage.file.open": "1.0",
|
|
32
|
+
"storage.file.read": "1.0",
|
|
33
|
+
"storage.file.remove": "1.0",
|
|
34
|
+
"storage.file.save": "1.0",
|
|
35
|
+
"storage.file.stat": "1.0",
|
|
36
|
+
"storage.file.usage": "1.0",
|
|
37
|
+
"storage.file.write": "1.0",
|
|
38
|
+
"storage.secret.clear": "1.0",
|
|
39
|
+
"storage.secret.get": "1.0",
|
|
40
|
+
"storage.secret.remove": "1.0",
|
|
41
|
+
"storage.secret.set": "1.0",
|
|
42
|
+
"system.brightness": "1.0",
|
|
43
|
+
"system.copyText": "1.0",
|
|
44
|
+
"system.delay": "1.0",
|
|
45
|
+
"system.dial": "1.0",
|
|
46
|
+
"system.info": "1.0",
|
|
47
|
+
"system.keepAwake": "1.0",
|
|
48
|
+
"system.openUrl": "1.0",
|
|
49
|
+
"system.share": "1.0",
|
|
50
|
+
"system.torch": "1.0",
|
|
51
|
+
"system.vibrate": "1.0",
|
|
52
|
+
"ui.alert": "1.0",
|
|
53
|
+
"ui.pickDate": "1.0",
|
|
54
|
+
"ui.pickTime": "1.0"
|
|
55
|
+
};
|
|
56
|
+
let hostApiVersions = [DEFAULT_DASH_API_VERSION];
|
|
57
|
+
let dotMinApiVersion;
|
|
58
|
+
const checkedFeatures = /* @__PURE__ */ new Set();
|
|
59
|
+
const warnedFeatures = /* @__PURE__ */ new Set();
|
|
60
|
+
function useHostDashApiVersions(versions) {
|
|
61
|
+
hostApiVersions = versions;
|
|
62
|
+
}
|
|
63
|
+
function warnAboveDashApiVersion(minApiVersion) {
|
|
64
|
+
dotMinApiVersion = minApiVersion;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Whether the Dash the dot runs in has `feature`: a call, such as "contacts.pickPhone", or a field
|
|
68
|
+
* added to a call later. Check it before using one that's newer than the dot's minApiVersion.
|
|
69
|
+
* @since 1.0
|
|
70
|
+
*/
|
|
71
|
+
function supports(feature) {
|
|
72
|
+
checkedFeatures.add(feature);
|
|
73
|
+
const since = sinceOf(feature);
|
|
74
|
+
return since !== void 0 && offersDashApiVersion(hostApiVersions, since);
|
|
75
|
+
}
|
|
76
|
+
function warnIfNewerThanDot(method, params) {
|
|
77
|
+
if (dotMinApiVersion === void 0) return;
|
|
78
|
+
const callName = method.replace(/^dash\./, "");
|
|
79
|
+
for (const feature of [callName, ...fieldsSent(callName, params)]) {
|
|
80
|
+
const since = sinceOf(feature);
|
|
81
|
+
if (since === void 0) continue;
|
|
82
|
+
if (checkedFeatures.has(feature) || warnedFeatures.has(feature)) continue;
|
|
83
|
+
if (offersDashApiVersion([dotMinApiVersion], since)) continue;
|
|
84
|
+
warnedFeatures.add(feature);
|
|
85
|
+
console.warn(`dash.${feature} came in Dash API ${since}, but this dot's minApiVersion is ${dotMinApiVersion}, so older Dash doesn't have it. Raise "minApiVersion" in dot.json, or check dash.supports('${feature}') first.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function sinceOf(feature) {
|
|
89
|
+
const table = DASH_API_SINCE;
|
|
90
|
+
return Object.hasOwn(table, feature) ? table[feature] : void 0;
|
|
91
|
+
}
|
|
92
|
+
function fieldsSent(callName, params) {
|
|
93
|
+
if (typeof params !== "object" || params === null) return [];
|
|
94
|
+
return Object.keys(params).map((field) => `${callName}.${field}`).filter((feature) => sinceOf(feature) !== void 0);
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
3
97
|
//#region src/call.ts
|
|
4
98
|
function call(method, params, options = {}) {
|
|
99
|
+
warnIfNewerThanDot(method, params);
|
|
5
100
|
return callHost(method, params, options);
|
|
6
101
|
}
|
|
7
102
|
//#endregion
|
|
103
|
+
//#region src/account/index.ts
|
|
104
|
+
var account_exports = /* @__PURE__ */ __exportAll({ readProfile: () => readProfile });
|
|
105
|
+
/**
|
|
106
|
+
* The person signed in to Dash: their full name, and a token that names them in this dot. Needs the
|
|
107
|
+
* `account` permission. Rejects with `invalid` for a nonce that's empty or longer than 128
|
|
108
|
+
* characters, and with `failed` when no one is signed in.
|
|
109
|
+
* @since 1.0
|
|
110
|
+
*/
|
|
111
|
+
function readProfile(options, callOptions) {
|
|
112
|
+
return call("dash.account.readProfile", { nonce: options.nonce }, callOptions);
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
8
115
|
//#region src/contacts/pick-phone.ts
|
|
116
|
+
/**
|
|
117
|
+
* Shows the phone's contacts so the person chooses one phone number, such as who to send money to.
|
|
118
|
+
* Needs the `contacts` permission. The dot sees only the chosen contact. Rejects with `cancelled` if
|
|
119
|
+
* the person closes it.
|
|
120
|
+
* @since 1.0
|
|
121
|
+
*/
|
|
9
122
|
function pickPhone(callOptions) {
|
|
10
123
|
return call("dash.contacts.pickPhone", {}, callOptions);
|
|
11
124
|
}
|
|
@@ -13,57 +126,169 @@ function pickPhone(callOptions) {
|
|
|
13
126
|
//#region src/contacts/index.ts
|
|
14
127
|
var contacts_exports = /* @__PURE__ */ __exportAll({ pickPhone: () => pickPhone });
|
|
15
128
|
//#endregion
|
|
129
|
+
//#region src/crypto/index.ts
|
|
130
|
+
var crypto_exports = /* @__PURE__ */ __exportAll({
|
|
131
|
+
hmac: () => hmac,
|
|
132
|
+
randomBytes: () => randomBytes,
|
|
133
|
+
randomUUID: () => randomUUID,
|
|
134
|
+
sha256: () => sha256,
|
|
135
|
+
sha512: () => sha512
|
|
136
|
+
});
|
|
137
|
+
/** @since 1.0 */
|
|
138
|
+
function sha256(data, options = {}, callOptions) {
|
|
139
|
+
return call("dash.crypto.sha256", wireInput(data, options), callOptions);
|
|
140
|
+
}
|
|
141
|
+
/** @since 1.0 */
|
|
142
|
+
function sha512(data, options = {}, callOptions) {
|
|
143
|
+
return call("dash.crypto.sha512", wireInput(data, options), callOptions);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Signs `data` with `key`, as HMAC-SHA256 or HMAC-SHA512, such as
|
|
147
|
+
* `hmac({ algorithm: 'sha256', key, data })`.
|
|
148
|
+
* @since 1.0
|
|
149
|
+
*/
|
|
150
|
+
function hmac(options, callOptions) {
|
|
151
|
+
const wireKey = valueAndEncoding(options.key);
|
|
152
|
+
return call("dash.crypto.hmac", {
|
|
153
|
+
...wireInput(options.data, options),
|
|
154
|
+
algorithm: options.algorithm,
|
|
155
|
+
key: wireKey.value,
|
|
156
|
+
keyEncoding: wireKey.encoding
|
|
157
|
+
}, callOptions);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* `count` secure random bytes, from 1 to 1024, such as for a nonce.
|
|
161
|
+
* @since 1.0
|
|
162
|
+
*/
|
|
163
|
+
function randomBytes(count, options = {}, callOptions) {
|
|
164
|
+
return call("dash.crypto.randomBytes", {
|
|
165
|
+
count,
|
|
166
|
+
as: outputEncoding(options)
|
|
167
|
+
}, callOptions);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* A random version 4 UUID, such as "3f0e5c3a-6d1b-4c8e-9a2f-1b7d4e6a9c05".
|
|
171
|
+
* @since 1.0
|
|
172
|
+
*/
|
|
173
|
+
function randomUUID(callOptions) {
|
|
174
|
+
return call("dash.crypto.randomUUID", {}, callOptions);
|
|
175
|
+
}
|
|
176
|
+
function wireInput(data, options) {
|
|
177
|
+
const { value, encoding } = valueAndEncoding(data);
|
|
178
|
+
return {
|
|
179
|
+
data: value,
|
|
180
|
+
dataEncoding: encoding,
|
|
181
|
+
as: outputEncoding(options)
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function outputEncoding(options) {
|
|
185
|
+
return options.as ?? "hex";
|
|
186
|
+
}
|
|
187
|
+
function valueAndEncoding(input) {
|
|
188
|
+
if (typeof input === "string") return {
|
|
189
|
+
value: input,
|
|
190
|
+
encoding: "text"
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
value: input.base64,
|
|
194
|
+
encoding: "base64"
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/dot/index.ts
|
|
199
|
+
var dot_exports = /* @__PURE__ */ __exportAll({ close: () => close });
|
|
200
|
+
/**
|
|
201
|
+
* Closes the dot, as going back from its first page does. Calls still running are cancelled.
|
|
202
|
+
* @since 1.0
|
|
203
|
+
*/
|
|
204
|
+
function close(callOptions) {
|
|
205
|
+
return call("dash.dot.close", {}, callOptions);
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/media/pick-file.ts
|
|
209
|
+
/**
|
|
210
|
+
* Lets the person choose a file from their phone, of at most 25 MB. Needs the `files` permission.
|
|
211
|
+
* Rejects with `cancelled` if they close the picker, and with `invalid` for a larger file. Like a
|
|
212
|
+
* download, it lasts until the dot closes, so `dash.storage.file.save` it to keep it.
|
|
213
|
+
* @since 1.0
|
|
214
|
+
*/
|
|
215
|
+
function pickFile(options = {}, callOptions) {
|
|
216
|
+
const params = {};
|
|
217
|
+
if (options.types) params.types = options.types;
|
|
218
|
+
return call("dash.media.pickFile", params, callOptions);
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
16
221
|
//#region src/media/pick-photo.ts
|
|
222
|
+
/**
|
|
223
|
+
* Lets the person choose a photo or take one. Resolves with it as a JPEG of at most 2048 pixels on its
|
|
224
|
+
* longest side, without its location or other details. Rejects with `cancelled` if they close the
|
|
225
|
+
* picker, and with `unsupported` on a device without a camera. Save it with `dash.storage.file.save`
|
|
226
|
+
* to keep it after the dot closes.
|
|
227
|
+
* @since 1.0
|
|
228
|
+
*/
|
|
17
229
|
function pickPhoto(options, callOptions) {
|
|
18
230
|
return call("dash.media.pickPhoto", { source: options.source }, callOptions);
|
|
19
231
|
}
|
|
20
232
|
//#endregion
|
|
21
233
|
//#region src/media/scan-code.ts
|
|
234
|
+
/**
|
|
235
|
+
* Opens Dash's scanner until it reads a QR code. Needs the `camera` permission. Rejects with
|
|
236
|
+
* `cancelled` if the person closes it, and with `unsupported` where Dash has no scanner.
|
|
237
|
+
* @since 1.0
|
|
238
|
+
*/
|
|
22
239
|
function scanCode(callOptions) {
|
|
23
240
|
return call("dash.media.scanCode", {}, callOptions);
|
|
24
241
|
}
|
|
25
242
|
//#endregion
|
|
26
243
|
//#region src/media/index.ts
|
|
27
244
|
var media_exports = /* @__PURE__ */ __exportAll({
|
|
245
|
+
pickFile: () => pickFile,
|
|
28
246
|
pickPhoto: () => pickPhoto,
|
|
29
247
|
scanCode: () => scanCode
|
|
30
248
|
});
|
|
31
249
|
//#endregion
|
|
32
|
-
//#region src/files.ts
|
|
33
|
-
function fileId(file) {
|
|
34
|
-
return typeof file === "string" ? file : file.id;
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
250
|
//#region src/network/http.ts
|
|
38
251
|
var http_exports = /* @__PURE__ */ __exportAll({
|
|
39
252
|
download: () => download,
|
|
40
253
|
request: () => request,
|
|
41
254
|
upload: () => upload
|
|
42
255
|
});
|
|
256
|
+
/**
|
|
257
|
+
* Like fetch, resolves with any response, even a 404. An object body is sent as JSON.
|
|
258
|
+
* @since 1.0
|
|
259
|
+
*/
|
|
43
260
|
function request(options, callOptions) {
|
|
44
|
-
const { as, ...request } = options;
|
|
45
|
-
return readBody(call("dash.network.http.request", wireRequest(request,
|
|
261
|
+
const { as: readAs, ...request } = options;
|
|
262
|
+
return readBody(call("dash.network.http.request", wireRequest(request, readAs), callOptions), readAs);
|
|
46
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Saves a 2xx response's body, up to 256 MB, to a temporary file.
|
|
266
|
+
* @since 1.0
|
|
267
|
+
*/
|
|
47
268
|
function download(options, callOptions) {
|
|
48
269
|
return call("dash.network.http.download", wireRequest(options), callOptions);
|
|
49
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Sends the dot's files as a multipart form.
|
|
273
|
+
* @since 1.0
|
|
274
|
+
*/
|
|
50
275
|
function upload(options, callOptions) {
|
|
51
|
-
const { as, ...request } = options;
|
|
52
|
-
const files = request.files.map((
|
|
53
|
-
...
|
|
54
|
-
file:
|
|
276
|
+
const { as: readAs, ...request } = options;
|
|
277
|
+
const files = request.files.map((upload) => ({
|
|
278
|
+
...upload,
|
|
279
|
+
file: upload.file.id
|
|
55
280
|
}));
|
|
56
281
|
const params = {
|
|
57
282
|
...request,
|
|
58
283
|
files
|
|
59
284
|
};
|
|
60
|
-
if (
|
|
61
|
-
return readBody(call("dash.network.http.upload", params, callOptions),
|
|
285
|
+
if (readAs === "json") params.headers = withDefaultHeader(request.headers, "Accept", "application/json");
|
|
286
|
+
return readBody(call("dash.network.http.upload", params, callOptions), readAs);
|
|
62
287
|
}
|
|
63
|
-
function wireRequest(request,
|
|
288
|
+
function wireRequest(request, readAs) {
|
|
64
289
|
let headers = request.headers;
|
|
65
290
|
let body;
|
|
66
|
-
if (
|
|
291
|
+
if (readAs === "json") headers = withDefaultHeader(headers, "Accept", "application/json");
|
|
67
292
|
if (typeof request.body === "string") body = request.body;
|
|
68
293
|
else if (request.body !== void 0) {
|
|
69
294
|
headers = withDefaultHeader(headers, "Content-Type", "application/json");
|
|
@@ -76,15 +301,16 @@ function wireRequest(request, as) {
|
|
|
76
301
|
};
|
|
77
302
|
}
|
|
78
303
|
function withDefaultHeader(headers, name, value) {
|
|
304
|
+
if (headers === void 0) return { [name]: value };
|
|
79
305
|
const lowerName = name.toLowerCase();
|
|
80
|
-
if (
|
|
306
|
+
if (Object.keys(headers).some((existing) => existing.toLowerCase() === lowerName)) return headers;
|
|
81
307
|
return {
|
|
82
308
|
...headers,
|
|
83
309
|
[name]: value
|
|
84
310
|
};
|
|
85
311
|
}
|
|
86
|
-
function readBody(response,
|
|
87
|
-
if (
|
|
312
|
+
function readBody(response, readAs) {
|
|
313
|
+
if (readAs !== "json") return response;
|
|
88
314
|
const parsed = response.then((result) => ({
|
|
89
315
|
...result,
|
|
90
316
|
body: parseJson(result)
|
|
@@ -96,11 +322,15 @@ function parseJson({ status, statusText, body }) {
|
|
|
96
322
|
return JSON.parse(body);
|
|
97
323
|
} catch (error) {
|
|
98
324
|
const message = error instanceof Error ? error.message : String(error);
|
|
99
|
-
throw new HostError
|
|
325
|
+
throw new HostError("failed", `The response (${status} ${statusText}) isn't JSON: ${message}`);
|
|
100
326
|
}
|
|
101
327
|
}
|
|
102
328
|
//#endregion
|
|
103
329
|
//#region src/network/status.ts
|
|
330
|
+
/**
|
|
331
|
+
* Whether the phone is online now, and how. It can still be online without reaching a server.
|
|
332
|
+
* @since 1.0
|
|
333
|
+
*/
|
|
104
334
|
function status(callOptions) {
|
|
105
335
|
return call("dash.network.status", {}, callOptions);
|
|
106
336
|
}
|
|
@@ -120,9 +350,14 @@ var cache_exports = /* @__PURE__ */ __exportAll({
|
|
|
120
350
|
remove: () => remove$2,
|
|
121
351
|
set: () => set$1
|
|
122
352
|
});
|
|
353
|
+
/**
|
|
354
|
+
* Resolves with null for a missing or expired key.
|
|
355
|
+
* @since 1.0
|
|
356
|
+
*/
|
|
123
357
|
function get$1(key, callOptions) {
|
|
124
358
|
return call("dash.storage.cache.get", { key }, callOptions);
|
|
125
359
|
}
|
|
360
|
+
/** @since 1.0 */
|
|
126
361
|
function set$1(key, value, options = {}, callOptions) {
|
|
127
362
|
return call("dash.storage.cache.set", {
|
|
128
363
|
key,
|
|
@@ -130,15 +365,22 @@ function set$1(key, value, options = {}, callOptions) {
|
|
|
130
365
|
...options
|
|
131
366
|
}, callOptions);
|
|
132
367
|
}
|
|
368
|
+
/** @since 1.0 */
|
|
133
369
|
function remove$2(key, callOptions) {
|
|
134
370
|
return call("dash.storage.cache.remove", { key }, callOptions);
|
|
135
371
|
}
|
|
372
|
+
/** @since 1.0 */
|
|
136
373
|
function exists(key, callOptions) {
|
|
137
374
|
return call("dash.storage.cache.exists", { key }, callOptions);
|
|
138
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* The keys, sorted.
|
|
378
|
+
* @since 1.0
|
|
379
|
+
*/
|
|
139
380
|
function keys(callOptions) {
|
|
140
381
|
return call("dash.storage.cache.keys", {}, callOptions);
|
|
141
382
|
}
|
|
383
|
+
/** @since 1.0 */
|
|
142
384
|
function clear$1(callOptions) {
|
|
143
385
|
return call("dash.storage.cache.clear", {}, callOptions);
|
|
144
386
|
}
|
|
@@ -150,7 +392,6 @@ var file_exports = /* @__PURE__ */ __exportAll({
|
|
|
150
392
|
list: () => list,
|
|
151
393
|
move: () => move,
|
|
152
394
|
open: () => open,
|
|
153
|
-
pick: () => pick,
|
|
154
395
|
read: () => read,
|
|
155
396
|
remove: () => remove$1,
|
|
156
397
|
save: () => save,
|
|
@@ -158,12 +399,20 @@ var file_exports = /* @__PURE__ */ __exportAll({
|
|
|
158
399
|
usage: () => usage,
|
|
159
400
|
write: () => write
|
|
160
401
|
});
|
|
402
|
+
/**
|
|
403
|
+
* Reads a file of up to 5 MB.
|
|
404
|
+
* @since 1.0
|
|
405
|
+
*/
|
|
161
406
|
function read(path, options = {}, callOptions) {
|
|
162
407
|
return call("dash.storage.file.read", {
|
|
163
408
|
path,
|
|
164
409
|
...options
|
|
165
410
|
}, callOptions);
|
|
166
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Creates any missing folders above the file.
|
|
414
|
+
* @since 1.0
|
|
415
|
+
*/
|
|
167
416
|
function write(path, data, options = {}, callOptions) {
|
|
168
417
|
return call("dash.storage.file.write", {
|
|
169
418
|
path,
|
|
@@ -171,18 +420,25 @@ function write(path, data, options = {}, callOptions) {
|
|
|
171
420
|
...options
|
|
172
421
|
}, callOptions);
|
|
173
422
|
}
|
|
423
|
+
/** @since 1.0 */
|
|
174
424
|
function stat(path, callOptions) {
|
|
175
425
|
return call("dash.storage.file.stat", { path }, callOptions);
|
|
176
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* Sorted by path.
|
|
429
|
+
* @since 1.0
|
|
430
|
+
*/
|
|
177
431
|
function list(path = "", options = {}, callOptions) {
|
|
178
432
|
return call("dash.storage.file.list", {
|
|
179
433
|
path,
|
|
180
434
|
...options
|
|
181
435
|
}, callOptions);
|
|
182
436
|
}
|
|
437
|
+
/** @since 1.0 */
|
|
183
438
|
function createFolder(path, callOptions) {
|
|
184
439
|
return call("dash.storage.file.createFolder", { path }, callOptions);
|
|
185
440
|
}
|
|
441
|
+
/** @since 1.0 */
|
|
186
442
|
function move(from, to, options = {}, callOptions) {
|
|
187
443
|
return call("dash.storage.file.move", {
|
|
188
444
|
from,
|
|
@@ -190,6 +446,7 @@ function move(from, to, options = {}, callOptions) {
|
|
|
190
446
|
...options
|
|
191
447
|
}, callOptions);
|
|
192
448
|
}
|
|
449
|
+
/** @since 1.0 */
|
|
193
450
|
function copy(from, to, options = {}, callOptions) {
|
|
194
451
|
return call("dash.storage.file.copy", {
|
|
195
452
|
from,
|
|
@@ -197,30 +454,38 @@ function copy(from, to, options = {}, callOptions) {
|
|
|
197
454
|
...options
|
|
198
455
|
}, callOptions);
|
|
199
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* Removing a folder that isn't empty needs `recursive`.
|
|
459
|
+
* @since 1.0
|
|
460
|
+
*/
|
|
200
461
|
function remove$1(path, options = {}, callOptions) {
|
|
201
462
|
return call("dash.storage.file.remove", {
|
|
202
463
|
path,
|
|
203
464
|
...options
|
|
204
465
|
}, callOptions);
|
|
205
466
|
}
|
|
467
|
+
/**
|
|
468
|
+
* Keeps a temporary file, such as a download, at `path`.
|
|
469
|
+
* @since 1.0
|
|
470
|
+
*/
|
|
206
471
|
function save(file, path, options = {}, callOptions) {
|
|
207
472
|
return call("dash.storage.file.save", {
|
|
208
|
-
file:
|
|
473
|
+
file: file.id,
|
|
209
474
|
path,
|
|
210
475
|
...options
|
|
211
476
|
}, callOptions);
|
|
212
477
|
}
|
|
478
|
+
/**
|
|
479
|
+
* A stored file as a DotFile, to show with its `url` or send with `http.upload`.
|
|
480
|
+
* @since 1.0
|
|
481
|
+
*/
|
|
213
482
|
function open(path, callOptions) {
|
|
214
483
|
return call("dash.storage.file.open", { path }, callOptions);
|
|
215
484
|
}
|
|
485
|
+
/** @since 1.0 */
|
|
216
486
|
function usage(callOptions) {
|
|
217
487
|
return call("dash.storage.file.usage", {}, callOptions);
|
|
218
488
|
}
|
|
219
|
-
function pick(options = {}, callOptions) {
|
|
220
|
-
const params = {};
|
|
221
|
-
if (options.types) params.types = options.types;
|
|
222
|
-
return call("dash.storage.file.pick", params, callOptions);
|
|
223
|
-
}
|
|
224
489
|
//#endregion
|
|
225
490
|
//#region src/storage/secret.ts
|
|
226
491
|
var secret_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -229,18 +494,22 @@ var secret_exports = /* @__PURE__ */ __exportAll({
|
|
|
229
494
|
remove: () => remove,
|
|
230
495
|
set: () => set
|
|
231
496
|
});
|
|
497
|
+
/** @since 1.0 */
|
|
232
498
|
function get(key, callOptions) {
|
|
233
499
|
return call("dash.storage.secret.get", { key }, callOptions);
|
|
234
500
|
}
|
|
501
|
+
/** @since 1.0 */
|
|
235
502
|
function set(key, value, callOptions) {
|
|
236
503
|
return call("dash.storage.secret.set", {
|
|
237
504
|
key,
|
|
238
505
|
value
|
|
239
506
|
}, callOptions);
|
|
240
507
|
}
|
|
508
|
+
/** @since 1.0 */
|
|
241
509
|
function remove(key, callOptions) {
|
|
242
510
|
return call("dash.storage.secret.remove", { key }, callOptions);
|
|
243
511
|
}
|
|
512
|
+
/** @since 1.0 */
|
|
244
513
|
function clear(callOptions) {
|
|
245
514
|
return call("dash.storage.secret.clear", {}, callOptions);
|
|
246
515
|
}
|
|
@@ -253,56 +522,97 @@ var storage_exports = /* @__PURE__ */ __exportAll({
|
|
|
253
522
|
});
|
|
254
523
|
//#endregion
|
|
255
524
|
//#region src/system/clipboard.ts
|
|
525
|
+
/** @since 1.0 */
|
|
256
526
|
function copyText(text, callOptions) {
|
|
257
527
|
return call("dash.system.copyText", { text }, callOptions);
|
|
258
528
|
}
|
|
259
529
|
//#endregion
|
|
260
530
|
//#region src/system/delay.ts
|
|
531
|
+
/**
|
|
532
|
+
* Resolves after `milliseconds`. The host keeps the time, since a dot's logic has no timers.
|
|
533
|
+
* @since 1.0
|
|
534
|
+
*/
|
|
261
535
|
function delay(milliseconds, callOptions) {
|
|
262
536
|
return call("dash.system.delay", { milliseconds }, callOptions);
|
|
263
537
|
}
|
|
264
538
|
//#endregion
|
|
265
539
|
//#region src/system/dial.ts
|
|
540
|
+
/**
|
|
541
|
+
* Opens the phone's dialer with `number` ready, such as "+232 76 123456" or a USSD code such as
|
|
542
|
+
* "*715#". The person taps Call. Spaces and dashes are fine; anything else but digits, +, * and #
|
|
543
|
+
* rejects with `invalid`.
|
|
544
|
+
* @since 1.0
|
|
545
|
+
*/
|
|
266
546
|
function dial(number, callOptions) {
|
|
267
547
|
return call("dash.system.dial", { number }, callOptions);
|
|
268
548
|
}
|
|
269
549
|
//#endregion
|
|
270
550
|
//#region src/system/haptics.ts
|
|
551
|
+
/**
|
|
552
|
+
* Plays a short vibration. Resolves once it's done.
|
|
553
|
+
* @since 1.0
|
|
554
|
+
*/
|
|
271
555
|
function vibrate(options = {}, callOptions) {
|
|
272
556
|
return call("dash.system.vibrate", { style: options.style ?? "medium" }, callOptions);
|
|
273
557
|
}
|
|
274
558
|
//#endregion
|
|
275
559
|
//#region src/system/info.ts
|
|
560
|
+
/**
|
|
561
|
+
* The phone and the Dash the dot runs in. It has nothing that identifies the person or the phone.
|
|
562
|
+
* @since 1.0
|
|
563
|
+
*/
|
|
276
564
|
function info(callOptions) {
|
|
277
565
|
return call("dash.system.info", {}, callOptions);
|
|
278
566
|
}
|
|
279
567
|
//#endregion
|
|
280
568
|
//#region src/system/open-url.ts
|
|
569
|
+
/**
|
|
570
|
+
* Opens an https address in the device's browser. Any other address rejects with `invalid`.
|
|
571
|
+
* @since 1.0
|
|
572
|
+
*/
|
|
281
573
|
function openUrl(url, callOptions) {
|
|
282
574
|
return call("dash.system.openUrl", { url }, callOptions);
|
|
283
575
|
}
|
|
284
576
|
//#endregion
|
|
285
577
|
//#region src/system/screen.ts
|
|
578
|
+
/**
|
|
579
|
+
* Keeps the screen from dimming and locking while the dot shows, such as while a ticket's QR code is
|
|
580
|
+
* up. Dash undoes it when the dot closes.
|
|
581
|
+
* @since 1.0
|
|
582
|
+
*/
|
|
286
583
|
function keepAwake(on, callOptions) {
|
|
287
584
|
return call("dash.system.keepAwake", { on }, callOptions);
|
|
288
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* `max` makes the screen as bright as it goes, so a scanner can read a QR code on it, and `normal`
|
|
588
|
+
* puts it back. Dash puts it back too when the dot closes or the person leaves the app.
|
|
589
|
+
* @since 1.0
|
|
590
|
+
*/
|
|
289
591
|
function brightness(level, callOptions) {
|
|
290
592
|
return call("dash.system.brightness", { level }, callOptions);
|
|
291
593
|
}
|
|
292
594
|
//#endregion
|
|
293
595
|
//#region src/system/share.ts
|
|
596
|
+
/**
|
|
597
|
+
* Opens the device's share sheet. Resolves once it shows.
|
|
598
|
+
* @since 1.0
|
|
599
|
+
*/
|
|
294
600
|
function share(options, callOptions) {
|
|
295
|
-
const { file, ...
|
|
296
|
-
if (file === void 0) return call("dash.system.share",
|
|
601
|
+
const { file, ...content } = options;
|
|
602
|
+
if (file === void 0) return call("dash.system.share", content, callOptions);
|
|
297
603
|
return call("dash.system.share", {
|
|
298
|
-
...
|
|
299
|
-
file:
|
|
604
|
+
...content,
|
|
605
|
+
file: file.id
|
|
300
606
|
}, callOptions);
|
|
301
607
|
}
|
|
302
608
|
//#endregion
|
|
303
609
|
//#region src/system/torch.ts
|
|
304
|
-
|
|
305
|
-
|
|
610
|
+
/**
|
|
611
|
+
* Turns the torch on or off. Rejects with `unsupported` on a device without one.
|
|
612
|
+
* @since 1.0
|
|
613
|
+
*/
|
|
614
|
+
function torch(on, callOptions) {
|
|
615
|
+
return call("dash.system.torch", { on }, callOptions);
|
|
306
616
|
}
|
|
307
617
|
//#endregion
|
|
308
618
|
//#region src/system/index.ts
|
|
@@ -320,6 +630,10 @@ var system_exports = /* @__PURE__ */ __exportAll({
|
|
|
320
630
|
});
|
|
321
631
|
//#endregion
|
|
322
632
|
//#region src/ui/dialogs.ts
|
|
633
|
+
/**
|
|
634
|
+
* Shows a native alert. Resolves with the action the person chose.
|
|
635
|
+
* @since 1.0
|
|
636
|
+
*/
|
|
323
637
|
function alert(options, callOptions) {
|
|
324
638
|
const actions = options.actions ?? [{
|
|
325
639
|
id: "ok",
|
|
@@ -332,9 +646,19 @@ function alert(options, callOptions) {
|
|
|
332
646
|
}
|
|
333
647
|
//#endregion
|
|
334
648
|
//#region src/ui/pickers.ts
|
|
649
|
+
/**
|
|
650
|
+
* Opens the phone's own calendar. Resolves with the chosen date, such as "2026-10-24", or rejects
|
|
651
|
+
* with `cancelled` if the person closes it.
|
|
652
|
+
* @since 1.0
|
|
653
|
+
*/
|
|
335
654
|
function pickDate(options = {}, callOptions) {
|
|
336
655
|
return call("dash.ui.pickDate", options, callOptions);
|
|
337
656
|
}
|
|
657
|
+
/**
|
|
658
|
+
* Opens the phone's own clock. Resolves with the chosen time in 24 hours, such as "19:30", or
|
|
659
|
+
* rejects with `cancelled` if the person closes it.
|
|
660
|
+
* @since 1.0
|
|
661
|
+
*/
|
|
338
662
|
function pickTime(options = {}, callOptions) {
|
|
339
663
|
return call("dash.ui.pickTime", options, callOptions);
|
|
340
664
|
}
|
|
@@ -346,15 +670,131 @@ var ui_exports = /* @__PURE__ */ __exportAll({
|
|
|
346
670
|
pickTime: () => pickTime
|
|
347
671
|
});
|
|
348
672
|
//#endregion
|
|
673
|
+
//#region src/utils/encoding.ts
|
|
674
|
+
const BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
675
|
+
const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
676
|
+
const HEX_PATTERN = /^(?:[0-9a-fA-F]{2})*$/;
|
|
677
|
+
const base64 = {
|
|
678
|
+
encode(text) {
|
|
679
|
+
return bytesToBase64(utf8Bytes(text));
|
|
680
|
+
},
|
|
681
|
+
decode(encoded) {
|
|
682
|
+
return utf8Text(base64ToBytes(encoded));
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
const hex = {
|
|
686
|
+
encode(text) {
|
|
687
|
+
return utf8Bytes(text).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
688
|
+
},
|
|
689
|
+
decode(encoded) {
|
|
690
|
+
if (!HEX_PATTERN.test(encoded)) throw new Error(`"${encoded.slice(0, 20)}" isn't hex. Use pairs of 0-9 and a-f.`);
|
|
691
|
+
const bytes = [];
|
|
692
|
+
for (let index = 0; index < encoded.length; index += 2) bytes.push(parseInt(encoded.slice(index, index + 2), 16));
|
|
693
|
+
return utf8Text(bytes);
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
function bytesToBase64(bytes) {
|
|
697
|
+
let encoded = "";
|
|
698
|
+
for (let index = 0; index < bytes.length; index += 3) {
|
|
699
|
+
const group = bytes.slice(index, index + 3);
|
|
700
|
+
const bits = (group[0] ?? 0) << 16 | (group[1] ?? 0) << 8 | (group[2] ?? 0);
|
|
701
|
+
const sextets = [
|
|
702
|
+
bits >> 18 & 63,
|
|
703
|
+
bits >> 12 & 63,
|
|
704
|
+
bits >> 6 & 63,
|
|
705
|
+
bits & 63
|
|
706
|
+
];
|
|
707
|
+
const characterCount = group.length + 1;
|
|
708
|
+
for (const sextet of sextets.slice(0, characterCount)) encoded += BASE64_ALPHABET[sextet];
|
|
709
|
+
encoded += "=".repeat(4 - characterCount);
|
|
710
|
+
}
|
|
711
|
+
return encoded;
|
|
712
|
+
}
|
|
713
|
+
function base64ToBytes(encoded) {
|
|
714
|
+
if (!BASE64_PATTERN.test(encoded)) throw new Error(`"${encoded.slice(0, 20)}" isn't base64.`);
|
|
715
|
+
const bytes = [];
|
|
716
|
+
for (let index = 0; index < encoded.length; index += 4) {
|
|
717
|
+
const characters = encoded.slice(index, index + 4);
|
|
718
|
+
let bits = 0;
|
|
719
|
+
let padding = 0;
|
|
720
|
+
for (const character of characters) {
|
|
721
|
+
bits <<= 6;
|
|
722
|
+
if (character === "=") padding += 1;
|
|
723
|
+
else bits |= BASE64_ALPHABET.indexOf(character);
|
|
724
|
+
}
|
|
725
|
+
bytes.push(bits >> 16 & 255);
|
|
726
|
+
if (padding < 2) bytes.push(bits >> 8 & 255);
|
|
727
|
+
if (padding < 1) bytes.push(bits & 255);
|
|
728
|
+
}
|
|
729
|
+
return bytes;
|
|
730
|
+
}
|
|
731
|
+
function utf8Bytes(text) {
|
|
732
|
+
const bytes = [];
|
|
733
|
+
for (const character of text) {
|
|
734
|
+
const codePoint = character.codePointAt(0);
|
|
735
|
+
if (codePoint < 128) bytes.push(codePoint);
|
|
736
|
+
else if (codePoint < 2048) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
|
|
737
|
+
else if (codePoint < 65536) bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
|
|
738
|
+
else bytes.push(240 | codePoint >> 18, 128 | codePoint >> 12 & 63, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
|
|
739
|
+
}
|
|
740
|
+
return bytes;
|
|
741
|
+
}
|
|
742
|
+
const MAX_CODE_POINT = 1114111;
|
|
743
|
+
function utf8Text(bytes) {
|
|
744
|
+
let text = "";
|
|
745
|
+
let index = 0;
|
|
746
|
+
while (index < bytes.length) {
|
|
747
|
+
const first = bytes[index];
|
|
748
|
+
const length = sequenceLength(first);
|
|
749
|
+
const continuation = bytes.slice(index + 1, index + length);
|
|
750
|
+
if (length === 0 || !isCompleteContinuation(continuation, length)) {
|
|
751
|
+
text += "�";
|
|
752
|
+
index += 1;
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
let codePoint = firstByteBits(first, length);
|
|
756
|
+
for (const byte of continuation) codePoint = codePoint << 6 | byte & 63;
|
|
757
|
+
if (codePoint > MAX_CODE_POINT) {
|
|
758
|
+
text += "�";
|
|
759
|
+
index += 1;
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
text += String.fromCodePoint(codePoint);
|
|
763
|
+
index += length;
|
|
764
|
+
}
|
|
765
|
+
return text;
|
|
766
|
+
}
|
|
767
|
+
function sequenceLength(first) {
|
|
768
|
+
if (first < 128) return 1;
|
|
769
|
+
if (first >= 240) return 4;
|
|
770
|
+
if (first >= 224) return 3;
|
|
771
|
+
if (first >= 192) return 2;
|
|
772
|
+
return 0;
|
|
773
|
+
}
|
|
774
|
+
function isCompleteContinuation(continuation, length) {
|
|
775
|
+
if (continuation.length !== length - 1) return false;
|
|
776
|
+
return continuation.every((byte) => (byte & 192) === 128);
|
|
777
|
+
}
|
|
778
|
+
function firstByteBits(first, length) {
|
|
779
|
+
if (length === 1) return first;
|
|
780
|
+
return first & 255 >> length + 1;
|
|
781
|
+
}
|
|
782
|
+
//#endregion
|
|
783
|
+
//#region src/utils/index.ts
|
|
784
|
+
var utils_exports = /* @__PURE__ */ __exportAll({
|
|
785
|
+
base64: () => base64,
|
|
786
|
+
hex: () => hex
|
|
787
|
+
});
|
|
788
|
+
//#endregion
|
|
349
789
|
//#region src/tracked.ts
|
|
350
790
|
function tracked(group, track) {
|
|
351
791
|
const copy = {};
|
|
352
792
|
for (const [name, member] of Object.entries(group)) if (typeof member === "function") {
|
|
353
|
-
const
|
|
793
|
+
const startCall = member;
|
|
354
794
|
copy[name] = (...args) => {
|
|
355
|
-
const
|
|
356
|
-
track(
|
|
357
|
-
return
|
|
795
|
+
const result = startCall(...args);
|
|
796
|
+
if (result instanceof Promise) track(result);
|
|
797
|
+
return result;
|
|
358
798
|
};
|
|
359
799
|
} else copy[name] = tracked(member, track);
|
|
360
800
|
return copy;
|
|
@@ -362,27 +802,9 @@ function tracked(group, track) {
|
|
|
362
802
|
//#endregion
|
|
363
803
|
//#region src/errors.ts
|
|
364
804
|
function isDashError(error, ...codes) {
|
|
365
|
-
if (error instanceof HostError
|
|
805
|
+
if (error instanceof HostError) return codes.length === 0 || codes.includes(error.code);
|
|
366
806
|
return false;
|
|
367
807
|
}
|
|
368
|
-
function isDashCancelled(error) {
|
|
369
|
-
return isDashError(error, "cancelled");
|
|
370
|
-
}
|
|
371
|
-
function isDashTimeout(error) {
|
|
372
|
-
return isDashError(error, "timeout");
|
|
373
|
-
}
|
|
374
|
-
function isDashDenied(error) {
|
|
375
|
-
return isDashError(error, "denied");
|
|
376
|
-
}
|
|
377
|
-
function isDashInvalid(error) {
|
|
378
|
-
return isDashError(error, "invalid");
|
|
379
|
-
}
|
|
380
|
-
function isDashUnsupported(error) {
|
|
381
|
-
return isDashError(error, "unsupported");
|
|
382
|
-
}
|
|
383
|
-
function isDashFailed(error) {
|
|
384
|
-
return isDashError(error, "failed");
|
|
385
|
-
}
|
|
386
808
|
function errorMessage(error) {
|
|
387
809
|
if (error instanceof Error) return error.message;
|
|
388
810
|
if (typeof error === "string" && error) return error;
|
|
@@ -392,7 +814,7 @@ async function unlessCancelled(call) {
|
|
|
392
814
|
try {
|
|
393
815
|
return await call;
|
|
394
816
|
} catch (error) {
|
|
395
|
-
if (
|
|
817
|
+
if (isDashError(error, "cancelled")) return;
|
|
396
818
|
throw error;
|
|
397
819
|
}
|
|
398
820
|
}
|
|
@@ -413,7 +835,7 @@ function debounce(milliseconds) {
|
|
|
413
835
|
await wait(dash.system.delay(milliseconds));
|
|
414
836
|
return true;
|
|
415
837
|
} catch (error) {
|
|
416
|
-
if (
|
|
838
|
+
if (isDashError(error, "cancelled")) return false;
|
|
417
839
|
throw error;
|
|
418
840
|
}
|
|
419
841
|
};
|
|
@@ -426,9 +848,14 @@ const dash = {
|
|
|
426
848
|
network: network_exports,
|
|
427
849
|
storage: storage_exports,
|
|
428
850
|
media: media_exports,
|
|
429
|
-
contacts: contacts_exports
|
|
851
|
+
contacts: contacts_exports,
|
|
852
|
+
dot: dot_exports,
|
|
853
|
+
account: account_exports,
|
|
854
|
+
crypto: crypto_exports,
|
|
855
|
+
utils: utils_exports,
|
|
856
|
+
supports
|
|
430
857
|
};
|
|
431
858
|
//#endregion
|
|
432
|
-
export {
|
|
859
|
+
export { DASH_API_SINCE, DASH_API_VERSION, DashError, dash, debounce, errorMessage, isDashError, latest, tracked, unlessCancelled, useHostDashApiVersions, warnAboveDashApiVersion };
|
|
433
860
|
|
|
434
861
|
//# sourceMappingURL=index.js.map
|