@heyputer/puter.js 2.1.4 → 2.1.7

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 (57) hide show
  1. package/dist/puter.cjs +2 -2
  2. package/index.d.ts +41 -15
  3. package/package.json +1 -1
  4. package/src/index.js +116 -79
  5. package/src/lib/APICallLogger.js +20 -21
  6. package/src/lib/EventListener.js +10 -10
  7. package/src/lib/filesystem/APIFS.js +11 -19
  8. package/src/lib/filesystem/CacheFS.js +25 -25
  9. package/src/lib/filesystem/PostMessageFS.js +11 -11
  10. package/src/lib/filesystem/definitions.js +11 -10
  11. package/src/lib/path.js +505 -446
  12. package/src/lib/polyfills/fileReaderPoly.js +40 -0
  13. package/src/lib/polyfills/localStorage.js +30 -33
  14. package/src/lib/polyfills/xhrshim.js +206 -207
  15. package/src/lib/utils.js +160 -151
  16. package/src/lib/xdrpc.js +9 -9
  17. package/src/modules/AI.js +473 -292
  18. package/src/modules/Apps.js +56 -56
  19. package/src/modules/Auth.js +17 -17
  20. package/src/modules/Debug.js +1 -1
  21. package/src/modules/Drivers.js +41 -41
  22. package/src/modules/FSItem.js +64 -62
  23. package/src/modules/FileSystem/index.js +22 -23
  24. package/src/modules/FileSystem/operations/copy.js +7 -7
  25. package/src/modules/FileSystem/operations/deleteFSEntry.js +14 -12
  26. package/src/modules/FileSystem/operations/getReadUrl.js +16 -14
  27. package/src/modules/FileSystem/operations/mkdir.js +11 -11
  28. package/src/modules/FileSystem/operations/move.js +12 -12
  29. package/src/modules/FileSystem/operations/read.js +10 -10
  30. package/src/modules/FileSystem/operations/readdir.js +28 -28
  31. package/src/modules/FileSystem/operations/rename.js +11 -11
  32. package/src/modules/FileSystem/operations/sign.js +33 -30
  33. package/src/modules/FileSystem/operations/space.js +7 -7
  34. package/src/modules/FileSystem/operations/stat.js +25 -25
  35. package/src/modules/FileSystem/operations/symlink.js +15 -17
  36. package/src/modules/FileSystem/operations/upload.js +151 -122
  37. package/src/modules/FileSystem/operations/write.js +16 -12
  38. package/src/modules/FileSystem/utils/getAbsolutePathForApp.js +10 -6
  39. package/src/modules/Hosting.js +29 -29
  40. package/src/modules/KV.js +23 -23
  41. package/src/modules/OS.js +15 -15
  42. package/src/modules/Perms.js +19 -21
  43. package/src/modules/PuterDialog.js +46 -48
  44. package/src/modules/Threads.js +17 -20
  45. package/src/modules/UI.js +156 -156
  46. package/src/modules/Util.js +3 -3
  47. package/src/modules/Workers.js +52 -49
  48. package/src/modules/networking/PSocket.js +38 -38
  49. package/src/modules/networking/PTLS.js +54 -47
  50. package/src/modules/networking/PWispHandler.js +49 -47
  51. package/src/modules/networking/parsers.js +110 -108
  52. package/src/modules/networking/requests.js +67 -78
  53. package/src/services/APIAccess.js +9 -9
  54. package/src/services/FSRelay.js +6 -6
  55. package/src/services/Filesystem.js +8 -8
  56. package/src/services/NoPuterYet.js +2 -2
  57. package/src/services/XDIncoming.js +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as utils from '../lib/utils.js';
2
2
  import getAbsolutePathForApp from './FileSystem/utils/getAbsolutePathForApp.js';
3
3
 
