@heyputer/puter.js 2.2.2 → 2.2.5

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/index.d.ts CHANGED
@@ -11,7 +11,6 @@ import type { KV, KVIncrementPath, KVPair } from './types/modules/kv.d.ts';
11
11
  import type { Networking, PSocket, PTLSSocket } from './types/modules/networking.d.ts';
12
12
  import type { OS } from './types/modules/os.d.ts';
13
13
  import type { Perms } from './types/modules/perms.d.ts';
14
- import type Threads from './types/modules/threads.d.ts';
15
14
  import type { AlertButton, AppConnection, AppConnectionCloseEvent, CancelAwarePromise, ContextMenuItem, ContextMenuOptions, DirectoryPickerOptions, FilePickerOptions, LaunchAppOptions, MenuItem, MenubarOptions, ThemeData, UI, WindowOptions } from './types/modules/ui.d.ts';
16
15
  import type Util, { UtilRPC } from './types/modules/util.d.ts';
17
16
  import type { WorkerDeployment, WorkerInfo, WorkersHandler } from './types/modules/workers.d.ts';
@@ -93,7 +92,6 @@ export type {
93
92
  Speech2TxtOptions,
94
93
  Subdomain,
95
94
  ThemeData,
96
- Threads,
97
95
  ToolSchema,
98
96
  Txt2ImgOptions,
99
97
  Txt2SpeechCallable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyputer/puter.js",
3
- "version": "2.2.2",
3
+ "version": "2.2.5",
4
4
  "description": "Puter.js - A JavaScript library for interacting with Puter services.",
5
5
  "homepage": "https://developer.puter.com",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -18,7 +18,6 @@ import { PTLSSocket } from './modules/networking/PTLS.js';
18
18
  import { pFetch } from './modules/networking/requests.js';
19
19
  import OS from './modules/OS.js';
20
20
  import Perms from './modules/Perms.js';
21
- import Threads from './modules/Threads.js';
22
21
  import UI from './modules/UI.js';
23
22
  import Util from './modules/Util.js';
24
23
  import { WorkersHandler } from './modules/Workers.js';
@@ -170,7 +169,6 @@ const puterInit = (function () {
170
169
  this.registerModule('apps', Apps);
171
170
  this.registerModule('ai', AI);
172
171
  this.registerModule('kv', KV);
173
- this.registerModule('threads', Threads);
174
172
  this.registerModule('perms', Perms);
175
173
  this.registerModule('drivers', Drivers);
176
174
  this.registerModule('debug', Debug);
package/src/lib/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { FileReaderPoly } from "./polyfills/fileReaderPoly.js";
2
+ import { showUsageLimitDialog } from "../modules/UsageLimitDialog.js";
2
3
 
3
4
  /**
4
5
  * Parses a given response text into a JSON object. If the parsing fails due to invalid JSON format,
@@ -386,6 +387,14 @@ async function driverCall_ (
386
387
  const line = lines_received.shift();
387
388
  if ( line.trim() === '' ) continue;
388
389
  const lineObject = (JSON.parse(line));
390
+
391
+ // Check for usage limit errors in streaming responses
392
+ if ( lineObject?.error?.code === 'insufficient_funds' || lineObject?.metadata?.usage_limited === true ) {
393
+ if ( puter.env === 'web' ) {
394
+ showUsageLimitDialog('You have reached your usage limit for this account.<br>Please upgrade to continue.');
395
+ }
396
+ }
397
+
389
398
  if ( typeof (lineObject.text) === 'string' ) {
390
399
  Object.defineProperty(lineObject, 'toString', {
391
400
  enumerable: false,
@@ -462,6 +471,16 @@ async function driverCall_ (
462
471
  });
463
472
  }
464
473
 
474
+ // Check for usage limit errors and show upgrade dialog
475
+ const isInsufficientFunds = (response.target?.status === 402) ||
476
+ (resp?.error?.code === 'insufficient_funds') ||
477
+ (resp?.error?.status === 402);
478
+ const isUsageLimited = resp?.metadata?.usage_limited === true;
479
+
480
+ if ( (isInsufficientFunds || isUsageLimited) && puter.env === 'web' ) {
481
+ showUsageLimitDialog('Your account has not enough funding to complete this request.<br>Please upgrade to continue.');
482
+ }
483
+
465
484
  // HTTP Error - unauthorized
466
485
  if ( response.status === 401 || resp?.code === 'token_auth_failed' ) {
467
486
  if ( resp?.code === 'token_auth_failed' && puter.env === 'web' ) {
@@ -16,6 +16,37 @@ class Apps {
16
16
  this.appID = puter.appID;
17
17
  }
18
18
 
19
+ #addUserIterationToApp (app) {
20
+ app.getUsers = async (params) => {
21
+ params = params ?? {};
22
+ return (await puter.drivers.call('app-telemetry', 'app-telemetry', 'get_users', { app_uuid: app.uid, limit: params.limit, offset: params.offset })).result;
23
+ };
24
+ app.users = async function* (pageSize = 100) {
25
+ let offset = 0;
26
+
27
+ while ( true ) {
28
+ const users = await app.getUsers({ limit: pageSize, offset });
29
+
30
+ if ( !users || users.length === 0 ) return;
31
+
32
+ for ( const user of users ) {
33
+ yield user;
34
+ }
35
+
36
+ offset += users.length;
37
+ if ( users.length < pageSize ) return;
38
+ }
39
+ };
40
+ return app;
41
+ }
42
+
43
+ #addUserIterationToApps (apps) {
44
+ apps.forEach(app => {
45
+ this.#addUserIterationToApp(app);
46
+ });
47
+ return apps;
48
+ }
49
+
19
50
  /**
20
51
  * Sets a new authentication token.
21
52
  *
@@ -48,7 +79,7 @@ class Apps {
48
79
 
49
80
  options.predicate = ['user-can-edit'];
50
81
 
51
- return utils.make_driver_method(['uid'], 'puter-apps', undefined, 'select').call(this, options);
82
+ return this.#addUserIterationToApps(await utils.make_driver_method(['uid'], 'puter-apps', 'es:app', 'select').call(this, options));
52
83
  };
53
84
 
54
85
  create = async (...args) => {
@@ -112,7 +143,7 @@ class Apps {
112
143
  }
113
144
 
114
145
  // Call the original chat.complete method
115
- return await utils.make_driver_method(['object'], 'puter-apps', undefined, 'create').call(this, options);
146
+ return this.#addUserIterationToApp(await utils.make_driver_method(['object'], 'puter-apps', 'es:app', 'create').call(this, options));
116
147
  };
117
148
 
118
149
  update = async (...args) => {
@@ -138,7 +169,7 @@ class Apps {
138
169
  }
139
170
 
140
171
  // Call the original chat.complete method
141
- return await utils.make_driver_method(['object'], 'puter-apps', undefined, 'update').call(this, options);
172
+ return this.#addUserIterationToApp(await utils.make_driver_method(['object'], 'puter-apps', 'es:app', 'update').call(this, options));
142
173
  };
143
174
 
144
175
  get = async (...args) => {
@@ -159,8 +190,7 @@ class Apps {
159
190
  if ( typeof args[0] === 'object' && args[0] !== null ) {
160
191
  options.params = args[0];
161
192
  }
162
-
163
- return utils.make_driver_method(['uid'], 'puter-apps', undefined, 'read').call(this, options);
193
+ return this.#addUserIterationToApp(await utils.make_driver_method(['uid'], 'puter-apps', 'es:app', 'read').call(this, options));
164
194
  };
165
195
 
166
196
  delete = async (...args) => {
@@ -170,7 +200,7 @@ class Apps {
170
200
  if ( Array.isArray(args) && typeof args[0] === 'string' ) {
171
201
  options = { id: { name: args[0] } };
172
202
  }
173
- return utils.make_driver_method(['uid'], 'puter-apps', undefined, 'delete').call(this, options);
203
+ return utils.make_driver_method(['uid'], 'puter-apps', 'es:app', 'delete').call(this, options);
174
204
  };
175
205
 
176
206
  getDeveloperProfile = function (...args) {
@@ -45,8 +45,6 @@ export class PuterJSFileSystemModule {
45
45
 
46
46
  FSItem = FSItem;
47
47
 
48
- static NARI_METHODS = {};
49
-
50
48
  /**
51
49
  * Creates a new instance with the given authentication token, API origin, and app ID,
52
50
  * and connects to the socket.
@@ -2,6 +2,7 @@ import path from '../../../lib/path.js';
2
2
  import * as utils from '../../../lib/utils.js';
3
3
  import getAbsolutePathForApp from '../utils/getAbsolutePathForApp.js';
4
4
 
5
+ /* eslint-disable */
5
6
  const upload = async function (items, dirPath, options = {}) {
6
7
  return new Promise(async (resolve, reject) => {
7
8
  const DataTransferItem = globalThis.DataTransfer || (class DataTransferItem {
@@ -299,6 +300,7 @@ const upload = async function (items, dirPath, options = {}) {
299
300
  op: options.shortcutTo ? 'shortcut' : 'write',
300
301
  dedupe_name: options.dedupeName ?? true,
301
302
  overwrite: options.overwrite ?? false,
303
+ thumbnail: options.thumbnail ?? undefined,
302
304
  create_missing_ancestors: (options.createMissingAncestors || options.createMissingParents),
303
305
  operation_id: operation_id,
304
306
  path: (
package/src/modules/KV.js CHANGED
@@ -212,6 +212,84 @@ class KV {
212
212
  return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'decr').call(this, options);
213
213
  };
214
214
 
215
+ add = async (...args) => {
216
+ let options = {};
217
+
218
+ // arguments are required
219
+ if ( !args || args.length === 0 ) {
220
+ throw ({ message: 'Arguments are required', code: 'arguments_required' });
221
+ }
222
+
223
+ options.key = args[0];
224
+ const provided = args[1];
225
+ const isPathMap = provided && typeof provided === 'object' && !Array.isArray(provided);
226
+ options.pathAndValueMap = provided === undefined ? { '': 1 } : isPathMap ? provided : { '': provided };
227
+
228
+ // key size cannot be larger than MAX_KEY_SIZE
229
+ if ( options.key.length > this.MAX_KEY_SIZE ) {
230
+ throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
231
+ }
232
+
233
+ return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'add').call(this, options);
234
+ };
235
+
236
+ remove = async (...args) => {
237
+ if ( !args || args.length < 2 ) {
238
+ throw ({ message: 'At least one path is required', code: 'arguments_required' });
239
+ }
240
+
241
+ const key = args[0];
242
+ const paths = args.slice(1);
243
+
244
+ if ( Array.isArray(paths[0]) && paths.length === 1 ) {
245
+ throw ({ message: 'Paths must be provided as separate arguments', code: 'paths_invalid' });
246
+ }
247
+
248
+ if ( key === undefined || key === null ) {
249
+ throw ({ message: 'Key cannot be undefined', code: 'key_undefined' });
250
+ }
251
+
252
+ if ( key.length > this.MAX_KEY_SIZE ) {
253
+ throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
254
+ }
255
+
256
+ if ( paths.length === 0 ) {
257
+ throw ({ message: 'At least one path is required', code: 'arguments_required' });
258
+ }
259
+
260
+ if ( paths.some((path) => typeof path !== 'string') ) {
261
+ throw ({ message: 'All paths must be strings', code: 'paths_invalid' });
262
+ }
263
+
264
+ return utils.make_driver_method(['key', 'paths'], 'puter-kvstore', undefined, 'remove')
265
+ .call(this, { key, paths });
266
+ };
267
+
268
+ update = utils.make_driver_method(['key', 'pathAndValueMap', 'ttl'], 'puter-kvstore', undefined, 'update', {
269
+ preprocess: (args) => {
270
+ if ( args.key === undefined || args.key === null ) {
271
+ throw { message: 'Key cannot be undefined', code: 'key_undefined' };
272
+ }
273
+ if ( args.key.length > this.MAX_KEY_SIZE ) {
274
+ throw { message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' };
275
+ }
276
+ if ( args.pathAndValueMap === undefined || args.pathAndValueMap === null || Array.isArray(args.pathAndValueMap) || typeof args.pathAndValueMap !== 'object' ) {
277
+ throw { message: 'pathAndValueMap must be an object', code: 'path_map_invalid' };
278
+ }
279
+ if ( Object.keys(args.pathAndValueMap).length === 0 ) {
280
+ throw { message: 'pathAndValueMap cannot be empty', code: 'path_map_invalid' };
281
+ }
282
+ if ( args.ttl !== undefined && args.ttl !== null ) {
283
+ const ttl = Number(args.ttl);
284
+ if ( Number.isNaN(ttl) ) {
285
+ throw { message: 'ttl must be a number', code: 'ttl_invalid' };
286
+ }
287
+ args.ttl = ttl;
288
+ }
289
+ return args;
290
+ },
291
+ });
292
+
215
293
  /**
216
294
  * Set a time to live (in seconds) on a key. After the time to live has expired, the key will be deleted.
217
295
  * Prefer this over expireAt if you want timestamp to be set by the server, to avoid issues with clock drift.
@@ -434,7 +434,7 @@ class PuterDialog extends (globalThis.HTMLElement || Object) { // It will fall b
434
434
  // Add event listener to the button
435
435
  this.shadowRoot.querySelector('#launch-auth-popup')?.addEventListener('click', () => {
436
436
  let w = 600;
437
- let h = 400;
437
+ let h = 600;
438
438
  let title = 'Puter';
439
439
  var left = (screen.width / 2) - (w / 2);
440
440
  var top = (screen.height / 2) - (h / 2);
@@ -454,7 +454,7 @@ class PuterDialog extends (globalThis.HTMLElement || Object) { // It will fall b
454
454
  open () {
455
455
  if ( this.hasUserActivation() ) {
456
456
  let w = 600;
457
- let h = 400;
457
+ let h = 600;
458
458
  let title = 'Puter';
459
459
  var left = (screen.width / 2) - (w / 2);
460
460
  var top = (screen.height / 2) - (h / 2);
@@ -0,0 +1,208 @@
1
+ class UsageLimitDialog extends (globalThis.HTMLElement || Object) {
2
+ constructor (message) {
3
+ super();
4
+ this.message = message || 'You have reached your usage limit for this account.';
5
+
6
+ this.attachShadow({ mode: 'open' });
7
+
8
+ this.shadowRoot.innerHTML = `
9
+ <style>
10
+ dialog {
11
+ background: transparent;
12
+ border: none;
13
+ box-shadow: none;
14
+ outline: none;
15
+ padding: 0;
16
+ max-width: 90vw;
17
+ }
18
+
19
+ dialog::backdrop {
20
+ background: rgba(0, 0, 0, 0.5);
21
+ }
22
+
23
+ .dialog-content {
24
+ border: 1px solid #e8e8e8;
25
+ border-radius: 12px;
26
+ padding: 32px;
27
+ background: white;
28
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
29
+ -webkit-font-smoothing: antialiased;
30
+ color: #333;
31
+ position: relative;
32
+ max-width: 420px;
33
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
34
+ }
35
+
36
+ .close-btn {
37
+ position: absolute;
38
+ right: 16px;
39
+ top: 12px;
40
+ font-size: 20px;
41
+ color: #999;
42
+ cursor: pointer;
43
+ width: 28px;
44
+ height: 28px;
45
+ display: flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ border-radius: 50%;
49
+ transition: background 0.2s, color 0.2s;
50
+ }
51
+
52
+ .close-btn:hover {
53
+ background: #f0f0f0;
54
+ color: #333;
55
+ }
56
+
57
+ .icon-container {
58
+ width: 64px;
59
+ height: 64px;
60
+ margin: 0 auto 20px;
61
+ background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
62
+ border-radius: 50%;
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ }
67
+
68
+ .icon-container svg {
69
+ width: 32px;
70
+ height: 32px;
71
+ color: #f57c00;
72
+ }
73
+
74
+ h2 {
75
+ margin: 0 0 12px;
76
+ font-size: 20px;
77
+ font-weight: 600;
78
+ text-align: center;
79
+ color: #1a1a1a;
80
+ }
81
+
82
+ .message {
83
+ text-align: center;
84
+ font-size: 14px;
85
+ line-height: 1.5;
86
+ color: #666;
87
+ margin-bottom: 24px;
88
+ }
89
+
90
+ .buttons {
91
+ display: flex;
92
+ gap: 12px;
93
+ justify-content: center;
94
+ }
95
+
96
+ .button {
97
+ padding: 10px 24px;
98
+ border-radius: 8px;
99
+ font-size: 14px;
100
+ font-weight: 500;
101
+ cursor: pointer;
102
+ transition: all 0.2s;
103
+ border: none;
104
+ font-family: inherit;
105
+ }
106
+
107
+ .button-secondary {
108
+ background: #f5f5f5;
109
+ color: #666;
110
+ }
111
+
112
+ .button-secondary:hover {
113
+ background: #e8e8e8;
114
+ }
115
+
116
+ .button-primary {
117
+ background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
118
+ color: white;
119
+ }
120
+
121
+ .button-primary:hover {
122
+ background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
123
+ box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
124
+ }
125
+ </style>
126
+ <dialog>
127
+ <div class="dialog-content">
128
+ <span class="close-btn">&#x2715;</span>
129
+ <div class="icon-container">
130
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
131
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
132
+ </svg>
133
+ </div>
134
+ <h2>Low Balance</h2>
135
+ <p class="message">${this.message}</p>
136
+ <div class="buttons">
137
+ <button class="button button-secondary" id="close-btn">Close</button>
138
+ <button class="button button-primary" id="upgrade-btn">Upgrade Now</button>
139
+ </div>
140
+ </div>
141
+ </dialog>
142
+ `;
143
+ }
144
+
145
+ connectedCallback () {
146
+ const dialog = this.shadowRoot.querySelector('dialog');
147
+
148
+ this.shadowRoot.querySelector('.close-btn').addEventListener('click', () => {
149
+ this.close();
150
+ });
151
+
152
+ this.shadowRoot.querySelector('#close-btn').addEventListener('click', () => {
153
+ this.close();
154
+ });
155
+
156
+ this.shadowRoot.querySelector('#upgrade-btn').addEventListener('click', () => {
157
+ window.open('https://puter.com/dashboard', '_blank');
158
+ this.close();
159
+ });
160
+
161
+ // Close on backdrop click
162
+ dialog.addEventListener('click', (e) => {
163
+ if ( e.target === dialog ) {
164
+ this.close();
165
+ }
166
+ });
167
+ }
168
+
169
+ open () {
170
+ this.shadowRoot.querySelector('dialog').showModal();
171
+ }
172
+
173
+ close () {
174
+ this.shadowRoot.querySelector('dialog').close();
175
+ this.remove();
176
+ }
177
+ }
178
+
179
+ // Only define custom element in environments with DOM support
180
+ if ( typeof globalThis.HTMLElement !== 'undefined' && globalThis.customElements ) {
181
+ if ( ! customElements.get('usage-limit-dialog') ) {
182
+ customElements.define('usage-limit-dialog', UsageLimitDialog);
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Shows a usage limit dialog to the user
188
+ * @param {string} message - The message to display
189
+ */
190
+ export function showUsageLimitDialog (message) {
191
+ // Only log in non-browser environments
192
+ if ( typeof globalThis.document === 'undefined' ) {
193
+ console.warn('[Puter]', message);
194
+ return;
195
+ }
196
+
197
+ // Check if dialog is already shown to prevent duplicates
198
+ if ( document.querySelector('usage-limit-dialog') ) {
199
+ return;
200
+ }
201
+
202
+ const dialog = new UsageLimitDialog(message);
203
+ document.body.appendChild(dialog);
204
+ dialog.open();
205
+ }
206
+
207
+ export default UsageLimitDialog;
208
+
@@ -158,24 +158,14 @@ export interface Speech2SpeechOptions {
158
158
  file?: string | File | Blob;
159
159
  provider?: string;
160
160
  model?: string;
161
- modelId?: string;
162
- model_id?: string;
163
161
  voice?: string;
164
- voiceId?: string;
165
- voice_id?: string;
166
162
  output_format?: string;
167
- outputFormat?: string;
168
163
  voice_settings?: Record<string, unknown>;
169
- voiceSettings?: Record<string, unknown>;
170
164
  seed?: number;
171
165
  file_format?: string;
172
- fileFormat?: string;
173
166
  remove_background_noise?: boolean;
174
- removeBackgroundNoise?: boolean;
175
167
  optimize_streaming_latency?: number;
176
- optimizeStreamingLatency?: number;
177
168
  enable_logging?: boolean;
178
- enableLogging?: boolean;
179
169
  test_mode?: boolean;
180
170
  }
181
171
 
@@ -1,6 +1,6 @@
1
- import type { PaginationOptions, RequestCallbacks } from '../shared.d.ts';
1
+ import type { RequestCallbacks } from '../shared.d.ts';
2
2
 
3
- export interface AppRecord {
3
+ export interface App {
4
4
  uid: string;
5
5
  name: string;
6
6
  index_url: string;
@@ -16,12 +16,25 @@ export interface AppRecord {
16
16
  user_count?: number;
17
17
  }
18
18
 
19
- export interface AppListOptions extends PaginationOptions {
19
+ export interface CreateAppResult {
20
+ uid: string;
21
+ name: string;
22
+ title: string;
23
+ index_url: string;
24
+ subdomain: string;
25
+ owner: {
26
+ username: string;
27
+ uuid: string;
28
+ };
29
+ app_owner?: Record<string, unknown>;
30
+ }
31
+
32
+ export interface AppListOptions {
20
33
  stats_period?: string;
21
34
  icon_size?: null | 16 | 32 | 64 | 128 | 256 | 512;
22
35
  }
23
36
 
24
- export interface CreateAppOptions extends RequestCallbacks<AppRecord> {
37
+ export interface CreateAppOptions {
25
38
  name: string;
26
39
  indexURL: string;
27
40
  title?: string;
@@ -34,7 +47,7 @@ export interface CreateAppOptions extends RequestCallbacks<AppRecord> {
34
47
  dedupeName?: boolean;
35
48
  }
36
49
 
37
- export interface UpdateAppAttributes extends RequestCallbacks<AppRecord> {
50
+ export interface UpdateAppAttributes {
38
51
  name?: string;
39
52
  indexURL?: string;
40
53
  title?: string;
@@ -47,16 +60,12 @@ export interface UpdateAppAttributes extends RequestCallbacks<AppRecord> {
47
60
  }
48
61
 
49
62
  export class Apps {
50
- constructor (context: { authToken?: string; APIOrigin: string; appID?: string });
51
-
52
- setAuthToken (authToken: string): void;
53
- setAPIOrigin (APIOrigin: string): void;
54
-
55
- list (options?: AppListOptions): Promise<AppRecord[]>;
56
- create (name: string, indexURL: string, title?: string): Promise<AppRecord>;
57
- create (options: CreateAppOptions): Promise<AppRecord>;
58
- update (name: string, attributes: UpdateAppAttributes): Promise<AppRecord>;
59
- get (name: string, options?: AppListOptions): Promise<AppRecord>;
63
+ list (options?: AppListOptions): Promise<App[]>;
64
+ create (name: string, indexURL: string, title?: string): Promise<CreateAppResult>;
65
+ create (options: CreateAppOptions): Promise<CreateAppResult>;
66
+ update (name: string, attributes: UpdateAppAttributes): Promise<App>;
67
+ get (name: string, options?: AppListOptions): Promise<App>;
60
68
  delete (name: string): Promise<{ success?: boolean }>;
61
69
  getDeveloperProfile (options?: RequestCallbacks<Record<string, unknown>>): Promise<Record<string, unknown>>;
70
+ getDeveloperProfile (success: (value: Record<string, unknown>) => void, error?: (reason: unknown) => void): Promise<Record<string, unknown>>;
62
71
  }
@@ -1,3 +1,5 @@
1
+ import { RequestCallbacks } from "../shared";
2
+
1
3
  export interface User {
2
4
  uuid: string;
3
5
  username: string;
@@ -55,7 +57,7 @@ export class Auth {
55
57
  signIn (options?: { attempt_temp_user_creation?: boolean }): Promise<SignInResult>;
56
58
  signOut (): void;
57
59
  isSignedIn (): boolean;
58
- getUser (): Promise<User>;
60
+ getUser (options:? RequestCallbacks<User>): Promise<User>;
59
61
  whoami (): Promise<User>;
60
62
  getMonthlyUsage (): Promise<MonthlyUsage>;
61
63
  getDetailedAppUsage (appId: string): Promise<DetailedAppUsage>;
@@ -43,7 +43,6 @@ export interface DeleteOptions extends RequestCallbacks<void> {
43
43
  paths?: string | string[];
44
44
  recursive?: boolean;
45
45
  descendantsOnly?: boolean;
46
- descendants_only?: boolean;
47
46
  }
48
47
 
49
48
  export interface ReadOptions extends RequestCallbacks<Blob> {
@@ -100,7 +99,6 @@ export interface WriteOptions extends RequestCallbacks<FSItem> {
100
99
  dedupeName?: boolean;
101
100
  createMissingParents?: boolean;
102
101
  createMissingAncestors?: boolean;
103
- name?: string;
104
102
  init?: (operationId: string, xhr: XMLHttpRequest) => void;
105
103
  start?: () => void;
106
104
  progress?: (operationId: string, progress: number) => void;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-unused-vars */
1
2
  export type KVValue = string | number | boolean | object | unknown;
2
3
  export type KVScalar = KVValue | KVValue[];
3
4
 
@@ -10,6 +11,14 @@ export interface KVIncrementPath {
10
11
  [path: string]: number;
11
12
  }
12
13
 
14
+ export interface KVUpdatePath {
15
+ [path: string]: KVValue;
16
+ }
17
+
18
+ export interface KVAddPath {
19
+ [path: string]: KVValue | KVValue[];
20
+ }
21
+
13
22
  export class KV {
14
23
  readonly MAX_KEY_SIZE: number;
15
24
  readonly MAX_VALUE_SIZE: number;
@@ -19,6 +28,9 @@ export class KV {
19
28
  del (key: string): Promise<boolean>;
20
29
  incr (key: string, amount?: number | KVIncrementPath): Promise<number>;
21
30
  decr (key: string, amount?: number | KVIncrementPath): Promise<number>;
31
+ add (key: string, value?: KVValue | KVAddPath): Promise<KVValue>;
32
+ remove (key: string, ...paths: string[]): Promise<KVValue>;
33
+ update (key: string, pathAndValueMap: KVUpdatePath, ttlSeconds?: number): Promise<KVValue>;
22
34
  expire (key: string, ttlSeconds: number): Promise<boolean>;
23
35
  expireAt (key: string, timestampSeconds: number): Promise<boolean>;
24
36
  list (pattern?: string, returnValues?: false): Promise<string[]>;
@@ -14,7 +14,7 @@ export class PSocket {
14
14
  close (): void;
15
15
  on (event: 'open', handler: () => void): void;
16
16
  on (event: 'data', handler: (buffer: Uint8Array) => void): void;
17
- on (event: 'error', handler: (reason: unknown) => void): void;
17
+ on (event: 'error', handler: (reason: string) => void): void;
18
18
  on (event: 'close', handler: (hadError: boolean) => void): void;
19
19
  addListener (event: SocketEvent, handler: (...args: unknown[]) => void): void;
20
20
  }