@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.
- package/dist/puter.cjs +2 -2
- package/index.d.ts +41 -15
- package/package.json +1 -1
- package/src/index.js +116 -79
- package/src/lib/APICallLogger.js +20 -21
- package/src/lib/EventListener.js +10 -10
- package/src/lib/filesystem/APIFS.js +11 -19
- package/src/lib/filesystem/CacheFS.js +25 -25
- package/src/lib/filesystem/PostMessageFS.js +11 -11
- package/src/lib/filesystem/definitions.js +11 -10
- package/src/lib/path.js +505 -446
- package/src/lib/polyfills/fileReaderPoly.js +40 -0
- package/src/lib/polyfills/localStorage.js +30 -33
- package/src/lib/polyfills/xhrshim.js +206 -207
- package/src/lib/utils.js +160 -151
- package/src/lib/xdrpc.js +9 -9
- package/src/modules/AI.js +473 -292
- package/src/modules/Apps.js +56 -56
- package/src/modules/Auth.js +17 -17
- package/src/modules/Debug.js +1 -1
- package/src/modules/Drivers.js +41 -41
- package/src/modules/FSItem.js +64 -62
- package/src/modules/FileSystem/index.js +22 -23
- package/src/modules/FileSystem/operations/copy.js +7 -7
- package/src/modules/FileSystem/operations/deleteFSEntry.js +14 -12
- package/src/modules/FileSystem/operations/getReadUrl.js +16 -14
- package/src/modules/FileSystem/operations/mkdir.js +11 -11
- package/src/modules/FileSystem/operations/move.js +12 -12
- package/src/modules/FileSystem/operations/read.js +10 -10
- package/src/modules/FileSystem/operations/readdir.js +28 -28
- package/src/modules/FileSystem/operations/rename.js +11 -11
- package/src/modules/FileSystem/operations/sign.js +33 -30
- package/src/modules/FileSystem/operations/space.js +7 -7
- package/src/modules/FileSystem/operations/stat.js +25 -25
- package/src/modules/FileSystem/operations/symlink.js +15 -17
- package/src/modules/FileSystem/operations/upload.js +151 -122
- package/src/modules/FileSystem/operations/write.js +16 -12
- package/src/modules/FileSystem/utils/getAbsolutePathForApp.js +10 -6
- package/src/modules/Hosting.js +29 -29
- package/src/modules/KV.js +23 -23
- package/src/modules/OS.js +15 -15
- package/src/modules/Perms.js +19 -21
- package/src/modules/PuterDialog.js +46 -48
- package/src/modules/Threads.js +17 -20
- package/src/modules/UI.js +156 -156
- package/src/modules/Util.js +3 -3
- package/src/modules/Workers.js +52 -49
- package/src/modules/networking/PSocket.js +38 -38
- package/src/modules/networking/PTLS.js +54 -47
- package/src/modules/networking/PWispHandler.js +49 -47
- package/src/modules/networking/parsers.js +110 -108
- package/src/modules/networking/requests.js +67 -78
- package/src/services/APIAccess.js +9 -9
- package/src/services/FSRelay.js +6 -6
- package/src/services/Filesystem.js +8 -8
- package/src/services/NoPuterYet.js +2 -2
- package/src/services/XDIncoming.js +1 -1
|
@@ -13,7 +13,7 @@ const readdir = async function (...args) {
|
|
|
13
13
|
let options;
|
|
14
14
|
|
|
15
15
|
// If first argument is an object, it's the options
|
|
16
|
-
if (typeof args[0] === 'object' && args[0] !== null) {
|
|
16
|
+
if ( typeof args[0] === 'object' && args[0] !== null ) {
|
|
17
17
|
options = args[0];
|
|
18
18
|
} else {
|
|
19
19
|
// Otherwise, we assume separate arguments are provided
|
|
@@ -26,25 +26,25 @@ const readdir = async function (...args) {
|
|
|
26
26
|
|
|
27
27
|
return new Promise(async (resolve, reject) => {
|
|
28
28
|
// consistency levels
|
|
29
|
-
if(!options.consistency){
|
|
29
|
+
if ( ! options.consistency ) {
|
|
30
30
|
options.consistency = 'strong';
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// Either path or uid is required
|
|
34
|
-
if(!options.path && !options.uid){
|
|
34
|
+
if ( !options.path && !options.uid ) {
|
|
35
35
|
throw new Error({ code: 'NO_PATH_OR_UID', message: 'Either path or uid must be provided.' });
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// Generate cache key based on path or uid
|
|
39
39
|
let cacheKey;
|
|
40
|
-
if(options.path){
|
|
41
|
-
cacheKey =
|
|
40
|
+
if ( options.path ) {
|
|
41
|
+
cacheKey = `readdir:${ options.path}`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
if(options.consistency === 'eventual'){
|
|
44
|
+
if ( options.consistency === 'eventual' ) {
|
|
45
45
|
// Check cache
|
|
46
46
|
const cachedResult = await puter._cache.get(cacheKey);
|
|
47
|
-
if(cachedResult){
|
|
47
|
+
if ( cachedResult ) {
|
|
48
48
|
resolve(cachedResult);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
@@ -62,17 +62,17 @@ const readdir = async function (...args) {
|
|
|
62
62
|
// Check if there's already an in-flight request for the same parameters
|
|
63
63
|
const existingEntry = inflightRequests.get(deduplicationKey);
|
|
64
64
|
const now = Date.now();
|
|
65
|
-
|
|
66
|
-
if (existingEntry) {
|
|
65
|
+
|
|
66
|
+
if ( existingEntry ) {
|
|
67
67
|
const timeSinceRequest = now - existingEntry.timestamp;
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
// Only reuse the request if it's within the deduplication window
|
|
70
|
-
if (timeSinceRequest < DEDUPLICATION_WINDOW_MS) {
|
|
70
|
+
if ( timeSinceRequest < DEDUPLICATION_WINDOW_MS ) {
|
|
71
71
|
// Wait for the existing request and return its result
|
|
72
72
|
try {
|
|
73
73
|
const result = await existingEntry.promise;
|
|
74
74
|
resolve(result);
|
|
75
|
-
} catch (error) {
|
|
75
|
+
} catch ( error ) {
|
|
76
76
|
reject(error);
|
|
77
77
|
}
|
|
78
78
|
return;
|
|
@@ -84,12 +84,12 @@ const readdir = async function (...args) {
|
|
|
84
84
|
|
|
85
85
|
// Create a promise for this request and store it to deduplicate concurrent calls
|
|
86
86
|
const requestPromise = new Promise(async (resolveRequest, rejectRequest) => {
|
|
87
|
-
// If auth token is not provided and we are in the web environment,
|
|
87
|
+
// If auth token is not provided and we are in the web environment,
|
|
88
88
|
// try to authenticate with Puter
|
|
89
|
-
if(!puter.authToken && puter.env === 'web'){
|
|
90
|
-
try{
|
|
89
|
+
if ( !puter.authToken && puter.env === 'web' ) {
|
|
90
|
+
try {
|
|
91
91
|
await puter.ui.authenticateWithPuter();
|
|
92
|
-
}catch(e){
|
|
92
|
+
} catch (e) {
|
|
93
93
|
// if authentication fails, throw an error
|
|
94
94
|
rejectRequest('Authentication failed.');
|
|
95
95
|
return;
|
|
@@ -97,26 +97,26 @@ const readdir = async function (...args) {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// create xhr object
|
|
100
|
-
const xhr = utils.initXhr('/readdir', this.APIOrigin, undefined,
|
|
100
|
+
const xhr = utils.initXhr('/readdir', this.APIOrigin, undefined, 'post', 'text/plain;actually=json');
|
|
101
101
|
|
|
102
102
|
// set up event handlers for load and error events
|
|
103
103
|
utils.setupXhrEventHandlers(xhr, options.success, options.error, async (result) => {
|
|
104
104
|
// Calculate the size of the result for cache eligibility check
|
|
105
105
|
const resultSize = JSON.stringify(result).length;
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
// Cache the result if it's not bigger than MAX_CACHE_SIZE
|
|
108
108
|
const MAX_CACHE_SIZE = 100 * 1024 * 1024;
|
|
109
109
|
|
|
110
|
-
if(resultSize <= MAX_CACHE_SIZE){
|
|
110
|
+
if ( resultSize <= MAX_CACHE_SIZE ) {
|
|
111
111
|
// UPSERT the cache
|
|
112
112
|
puter._cache.set(cacheKey, result);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
// set each individual item's cache
|
|
116
|
-
for(const item of result){
|
|
117
|
-
puter._cache.set(
|
|
116
|
+
for ( const item of result ) {
|
|
117
|
+
puter._cache.set(`item:${ item.path}`, item);
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
resolveRequest(result);
|
|
121
121
|
}, rejectRequest);
|
|
122
122
|
|
|
@@ -124,13 +124,13 @@ const readdir = async function (...args) {
|
|
|
124
124
|
const payload = {
|
|
125
125
|
no_thumbs: options.no_thumbs,
|
|
126
126
|
no_assocs: options.no_assocs,
|
|
127
|
-
auth_token: this.authToken
|
|
127
|
+
auth_token: this.authToken,
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
// Add either uid or path to the payload
|
|
131
|
-
if (options.uid) {
|
|
131
|
+
if ( options.uid ) {
|
|
132
132
|
payload.uid = options.uid;
|
|
133
|
-
} else if (options.path) {
|
|
133
|
+
} else if ( options.path ) {
|
|
134
134
|
payload.path = getAbsolutePathForApp(options.path);
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -148,11 +148,11 @@ const readdir = async function (...args) {
|
|
|
148
148
|
const result = await requestPromise;
|
|
149
149
|
inflightRequests.delete(deduplicationKey);
|
|
150
150
|
resolve(result);
|
|
151
|
-
} catch (error) {
|
|
151
|
+
} catch ( error ) {
|
|
152
152
|
inflightRequests.delete(deduplicationKey);
|
|
153
153
|
reject(error);
|
|
154
154
|
}
|
|
155
|
-
})
|
|
156
|
-
}
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
157
|
|
|
158
158
|
export default readdir;
|
|
@@ -5,7 +5,7 @@ const rename = function (...args) {
|
|
|
5
5
|
let options;
|
|
6
6
|
|
|
7
7
|
// If first argument is an object, it's the options
|
|
8
|
-
if (typeof args[0] === 'object' && args[0] !== null) {
|
|
8
|
+
if ( typeof args[0] === 'object' && args[0] !== null ) {
|
|
9
9
|
options = args[0];
|
|
10
10
|
} else {
|
|
11
11
|
// Otherwise, we assume separate arguments are provided
|
|
@@ -19,12 +19,12 @@ const rename = function (...args) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
return new Promise(async (resolve, reject) => {
|
|
22
|
-
// If auth token is not provided and we are in the web environment,
|
|
22
|
+
// If auth token is not provided and we are in the web environment,
|
|
23
23
|
// try to authenticate with Puter
|
|
24
|
-
if(!puter.authToken && puter.env === 'web'){
|
|
25
|
-
try{
|
|
24
|
+
if ( !puter.authToken && puter.env === 'web' ) {
|
|
25
|
+
try {
|
|
26
26
|
await puter.ui.authenticateWithPuter();
|
|
27
|
-
}catch(e){
|
|
27
|
+
} catch (e) {
|
|
28
28
|
// if authentication fails, throw an error
|
|
29
29
|
reject('Authentication failed.');
|
|
30
30
|
}
|
|
@@ -40,18 +40,18 @@ const rename = function (...args) {
|
|
|
40
40
|
original_client_socket_id: options.excludeSocketID || options.original_client_socket_id,
|
|
41
41
|
new_name: options.new_name || options.newName,
|
|
42
42
|
};
|
|
43
|
-
|
|
44
|
-
if (options.uid !== undefined) {
|
|
43
|
+
|
|
44
|
+
if ( options.uid !== undefined ) {
|
|
45
45
|
dataToSend.uid = options.uid;
|
|
46
|
-
} else if (options.path !== undefined) {
|
|
46
|
+
} else if ( options.path !== undefined ) {
|
|
47
47
|
// If dirPath is not provided or it's not starting with a slash, it means it's a relative path
|
|
48
48
|
// in that case, we need to prepend the app's root directory to it
|
|
49
49
|
dataToSend.path = getAbsolutePathForApp(options.path);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
xhr.send(JSON.stringify(dataToSend));
|
|
53
53
|
|
|
54
|
-
})
|
|
55
|
-
}
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
56
|
|
|
57
57
|
export default rename;
|
|
@@ -12,7 +12,7 @@ import * as utils from '../../../lib/utils.js';
|
|
|
12
12
|
* @throws {Error} If the AJAX request fails.
|
|
13
13
|
* @async
|
|
14
14
|
*/
|
|
15
|
-
const sign = function(...args){
|
|
15
|
+
const sign = function (...args) {
|
|
16
16
|
let options;
|
|
17
17
|
|
|
18
18
|
// Otherwise, we assume separate arguments are provided
|
|
@@ -25,79 +25,82 @@ const sign = function(...args){
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
return new Promise(async (resolve, reject) => {
|
|
28
|
-
// If auth token is not provided and we are in the web environment,
|
|
28
|
+
// If auth token is not provided and we are in the web environment,
|
|
29
29
|
// try to authenticate with Puter
|
|
30
|
-
if(!puter.authToken && puter.env === 'web'){
|
|
31
|
-
try{
|
|
30
|
+
if ( !puter.authToken && puter.env === 'web' ) {
|
|
31
|
+
try {
|
|
32
32
|
await puter.ui.authenticateWithPuter();
|
|
33
|
-
}catch(e){
|
|
33
|
+
} catch (e) {
|
|
34
34
|
// if authentication fails, throw an error
|
|
35
35
|
reject('Authentication failed.');
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
39
|
let items = options.items;
|
|
41
40
|
|
|
42
41
|
// if only a single item is passed, convert it to array
|
|
43
42
|
// so that the code below can work with arrays
|
|
44
|
-
if(!Array.isArray(items)){
|
|
45
|
-
items = [items]
|
|
43
|
+
if ( ! Array.isArray(items) ) {
|
|
44
|
+
items = [items];
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
// create xhr object
|
|
49
48
|
const xhr = utils.initXhr('/sign', this.APIOrigin, this.authToken);
|
|
50
49
|
|
|
51
50
|
// response
|
|
52
|
-
xhr.addEventListener('load', async function(e){
|
|
51
|
+
xhr.addEventListener('load', async function (e) {
|
|
53
52
|
const resp = await utils.parseResponse(this);
|
|
54
53
|
// error
|
|
55
|
-
if(this.status !== 200){
|
|
54
|
+
if ( this.status !== 200 ) {
|
|
56
55
|
// if error callback is provided, call it
|
|
57
|
-
if(options.error && typeof options.error === 'function')
|
|
58
|
-
|
|
56
|
+
if ( options.error && typeof options.error === 'function' )
|
|
57
|
+
{
|
|
58
|
+
options.error(resp);
|
|
59
|
+
}
|
|
59
60
|
// reject promise
|
|
60
|
-
return reject(resp)
|
|
61
|
+
return reject(resp);
|
|
61
62
|
}
|
|
62
63
|
// success
|
|
63
|
-
else{
|
|
64
|
+
else {
|
|
64
65
|
let res = resp;
|
|
65
66
|
let result;
|
|
66
67
|
let token = res.token;
|
|
67
68
|
// if only a single item was passed, return a single object
|
|
68
|
-
if(items.length == 1){
|
|
69
|
-
result = {...(res.signatures[0])};
|
|
69
|
+
if ( items.length == 1 ) {
|
|
70
|
+
result = { ...(res.signatures[0]) };
|
|
70
71
|
}
|
|
71
72
|
// if multiple items were passed, return an array of objects
|
|
72
|
-
else{
|
|
73
|
-
let obj=[];
|
|
74
|
-
for(let i=0; i<res.signatures.length; i++){
|
|
75
|
-
obj.push({...res.signatures[i]});
|
|
73
|
+
else {
|
|
74
|
+
let obj = [];
|
|
75
|
+
for ( let i = 0; i < res.signatures.length; i++ ) {
|
|
76
|
+
obj.push({ ...res.signatures[i] });
|
|
76
77
|
}
|
|
77
78
|
result = obj;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
// if success callback is provided, call it
|
|
81
|
-
if(options.success && typeof options.success === 'function')
|
|
82
|
-
|
|
82
|
+
if ( options.success && typeof options.success === 'function' )
|
|
83
|
+
{
|
|
84
|
+
options.success({ token: token, items: result });
|
|
85
|
+
}
|
|
83
86
|
// resolve with success
|
|
84
|
-
return resolve({token: token, items: result});
|
|
87
|
+
return resolve({ token: token, items: result });
|
|
85
88
|
}
|
|
86
89
|
});
|
|
87
90
|
|
|
88
|
-
xhr.upload.addEventListener('progress', function(e){
|
|
89
|
-
})
|
|
91
|
+
xhr.upload.addEventListener('progress', function (e) {
|
|
92
|
+
});
|
|
90
93
|
|
|
91
94
|
// error
|
|
92
|
-
xhr.addEventListener('error', function(e){
|
|
95
|
+
xhr.addEventListener('error', function (e) {
|
|
93
96
|
return utils.handle_error(options.error, reject, this);
|
|
94
|
-
})
|
|
97
|
+
});
|
|
95
98
|
|
|
96
99
|
xhr.send(JSON.stringify({
|
|
97
100
|
app_uid: options.app_uid,
|
|
98
|
-
items: items
|
|
101
|
+
items: items,
|
|
99
102
|
}));
|
|
100
|
-
})
|
|
101
|
-
}
|
|
103
|
+
});
|
|
104
|
+
};
|
|
102
105
|
|
|
103
106
|
export default sign;
|
|
@@ -4,7 +4,7 @@ const space = function (...args) {
|
|
|
4
4
|
let options;
|
|
5
5
|
|
|
6
6
|
// If first argument is an object, it's the options
|
|
7
|
-
if (typeof args[0] === 'object' && args[0] !== null) {
|
|
7
|
+
if ( typeof args[0] === 'object' && args[0] !== null ) {
|
|
8
8
|
options = args[0];
|
|
9
9
|
} else {
|
|
10
10
|
// Otherwise, we assume separate arguments are provided
|
|
@@ -16,12 +16,12 @@ const space = function (...args) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
return new Promise(async (resolve, reject) => {
|
|
19
|
-
// If auth token is not provided and we are in the web environment,
|
|
19
|
+
// If auth token is not provided and we are in the web environment,
|
|
20
20
|
// try to authenticate with Puter
|
|
21
|
-
if(!puter.authToken && puter.env === 'web'){
|
|
22
|
-
try{
|
|
21
|
+
if ( !puter.authToken && puter.env === 'web' ) {
|
|
22
|
+
try {
|
|
23
23
|
await puter.ui.authenticateWithPuter();
|
|
24
|
-
}catch(e){
|
|
24
|
+
} catch (e) {
|
|
25
25
|
// if authentication fails, throw an error
|
|
26
26
|
reject('Authentication failed.');
|
|
27
27
|
}
|
|
@@ -34,7 +34,7 @@ const space = function (...args) {
|
|
|
34
34
|
utils.setupXhrEventHandlers(xhr, options.success, options.error, resolve, reject);
|
|
35
35
|
|
|
36
36
|
xhr.send();
|
|
37
|
-
})
|
|
38
|
-
}
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
39
|
|
|
40
40
|
export default space;
|
|
@@ -13,7 +13,7 @@ const stat = async function (...args) {
|
|
|
13
13
|
let options;
|
|
14
14
|
|
|
15
15
|
// If first argument is an object, it's the options
|
|
16
|
-
if (typeof args[0] === 'object' && args[0] !== null) {
|
|
16
|
+
if ( typeof args[0] === 'object' && args[0] !== null ) {
|
|
17
17
|
options = args[0];
|
|
18
18
|
} else {
|
|
19
19
|
// Otherwise, we assume separate arguments are provided
|
|
@@ -28,20 +28,20 @@ const stat = async function (...args) {
|
|
|
28
28
|
|
|
29
29
|
return new Promise(async (resolve, reject) => {
|
|
30
30
|
// consistency levels
|
|
31
|
-
if(!options.consistency){
|
|
31
|
+
if ( ! options.consistency ) {
|
|
32
32
|
options.consistency = 'strong';
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// Generate cache key based on path or uid
|
|
36
36
|
let cacheKey;
|
|
37
|
-
if(options.path){
|
|
38
|
-
cacheKey =
|
|
37
|
+
if ( options.path ) {
|
|
38
|
+
cacheKey = `item:${ options.path}`;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
if(options.consistency === 'eventual' && !options.returnSubdomains && !options.returnPermissions && !options.returnVersions && !options.returnSize){
|
|
41
|
+
if ( options.consistency === 'eventual' && !options.returnSubdomains && !options.returnPermissions && !options.returnVersions && !options.returnSize ) {
|
|
42
42
|
// Check cache
|
|
43
43
|
const cachedResult = await puter._cache.get(cacheKey);
|
|
44
|
-
if(cachedResult){
|
|
44
|
+
if ( cachedResult ) {
|
|
45
45
|
resolve(cachedResult);
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
@@ -61,17 +61,17 @@ const stat = async function (...args) {
|
|
|
61
61
|
// Check if there's already an in-flight request for the same parameters
|
|
62
62
|
const existingEntry = inflightRequests.get(deduplicationKey);
|
|
63
63
|
const now = Date.now();
|
|
64
|
-
|
|
65
|
-
if (existingEntry) {
|
|
64
|
+
|
|
65
|
+
if ( existingEntry ) {
|
|
66
66
|
const timeSinceRequest = now - existingEntry.timestamp;
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
// Only reuse the request if it's within the deduplication window
|
|
69
|
-
if (timeSinceRequest < DEDUPLICATION_WINDOW_MS) {
|
|
69
|
+
if ( timeSinceRequest < DEDUPLICATION_WINDOW_MS ) {
|
|
70
70
|
// Wait for the existing request and return its result
|
|
71
71
|
try {
|
|
72
72
|
const result = await existingEntry.promise;
|
|
73
73
|
resolve(result);
|
|
74
|
-
} catch (error) {
|
|
74
|
+
} catch ( error ) {
|
|
75
75
|
reject(error);
|
|
76
76
|
}
|
|
77
77
|
return;
|
|
@@ -83,12 +83,12 @@ const stat = async function (...args) {
|
|
|
83
83
|
|
|
84
84
|
// Create a promise for this request and store it to deduplicate concurrent calls
|
|
85
85
|
const requestPromise = new Promise(async (resolveRequest, rejectRequest) => {
|
|
86
|
-
// If auth token is not provided and we are in the web environment,
|
|
86
|
+
// If auth token is not provided and we are in the web environment,
|
|
87
87
|
// try to authenticate with Puter
|
|
88
|
-
if(!puter.authToken && puter.env === 'web'){
|
|
89
|
-
try{
|
|
88
|
+
if ( !puter.authToken && puter.env === 'web' ) {
|
|
89
|
+
try {
|
|
90
90
|
await puter.ui.authenticateWithPuter();
|
|
91
|
-
}catch(e){
|
|
91
|
+
} catch (e) {
|
|
92
92
|
// if authentication fails, throw an error
|
|
93
93
|
rejectRequest('Authentication failed.');
|
|
94
94
|
return;
|
|
@@ -96,33 +96,33 @@ const stat = async function (...args) {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// create xhr object
|
|
99
|
-
const xhr = utils.initXhr('/stat', this.APIOrigin, undefined,
|
|
99
|
+
const xhr = utils.initXhr('/stat', this.APIOrigin, undefined, 'post', 'text/plain;actually=json');
|
|
100
100
|
|
|
101
101
|
// set up event handlers for load and error events
|
|
102
102
|
utils.setupXhrEventHandlers(xhr, options.success, options.error, async (result) => {
|
|
103
103
|
// Calculate the size of the result for cache eligibility check
|
|
104
104
|
const resultSize = JSON.stringify(result).length;
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
// Cache the result if it's not bigger than MAX_CACHE_SIZE
|
|
107
107
|
const MAX_CACHE_SIZE = 20 * 1024 * 1024;
|
|
108
108
|
|
|
109
|
-
if(resultSize <= MAX_CACHE_SIZE){
|
|
109
|
+
if ( resultSize <= MAX_CACHE_SIZE ) {
|
|
110
110
|
// UPSERT the cache
|
|
111
111
|
puter._cache.set(cacheKey, result);
|
|
112
112
|
}
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
resolveRequest(result);
|
|
115
115
|
}, rejectRequest);
|
|
116
116
|
|
|
117
117
|
let dataToSend = {};
|
|
118
|
-
if (options.uid !== undefined) {
|
|
118
|
+
if ( options.uid !== undefined ) {
|
|
119
119
|
dataToSend.uid = options.uid;
|
|
120
|
-
} else if (options.path !== undefined) {
|
|
120
|
+
} else if ( options.path !== undefined ) {
|
|
121
121
|
// If dirPath is not provided or it's not starting with a slash, it means it's a relative path
|
|
122
122
|
// in that case, we need to prepend the app's root directory to it
|
|
123
123
|
dataToSend.path = getAbsolutePathForApp(options.path);
|
|
124
124
|
}
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
dataToSend.return_subdomains = options.returnSubdomains;
|
|
127
127
|
dataToSend.return_permissions = options.returnPermissions;
|
|
128
128
|
dataToSend.return_versions = options.returnVersions;
|
|
@@ -143,11 +143,11 @@ const stat = async function (...args) {
|
|
|
143
143
|
const result = await requestPromise;
|
|
144
144
|
inflightRequests.delete(deduplicationKey);
|
|
145
145
|
resolve(result);
|
|
146
|
-
} catch (error) {
|
|
146
|
+
} catch ( error ) {
|
|
147
147
|
inflightRequests.delete(deduplicationKey);
|
|
148
148
|
reject(error);
|
|
149
149
|
}
|
|
150
|
-
})
|
|
151
|
-
}
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
152
|
|
|
153
153
|
export default stat;
|
|
@@ -4,13 +4,12 @@ import pathLib from '../../../lib/path.js';
|
|
|
4
4
|
// This only works for absolute symlinks for now
|
|
5
5
|
const symlink = async function (target, linkPath) {
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
// If auth token is not provided and we are in the web environment,
|
|
7
|
+
// If auth token is not provided and we are in the web environment,
|
|
9
8
|
// try to authenticate with Puter
|
|
10
|
-
if(!puter.authToken && puter.env === 'web'){
|
|
11
|
-
try{
|
|
9
|
+
if ( !puter.authToken && puter.env === 'web' ) {
|
|
10
|
+
try {
|
|
12
11
|
await puter.ui.authenticateWithPuter();
|
|
13
|
-
}catch(e){
|
|
12
|
+
} catch (e) {
|
|
14
13
|
// if authentication fails, throw an error
|
|
15
14
|
throw 'Authentication failed.';
|
|
16
15
|
}
|
|
@@ -20,36 +19,35 @@ const symlink = async function (target, linkPath) {
|
|
|
20
19
|
linkPath = getAbsolutePathForApp(linkPath);
|
|
21
20
|
target = getAbsolutePathForApp(target);
|
|
22
21
|
const name = pathLib.basename(linkPath);
|
|
23
|
-
const linkDir = pathLib.dirname(linkPath)
|
|
22
|
+
const linkDir = pathLib.dirname(linkPath);
|
|
24
23
|
|
|
25
24
|
const op =
|
|
26
25
|
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
op: 'symlink',
|
|
27
|
+
path: linkDir,
|
|
28
|
+
name: name,
|
|
29
|
+
target: target,
|
|
31
30
|
};
|
|
32
31
|
|
|
33
32
|
const formData = new FormData();
|
|
34
33
|
formData.append('operation', JSON.stringify(op));
|
|
35
34
|
|
|
36
35
|
try {
|
|
37
|
-
const response = await fetch(this.APIOrigin
|
|
36
|
+
const response = await fetch(`${this.APIOrigin }/batch`, {
|
|
38
37
|
method: 'POST',
|
|
39
38
|
headers: { 'Authorization': `Bearer ${puter.authToken}` },
|
|
40
|
-
body: formData
|
|
39
|
+
body: formData,
|
|
41
40
|
});
|
|
42
|
-
if (response.status !== 200) {
|
|
41
|
+
if ( response.status !== 200 ) {
|
|
43
42
|
const error = await response.text();
|
|
44
|
-
console.error(
|
|
43
|
+
console.error('[symlink] fetch error: ', error);
|
|
45
44
|
throw error;
|
|
46
45
|
}
|
|
47
46
|
} catch (e) {
|
|
48
|
-
console.error(
|
|
47
|
+
console.error('[symlink] fetch error: ', e);
|
|
49
48
|
throw e;
|
|
50
49
|
}
|
|
51
|
-
|
|
52
50
|
|
|
53
|
-
}
|
|
51
|
+
};
|
|
54
52
|
|
|
55
53
|
export default symlink;
|