4
- class Hosting{
4
+ class Hosting {
5
5
  /**
6
6
  * Creates a new instance with the given authentication token, API origin, and app ID,
7
7
  *
@@ -29,7 +29,7 @@ class Hosting{
29
29
 
30
30
  /**
31
31
  * Sets the API origin.
32
- *
32
+ *
33
33
  * @param {string} APIOrigin - The new API origin.
34
34
  * @memberof [Apps]
35
35
  * @returns {void}
@@ -40,99 +40,99 @@ class Hosting{
40
40
 
41
41
  // todo document the `Subdomain` object.
42
42
  list = async (...args) => {
43
- return (await utils.make_driver_method([], 'puter-subdomains', undefined, 'select')(...args)).filter(e => !e.subdomain.startsWith("workers.puter."));
44
- }
43
+ return (await utils.make_driver_method([], 'puter-subdomains', undefined, 'select')(...args)).filter(e => !e.subdomain.startsWith('workers.puter.'));
44
+ };
45
45
 
46
46
  create = async (...args) => {
47
47
  let options = {};
48
48
  // * allows for: puter.hosting.new('example-subdomain') *
49
- if (typeof args[0] === 'string' && args.length === 1) {
49
+ if ( typeof args[0] === 'string' && args.length === 1 ) {
50
50
  // if subdomain is in the format of a `subdomain.puter.site` or `subdomain.puter.com`, extract the subdomain
51
51
  // and use it as the subdomain. This is to make development easier.
52
- if (args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/)) {
52
+ if ( args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/) ) {
53
53
  args[0] = args[0].split('.')[0];
54
54
  }
55
55
 
56
- options = { object: { subdomain: args[0] }};
56
+ options = { object: { subdomain: args[0] } };
57
57
  }
58
58
  // if there are two string arguments, assume they are the subdomain and the target directory
59
59
  // * allows for: puter.hosting.new('example-subdomain', '/path/to/target') *
60
- else if (Array.isArray(args) && args.length === 2 && typeof args[0] === 'string') {
60
+ else if ( Array.isArray(args) && args.length === 2 && typeof args[0] === 'string' ) {
61
61
  // if subdomain is in the format of a `subdomain.puter.site` or `subdomain.puter.com`, extract the subdomain
62
62
  // and use it as the subdomain. This is to make development easier.
63
- if (args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/)) {
63
+ if ( args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/) ) {
64
64
  args[0] = args[0].split('.')[0];
65
65
  }
66
66
 
67
67
  // if the target directory is not an absolute path, make it an absolute path relative to the app's root directory
68
- if(args[1]){
68
+ if ( args[1] ) {
69
69
  args[1] = getAbsolutePathForApp(args[1]);
70
70
  }
71
71
 
72
- options = { object: { subdomain: args[0], root_dir: args[1] }};
72
+ options = { object: { subdomain: args[0], root_dir: args[1] } };
73
73
  }
74
74
  // allows for: puter.hosting.new({ subdomain: 'subdomain' })
75
- else if (typeof args[0] === 'object') {
75
+ else if ( typeof args[0] === 'object' ) {
76
76
  options = { object: args[0] };
77
77
  }
78
78
  // Call the original chat.complete method
79
79
  return await utils.make_driver_method(['object'], 'puter-subdomains', undefined, 'create').call(this, options);
80
- }
80
+ };
81
81
 
82
- update = async(...args) => {
82
+ update = async (...args) => {
83
83
  let options = {};
84
84
  // If there are two string arguments, assume they are the subdomain and the target directory
85
85
  // * allows for: puter.hosting.update('example-subdomain', '/path/to/target') *
86
- if (Array.isArray(args) && typeof args[0] === 'string') {
86
+ if ( Array.isArray(args) && typeof args[0] === 'string' ) {
87
87
  // if subdomain is in the format of a `subdomain.puter.site` or `subdomain.puter.com`, extract the subdomain
88
88
  // and use it as the subdomain. This is to make development easier.
89
- if (args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/)) {
89
+ if ( args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/) ) {
90
90
  args[0] = args[0].split('.')[0];
91
91
  }
92
92
 
93
93
  // if the target directory is not an absolute path, make it an absolute path relative to the app's root directory
94
- if(args[1]){
94
+ if ( args[1] ) {
95
95
  args[1] = getAbsolutePathForApp(args[1]);
96
96
  }
97
97
 
98
- options = { id: {subdomain: args[0]}, object: { root_dir: args[1] ?? null }};
98
+ options = { id: { subdomain: args[0] }, object: { root_dir: args[1] ?? null } };
99
99
  }
100
100
 
101
101
  // Call the original chat.complete method
102
102
  return await utils.make_driver_method(['object'], 'puter-subdomains', undefined, 'update').call(this, options);
103
- }
103
+ };
104
104
 
105
- get = async(...args) => {
105
+ get = async (...args) => {
106
106
  let options = {};
107
107
  // if there is one string argument, assume it is the subdomain
108
108
  // * allows for: puter.hosting.get('example-subdomain') *
109
- if (Array.isArray(args) && typeof args[0] === 'string') {
109
+ if ( Array.isArray(args) && typeof args[0] === 'string' ) {
110
110
  // if subdomain is in the format of a `subdomain.puter.site` or `subdomain.puter.com`, extract the subdomain
111
111
  // and use it as the subdomain. This is to make development easier.
112
- if (args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/)) {
112
+ if ( args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/) ) {
113
113
  args[0] = args[0].split('.')[0];
114
114
  }
115
115
 
116
- options = { id: {subdomain: args[0]}};
116
+ options = { id: { subdomain: args[0] } };
117
117
  }
118
118
  return utils.make_driver_method(['uid'], 'puter-subdomains', undefined, 'read').call(this, options);
119
- }
119
+ };
120
120
 
121
- delete = async(...args) => {
121
+ delete = async (...args) => {
122
122
  let options = {};
123
123
  // if there is one string argument, assume it is the subdomain
124
124
  // * allows for: puter.hosting.get('example-subdomain') *
125
- if (Array.isArray(args) && typeof args[0] === 'string') {
125
+ if ( Array.isArray(args) && typeof args[0] === 'string' ) {
126
126
  // if subdomain is in the format of a `subdomain.puter.site` or `subdomain.puter.com`, extract the subdomain
127
127
  // and use it as the subdomain. This is to make development easier.
128
- if (args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/)) {
128
+ if ( args[0].match(/^[a-z0-9]+\.puter\.(site|com)$/) ) {
129
129
  args[0] = args[0].split('.')[0];
130
130
  }
131
131
 
132
- options = { id: {subdomain: args[0]}};
132
+ options = { id: { subdomain: args[0] } };
133
133
  }
134
134
  return utils.make_driver_method(['uid'], 'puter-subdomains', undefined, 'delete').call(this, options);
135
- }
135
+ };
136
136
  }
137
137
 
138
138
  export default Hosting;
package/src/modules/KV.js CHANGED
@@ -17,7 +17,7 @@ const gui_cache_keys = [
17
17
  'taskbar_position',
18
18
  'has_seen_toolbar_animation',
19
19
  ];
20
- class KV{
20
+ class KV {
21
21
  MAX_KEY_SIZE = 1024;
22
22
  MAX_VALUE_SIZE = 399 * 1024;
23
23
 
@@ -29,7 +29,7 @@ class KV{
29
29
  * @param {string} APIOrigin - Origin of the API server. Used to build the API endpoint URLs.
30
30
  * @param {string} appID - ID of the app to use.
31
31
  */
32
- constructor(context) {
32
+ constructor (context) {
33
33
  this.authToken = context.authToken;
34
34
  this.APIOrigin = context.APIOrigin;
35
35
  this.appID = context.appID;
@@ -79,7 +79,7 @@ class KV{
79
79
  * @memberof [KV]
80
80
  * @returns {void}
81
81
  */
82
- setAuthToken(authToken) {
82
+ setAuthToken (authToken) {
83
83
  this.authToken = authToken;
84
84
  }
85
85
 
@@ -90,7 +90,7 @@ class KV{
90
90
  * @memberof [KV]
91
91
  * @returns {void}
92
92
  */
93
- setAPIOrigin(APIOrigin) {
93
+ setAPIOrigin (APIOrigin) {
94
94
  this.APIOrigin = APIOrigin;
95
95
  }
96
96
 
@@ -116,15 +116,15 @@ class KV{
116
116
  */
117
117
  preprocess: (args) => {
118
118
  // key cannot be undefined or null
119
- if ( args.key === undefined || args.key === null ){
119
+ if ( args.key === undefined || args.key === null ) {
120
120
  throw { message: 'Key cannot be undefined', code: 'key_undefined' };
121
121
  }
122
122
  // key size cannot be larger than MAX_KEY_SIZE
123
- if ( args.key.length > this.MAX_KEY_SIZE ){
123
+ if ( args.key.length > this.MAX_KEY_SIZE ) {
124
124
  throw { message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' };
125
125
  }
126
126
  // value size cannot be larger than MAX_VALUE_SIZE
127
- if ( args.value && args.value.length > this.MAX_VALUE_SIZE ){
127
+ if ( args.value && args.value.length > this.MAX_VALUE_SIZE ) {
128
128
  throw { message: `Value size cannot be larger than ${this.MAX_VALUE_SIZE}`, code: 'value_too_large' };
129
129
  }
130
130
  return args;
@@ -134,7 +134,7 @@ class KV{
134
134
  /**
135
135
  * Resolves to the value if the key exists, or `undefined` if the key does not exist. Rejects with an error on failure.
136
136
  */
137
- async get(...args) {
137
+ async get (...args) {
138
138
  // Condition for gui boot cache
139
139
  if (
140
140
  typeof args[0] === 'string' &&
@@ -153,7 +153,7 @@ class KV{
153
153
  get_ = utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'get', {
154
154
  preprocess: (args) => {
155
155
  // key size cannot be larger than MAX_KEY_SIZE
156
- if ( args.key.length > this.MAX_KEY_SIZE ){
156
+ if ( args.key.length > this.MAX_KEY_SIZE ) {
157
157
  throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
158
158
  }
159
159
 
@@ -168,15 +168,15 @@ class KV{
168
168
  let options = {};
169
169
 
170
170
  // arguments are required
171
- if ( !args || args.length === 0 ){
171
+ if ( !args || args.length === 0 ) {
172
172
  throw ({ message: 'Arguments are required', code: 'arguments_required' });
173
173
  }
174
174
 
175
175
  options.key = args[0];
176
- options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
176
+ options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
177
177
 
178
178
  // key size cannot be larger than MAX_KEY_SIZE
179
- if ( options.key.length > this.MAX_KEY_SIZE ){
179
+ if ( options.key.length > this.MAX_KEY_SIZE ) {
180
180
  throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
181
181
  }
182
182
 
@@ -187,15 +187,15 @@ class KV{
187
187
  let options = {};
188
188
 
189
189
  // arguments are required
190
- if ( !args || args.length === 0 ){
190
+ if ( !args || args.length === 0 ) {
191
191
  throw ({ message: 'Arguments are required', code: 'arguments_required' });
192
192
  }
193
193
 
194
194
  options.key = args[0];
195
- options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
195
+ options.pathAndAmountMap = !args[1] ? { '': 1 } : typeof args[1] === 'number' ? { '': args[1] } : args[1];
196
196
 
197
197
  // key size cannot be larger than MAX_KEY_SIZE
198
- if ( options.key.length > this.MAX_KEY_SIZE ){
198
+ if ( options.key.length > this.MAX_KEY_SIZE ) {
199
199
  throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
200
200
  }
201
201
 
@@ -216,7 +216,7 @@ class KV{
216
216
  options.ttl = ttl;
217
217
 
218
218
  // key size cannot be larger than MAX_KEY_SIZE
219
- if ( options.key.length > this.MAX_KEY_SIZE ){
219
+ if ( options.key.length > this.MAX_KEY_SIZE ) {
220
220
  throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
221
221
  }
222
222
 
@@ -237,7 +237,7 @@ class KV{
237
237
  options.key = key;
238
238
  options.timestamp = timestamp;
239
239
  // key size cannot be larger than MAX_KEY_SIZE
240
- if ( options.key.length > this.MAX_KEY_SIZE ){
240
+ if ( options.key.length > this.MAX_KEY_SIZE ) {
241
241
  throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
242
242
  }
243
243
 
@@ -249,7 +249,7 @@ class KV{
249
249
  del = utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'del', {
250
250
  preprocess: (args) => {
251
251
  // key size cannot be larger than this.MAX_KEY_SIZE
252
- if ( args.key.length > this.MAX_KEY_SIZE ){
252
+ if ( args.key.length > this.MAX_KEY_SIZE ) {
253
253
  throw ({ message: `Key size cannot be larger than ${this.MAX_KEY_SIZE}`, code: 'key_too_large' });
254
254
  }
255
255
 
@@ -263,7 +263,7 @@ class KV{
263
263
  let returnValues = false;
264
264
 
265
265
  // list(true) or list(pattern, true) will return the key-value pairs
266
- if ( (args && args.length === 1 && args[0] === true) || (args && args.length === 2 && args[1] === true) ){
266
+ if ( (args && args.length === 1 && args[0] === true) || (args && args.length === 2 && args[1] === true) ) {
267
267
  options = {};
268
268
  returnValues = true;
269
269
  }
@@ -274,16 +274,16 @@ class KV{
274
274
 
275
275
  // list(pattern)
276
276
  // list(pattern, true)
277
- if ( (args && args.length === 1 && typeof args[0] === 'string') || (args && args.length === 2 && typeof args[0] === 'string' && args[1] === true) ){
277
+ if ( (args && args.length === 1 && typeof args[0] === 'string') || (args && args.length === 2 && typeof args[0] === 'string' && args[1] === true) ) {
278
278
  pattern = args[0];
279
279
  }
280
280
 
281
281
  return utils.make_driver_method([], 'puter-kvstore', undefined, 'list', {
282
282
  transform: (res) => {
283
283
  // glob pattern was provided
284
- if ( pattern ){
284
+ if ( pattern ) {
285
285
  // consider both the key and the value
286
- if ( !returnValues ) {
286
+ if ( ! returnValues ) {
287
287
  let keys = res.filter((key) => {
288
288
  return globMatch(pattern, key);
289
289
  });
@@ -309,7 +309,7 @@ class KV{
309
309
  clear = this.flush;
310
310
  }
311
311
 
312
- function globMatch(pattern, str) {
312
+ function globMatch (pattern, str) {
313
313
  const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
314
314
 
315
315
  let regexPattern = escapeRegExp(pattern)
package/src/modules/OS.js CHANGED
@@ -1,6 +1,6 @@
1
- import * as utils from '../lib/utils.js'
1
+ import * as utils from '../lib/utils.js';
2
2
 
3
- class OS{
3
+ class OS {
4
4
  /**
5
5
  * Creates a new instance with the given authentication token, API origin, and app ID,
6
6
  *
@@ -28,7 +28,7 @@ class OS{
28
28
 
29
29
  /**
30
30
  * Sets the API origin.
31
- *
31
+ *
32
32
  * @param {string} APIOrigin - The new API origin.
33
33
  * @memberof [Apps]
34
34
  * @returns {void}
@@ -37,11 +37,11 @@ class OS{
37
37
  this.APIOrigin = APIOrigin;
38
38
  }
39
39
 
40
- user = function(...args){
40
+ user = function (...args) {
41
41
  let options;
42
42
 
43
43
  // If first argument is an object, it's the options
44
- if (typeof args[0] === 'object' && args[0] !== null) {
44
+ if ( typeof args[0] === 'object' && args[0] !== null ) {
45
45
  options = args[0];
46
46
  } else {
47
47
  // Otherwise, we assume separate arguments are provided
@@ -52,25 +52,25 @@ class OS{
52
52
  }
53
53
 
54
54
  let query = '';
55
- if(options?.query){
56
- query = '?' + new URLSearchParams(options.query).toString();
55
+ if ( options?.query ) {
56
+ query = `?${ new URLSearchParams(options.query).toString()}`;
57
57
  }
58
58
 
59
59
  return new Promise((resolve, reject) => {
60
- const xhr = utils.initXhr('/whoami' + query, this.APIOrigin, this.authToken, 'get');
60
+ const xhr = utils.initXhr(`/whoami${ query}`, this.APIOrigin, this.authToken, 'get');
61
61
 
62
62
  // set up event handlers for load and error events
63
63
  utils.setupXhrEventHandlers(xhr, options.success, options.error, resolve, reject);
64
64
 
65
65
  xhr.send();
66
- })
67
- }
66
+ });
67
+ };
68
68
 
69
- version = function(...args){
69
+ version = function (...args) {
70
70
  let options;
71
71
 
72
72
  // If first argument is an object, it's the options
73
- if (typeof args[0] === 'object' && args[0] !== null) {
73
+ if ( typeof args[0] === 'object' && args[0] !== null ) {
74
74
  options = args[0];
75
75
  } else {
76
76
  // Otherwise, we assume separate arguments are provided
@@ -88,8 +88,8 @@ class OS{
88
88
  utils.setupXhrEventHandlers(xhr, options.success, options.error, resolve, reject);
89
89
 
90
90
  xhr.send();
91
- })
92
- }
91
+ });
92
+ };
93
93
  }
94
94
 
95
- export default OS
95
+ export default OS;
@@ -10,16 +10,14 @@ export default class Perms {
10
10
  this.APIOrigin = APIOrigin;
11
11
  }
12
12
  async req_ (route, body) {
13
- const resp = await fetch(
14
- this.APIOrigin + route, {
15
- method: body ? 'POST' : 'GET',
16
- headers: {
17
- Authorization: `Bearer ${this.authToken}`,
18
- 'Content-Type': 'application/json',
19
- },
20
- ...(body ? { body: JSON.stringify(body) } : {}),
21
- }
22
- );
13
+ const resp = await fetch(this.APIOrigin + route, {
14
+ method: body ? 'POST' : 'GET',
15
+ headers: {
16
+ Authorization: `Bearer ${this.authToken}`,
17
+ 'Content-Type': 'application/json',
18
+ },
19
+ ...(body ? { body: JSON.stringify(body) } : {}),
20
+ });
23
21
  return await resp.json();
24
22
  }
25
23
 
@@ -27,62 +25,62 @@ export default class Perms {
27
25
  async grantUser (target_username, permission) {
28
26
  return await this.req_('/auth/grant-user-user', {
29
27
  target_username, permission,
30
- })
28
+ });
31
29
  }
32
30
 
33
31
  async grantGroup (group_uid, permission) {
34
32
  return await this.req_('/auth/grant-user-group', {
35
33
  group_uid, permission,
36
- })
34
+ });
37
35
  }
38
36
 
39
37
  async grantApp (app_uid, permission) {
40
38
  return await this.req_('/auth/grant-user-app', {
41
39
  app_uid, permission,
42
- })
40
+ });
43
41
  }
44
42
 
45
43
  async grantAppAnyUser (app_uid, permission) {
46
44
  return await this.req_('/auth/grant-dev-app', {
47
45
  app_uid, permission,
48
- })
46
+ });
49
47
  }
50
48
 
51
49
  async grantOrigin (origin, permission) {
52
50
  return await this.req_('/auth/grant-user-app', {
53
51
  origin, permission,
54
- })
52
+ });
55
53
  }
56
-
54
+
57
55
  // Revoke Permissions
58
56
  async revokeUser (target_username, permission) {
59
57
  return await this.req_('/auth/revoke-user-user', {
60
58
  target_username, permission,
61
- })
59
+ });
62
60
  }
63
61
 
64
62
  async revokeGroup (group_uid, permission) {
65
63
  return await this.req_('/auth/revoke-user-group', {
66
64
  group_uid, permission,
67
- })
65
+ });
68
66
  }
69
67
 
70
68
  async revokeApp (app_uid, permission) {
71
69
  return await this.req_('/auth/revoke-user-app', {
72
70
  app_uid, permission,
73
- })
71
+ });
74
72
  }
75
73
 
76
74
  async revokeAppAnyUser (app_uid, permission) {
77
75
  return await this.req_('/auth/revoke-dev-app', {
78
76
  app_uid, permission,
79
- })
77
+ });
80
78
  }
81
79
 
82
80
  async revokeOrigin (origin, permission) {
83
81
  return await this.req_('/auth/revoke-user-app', {
84
82
  origin, permission,
85
- })
83
+ });
86
84
  }
87
85
 
88
86
  // Group Management