@themartiancompany/opfs 1.8.11

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 (114) hide show
  1. package/COPYING +674 -0
  2. package/README.cn.md +301 -0
  3. package/README.md +241 -0
  4. package/dist/main.cjs +1840 -0
  5. package/dist/main.cjs.map +1 -0
  6. package/dist/main.mjs +1751 -0
  7. package/dist/main.mjs.map +1 -0
  8. package/dist/types.d.ts +920 -0
  9. package/dist/types.d.ts.map +1 -0
  10. package/docs/README.md +115 -0
  11. package/docs/classes/SyncMessenger.md +42 -0
  12. package/docs/functions/appendFile.md +29 -0
  13. package/docs/functions/appendFileSync.md +26 -0
  14. package/docs/functions/assertAbsolutePath.md +29 -0
  15. package/docs/functions/assertFileUrl.md +29 -0
  16. package/docs/functions/connectSyncAgent.md +25 -0
  17. package/docs/functions/copy.md +35 -0
  18. package/docs/functions/copySync.md +30 -0
  19. package/docs/functions/createFile.md +27 -0
  20. package/docs/functions/createFileSync.md +25 -0
  21. package/docs/functions/deleteTemp.md +23 -0
  22. package/docs/functions/deleteTempSync.md +19 -0
  23. package/docs/functions/downloadFile.md +58 -0
  24. package/docs/functions/emptyDir.md +28 -0
  25. package/docs/functions/emptyDirSync.md +25 -0
  26. package/docs/functions/exists.md +29 -0
  27. package/docs/functions/existsSync.md +26 -0
  28. package/docs/functions/generateTempPath.md +27 -0
  29. package/docs/functions/getFileDataByHandle.md +27 -0
  30. package/docs/functions/getSyncMessenger.md +22 -0
  31. package/docs/functions/isDirectoryHandle.md +27 -0
  32. package/docs/functions/isFileHandle.md +27 -0
  33. package/docs/functions/isFileHandleLike.md +27 -0
  34. package/docs/functions/isOPFSSupported.md +21 -0
  35. package/docs/functions/isTempPath.md +27 -0
  36. package/docs/functions/mkTemp.md +28 -0
  37. package/docs/functions/mkTempSync.md +25 -0
  38. package/docs/functions/mkdir.md +27 -0
  39. package/docs/functions/mkdirSync.md +25 -0
  40. package/docs/functions/move.md +34 -0
  41. package/docs/functions/moveSync.md +30 -0
  42. package/docs/functions/pruneTemp.md +28 -0
  43. package/docs/functions/pruneTempSync.md +25 -0
  44. package/docs/functions/readBlobFile.md +28 -0
  45. package/docs/functions/readBlobFileSync.md +25 -0
  46. package/docs/functions/readDir.md +28 -0
  47. package/docs/functions/readDirSync.md +26 -0
  48. package/docs/functions/readFile.md +132 -0
  49. package/docs/functions/readFileSync.md +70 -0
  50. package/docs/functions/readJsonFile.md +35 -0
  51. package/docs/functions/readJsonFileSync.md +31 -0
  52. package/docs/functions/readTextFile.md +28 -0
  53. package/docs/functions/readTextFileSync.md +25 -0
  54. package/docs/functions/remove.md +27 -0
  55. package/docs/functions/removeSync.md +25 -0
  56. package/docs/functions/setSyncMessenger.md +26 -0
  57. package/docs/functions/startSyncAgent.md +21 -0
  58. package/docs/functions/stat.md +27 -0
  59. package/docs/functions/statSync.md +25 -0
  60. package/docs/functions/toFileSystemHandleLike.md +27 -0
  61. package/docs/functions/unzip.md +32 -0
  62. package/docs/functions/unzipFromUrl.md +36 -0
  63. package/docs/functions/unzipSync.md +26 -0
  64. package/docs/functions/uploadFile.md +33 -0
  65. package/docs/functions/writeFile.md +32 -0
  66. package/docs/functions/writeFileSync.md +30 -0
  67. package/docs/functions/zip.md +65 -0
  68. package/docs/functions/zipFromUrl.md +63 -0
  69. package/docs/functions/zipSync.md +55 -0
  70. package/docs/interfaces/CopyOptions.md +17 -0
  71. package/docs/interfaces/DownloadFileTempResponse.md +18 -0
  72. package/docs/interfaces/ErrorLike.md +18 -0
  73. package/docs/interfaces/ExistsOptions.md +18 -0
  74. package/docs/interfaces/FileLike.md +21 -0
  75. package/docs/interfaces/FileSystemFileHandleLike.md +25 -0
  76. package/docs/interfaces/FileSystemHandleLike.md +22 -0
  77. package/docs/interfaces/MoveOptions.md +17 -0
  78. package/docs/interfaces/ReadDirEntry.md +18 -0
  79. package/docs/interfaces/ReadDirEntrySync.md +18 -0
  80. package/docs/interfaces/ReadDirOptions.md +17 -0
  81. package/docs/interfaces/ReadOptions.md +17 -0
  82. package/docs/interfaces/SyncAgentOptions.md +19 -0
  83. package/docs/interfaces/TempOptions.md +19 -0
  84. package/docs/interfaces/UploadRequestInit.md +21 -0
  85. package/docs/interfaces/WriteOptions.md +19 -0
  86. package/docs/interfaces/ZipOptions.md +17 -0
  87. package/docs/type-aliases/FileEncoding.md +15 -0
  88. package/docs/type-aliases/FsRequestInit.md +15 -0
  89. package/docs/type-aliases/ReadFileContent.md +15 -0
  90. package/docs/type-aliases/WriteFileContent.md +15 -0
  91. package/docs/type-aliases/WriteSyncFileContent.md +16 -0
  92. package/docs/variables/CURRENT_DIR.md +15 -0
  93. package/docs/variables/NOT_FOUND_ERROR.md +18 -0
  94. package/docs/variables/ROOT_DIR.md +15 -0
  95. package/docs/variables/TMP_DIR.md +15 -0
  96. package/package.json +141 -0
  97. package/src/fs/assertions.ts +63 -0
  98. package/src/fs/constants.ts +63 -0
  99. package/src/fs/defines.ts +352 -0
  100. package/src/fs/helpers.ts +338 -0
  101. package/src/fs/opfs_core.ts +413 -0
  102. package/src/fs/opfs_download.ts +174 -0
  103. package/src/fs/opfs_ext.ts +504 -0
  104. package/src/fs/opfs_tmp.ts +131 -0
  105. package/src/fs/opfs_unzip.ts +168 -0
  106. package/src/fs/opfs_upload.ts +126 -0
  107. package/src/fs/opfs_zip.ts +314 -0
  108. package/src/fs/support.ts +36 -0
  109. package/src/fs/utils.ts +176 -0
  110. package/src/mod.ts +41 -0
  111. package/src/worker/helpers.ts +168 -0
  112. package/src/worker/opfs_worker.ts +298 -0
  113. package/src/worker/opfs_worker_adapter.ts +666 -0
  114. package/src/worker/shared.ts +400 -0
@@ -0,0 +1,413 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+ /** ----------------------------------------------------------------------
4
+ * Copyright ©
5
+ * Jiang Jie
6
+ * 2024, 2025
7
+ * Pellegrino Prevete
8
+ * 2025
9
+ *
10
+ * All rights reserved
11
+ * ----------------------------------------------------------------------
12
+ *
13
+ * This program is free software: you can redistribute it and/or modify
14
+ * it under the terms of the GNU General Public License as published by
15
+ * the Free Software Foundation, either version 3 of the License, or
16
+ * (at your option) any later version.
17
+ *
18
+ * This program is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License
24
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
25
+ */
26
+
27
+ import { basename,
28
+ dirname,
29
+ join } from '@std/path/posix';
30
+ import { Err,
31
+ Ok,
32
+ RESULT_VOID,
33
+ type AsyncIOResult,
34
+ type AsyncVoidIOResult } from 'happy-rusty';
35
+ import { assertAbsolutePath } from './assertions.ts';
36
+ import { NOT_FOUND_ERROR } from './constants.ts';
37
+ import type { ReadDirEntry,
38
+ ReadDirOptions,
39
+ ReadFileContent,
40
+ ReadOptions,
41
+ WriteFileContent,
42
+ WriteOptions } from './defines.ts';
43
+ import { getDirHandle,
44
+ getFileHandle,
45
+ isNotFoundError,
46
+ isRootPath } from './helpers.ts';
47
+ import { isDirectoryHandle } from './utils.ts';
48
+
49
+ /**
50
+ * Creates a new file at the specified path same as `touch`.
51
+ *
52
+ * @param filePath - The path of the file to create.
53
+ * @returns A promise that resolves to an `AsyncIOResult` indicating whether the file was successfully created.
54
+ */
55
+ export async function
56
+ createFile(
57
+ filePath:
58
+ string):
59
+ AsyncVoidIOResult {
60
+ assertAbsolutePath(
61
+ filePath);
62
+ const
63
+ fileHandleRes =
64
+ await getFileHandle(
65
+ filePath,
66
+ { create:
67
+ true });
68
+ return fileHandleRes.and(
69
+ RESULT_VOID);
70
+ }
71
+
72
+ /**
73
+ * Creates a new directory at the specified path same as `mkdir -p`.
74
+ *
75
+ * @param dirPath - The path where the new directory will be created.
76
+ * @returns A promise that resolves to an `AsyncIOResult` indicating whether the directory was successfully created.
77
+ */
78
+ export async function
79
+ mkdir(
80
+ dirPath:
81
+ string):
82
+ AsyncVoidIOResult {
83
+ assertAbsolutePath(
84
+ dirPath);
85
+ const
86
+ dirHandleRes =
87
+ await getDirHandle(
88
+ dirPath,
89
+ { create:
90
+ true,
91
+ });
92
+ return dirHandleRes.and(
93
+ RESULT_VOID);
94
+ }
95
+
96
+ /**
97
+ * Reads the contents of a directory at the specified path.
98
+ *
99
+ * @param dirPath - The path of the directory to read.
100
+ * @param options - Options of readdir.
101
+ * @returns A promise that resolves to an `AsyncIOResult` containing an async iterable iterator over the entries of the directory.
102
+ */
103
+ export async function
104
+ readDir(
105
+ dirPath:
106
+ string,
107
+ options?:
108
+ ReadDirOptions):
109
+ AsyncIOResult<AsyncIterableIterator<ReadDirEntry>> {
110
+ assertAbsolutePath(
111
+ dirPath);
112
+ const
113
+ dirHandleRes =
114
+ await getDirHandle(
115
+ dirPath);
116
+ async function*
117
+ read(
118
+ dirHandle:
119
+ FileSystemDirectoryHandle,
120
+ subDirPath:
121
+ string):
122
+ AsyncIterableIterator<ReadDirEntry> {
123
+ const
124
+ entries =
125
+ dirHandle.entries();
126
+ for await ( const [ name,
127
+ handle ] of entries) {
128
+ // relative path from `dirPath`
129
+ const
130
+ path =
131
+ subDirPath === dirPath ? name : join(
132
+ subDirPath,
133
+ name);
134
+ yield {
135
+ path,
136
+ handle,
137
+ };
138
+ if ( isDirectoryHandle(
139
+ handle) && options?.recursive ) {
140
+ yield* read(
141
+ await dirHandle.getDirectoryHandle(
142
+ name),
143
+ path);
144
+ }
145
+ }
146
+ }
147
+ return dirHandleRes.andThen(
148
+ x => Ok(
149
+ read(
150
+ x,
151
+ dirPath)));
152
+ }
153
+
154
+ /**
155
+ * Reads the content of a file at the specified path as a File.
156
+ *
157
+ * @param filePath - The path of the file to read.
158
+ * @param options - Read options specifying the 'blob' encoding.
159
+ * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a File.
160
+ */
161
+ export function
162
+ readFile(
163
+ filePath:
164
+ string,
165
+ options:
166
+ ReadOptions & { encoding:
167
+ 'blob'; }):
168
+ AsyncIOResult<File>;
169
+
170
+ /**
171
+ * Reads the content of a file at the specified path as a string.
172
+ *
173
+ * @param filePath - The path of the file to read.
174
+ * @param options - Read options specifying the 'utf8' encoding.
175
+ * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a string.
176
+ */
177
+ export function
178
+ readFile(
179
+ filePath:
180
+ string,
181
+ options:
182
+ ReadOptions & { encoding:
183
+ 'utf8'; }):
184
+ AsyncIOResult<string>;
185
+
186
+ /**
187
+ * Reads the content of a file at the specified path as an ArrayBuffer by default.
188
+ *
189
+ * @param filePath - The path of the file to read.
190
+ * @param options - Read options specifying the 'binary' encoding.
191
+ * @returns A promise that resolves to an `AsyncIOResult` containing the file content as an ArrayBuffer.
192
+ */
193
+ export function
194
+ readFile(
195
+ filePath:
196
+ string,
197
+ options?:
198
+ ReadOptions & { encoding:
199
+ 'binary'; }):
200
+ AsyncIOResult<ArrayBuffer>;
201
+
202
+ /**
203
+ * Reads the content of a file at the specified path with the specified options.
204
+ *
205
+ * @template T The type of the content to read from the file.
206
+ * @param filePath - The path of the file to read.
207
+ * @param options - Optional read options.
208
+ * @returns A promise that resolves to an `AsyncIOResult` containing the file content.
209
+ */
210
+ export async function
211
+ readFile<T extends ReadFileContent>(
212
+ filePath:
213
+ string,
214
+ options?:
215
+ ReadOptions):
216
+ AsyncIOResult<T> {
217
+ assertAbsolutePath(
218
+ filePath);
219
+ const
220
+ fileHandleRes =
221
+ await getFileHandle(
222
+ filePath);
223
+ return fileHandleRes.andThenAsync(
224
+ async fileHandle => {
225
+ const
226
+ file =
227
+ await fileHandle.getFile();
228
+ switch ( options?.encoding ) {
229
+ case 'blob': {
230
+ return Ok(file as unknown as T);
231
+ }
232
+ case 'utf8': {
233
+ const
234
+ text =
235
+ await file.text();
236
+ return Ok(text as unknown as T);
237
+ }
238
+ default: {
239
+ const
240
+ data =
241
+ await file.arrayBuffer();
242
+ return Ok(data as unknown as T);
243
+ }
244
+ }
245
+ });
246
+ }
247
+
248
+ /**
249
+ * Removes a file or directory at the specified path same as `rm -rf`.
250
+ *
251
+ * @param path - The path of the file or directory to remove.
252
+ * @returns A promise that resolves to an `AsyncIOResult` indicating whether the file or directory was successfully removed.
253
+ */
254
+ export async function
255
+ remove(
256
+ path:
257
+ string):
258
+ AsyncVoidIOResult {
259
+ assertAbsolutePath(
260
+ path);
261
+ const
262
+ dirPath =
263
+ dirname(
264
+ path);
265
+ const
266
+ childName =
267
+ basename(
268
+ path);
269
+ const
270
+ dirHandleRes =
271
+ await getDirHandle(
272
+ dirPath);
273
+ return ( await dirHandleRes.andThenAsync(
274
+ async (
275
+ dirHandle):
276
+ AsyncVoidIOResult => {
277
+ try {
278
+ // root
279
+ if ( isRootPath(
280
+ dirPath) &&
281
+ isRootPath(
282
+ childName) ) {
283
+ // TODO ts not support yet
284
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
285
+ await ( dirHandle as any ).remove(
286
+ { recursive:
287
+ true });
288
+ } else {
289
+ await dirHandle.removeEntry(
290
+ childName,
291
+ { recursive:
292
+ true });
293
+ }
294
+ } catch (
295
+ _error) {
296
+ return Err(_error as DOMException);
297
+ }
298
+ return RESULT_VOID;
299
+ })).orElse<Error>(
300
+ _error => {
301
+ // not found as success
302
+ return isNotFoundError(
303
+ _error) ? RESULT_VOID : Err(
304
+ _error);
305
+ });
306
+ }
307
+
308
+ /**
309
+ * Retrieves the status of a file or directory at the specified path.
310
+ *
311
+ * @param path - The path of the file or directory to retrieve status for.
312
+ * @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemHandle`.
313
+ */
314
+ export async function
315
+ stat(
316
+ path:
317
+ string):
318
+ AsyncIOResult<FileSystemHandle> {
319
+ assertAbsolutePath(
320
+ path);
321
+ const
322
+ dirPath =
323
+ dirname(
324
+ path);
325
+ const
326
+ childName =
327
+ basename(
328
+ path);
329
+ const
330
+ dirHandleRes =
331
+ await getDirHandle(
332
+ dirPath);
333
+ if ( !childName ) {
334
+ // root
335
+ return dirHandleRes;
336
+ }
337
+ return dirHandleRes.andThenAsync(
338
+ async dirHandle => {
339
+ // currently only rely on traversal inspection
340
+ for await ( const [ name,
341
+ handle] of dirHandle.entries() ) {
342
+ if ( name === childName ) {
343
+ return Ok(
344
+ handle);
345
+ }
346
+ }
347
+ const
348
+ err =
349
+ new Error(
350
+ `${ NOT_FOUND_ERROR }: '${ childName }' ` +
351
+ `does not exist. Full path is '${ path }'.`);
352
+ err.name =
353
+ NOT_FOUND_ERROR;
354
+ return Err(
355
+ err);
356
+ });
357
+ }
358
+
359
+ /**
360
+ * Writes content to a file at the specified path.
361
+ *
362
+ * @param filePath - The path of the file to write to.
363
+ * @param contents - The content to write to the file.
364
+ * @param options - Optional write options.
365
+ * @returns A promise that resolves to an `AsyncIOResult` indicating whether the file was successfully written.
366
+ */
367
+ export async function
368
+ writeFile(
369
+ filePath:
370
+ string,
371
+ contents:
372
+ WriteFileContent,
373
+ options?:
374
+ WriteOptions):
375
+ AsyncVoidIOResult {
376
+ assertAbsolutePath(
377
+ filePath);
378
+ // create as default
379
+ const { append = false, create = true } = options ?? {};
380
+ const
381
+ fileHandleRes =
382
+ await getFileHandle(
383
+ filePath,
384
+ { create });
385
+ return fileHandleRes.andThenAsync(
386
+ async fileHandle => {
387
+ const
388
+ writable =
389
+ await fileHandle.createWritable(
390
+ { keepExistingData:
391
+ append });
392
+ const
393
+ params:
394
+ WriteParams =
395
+ { type:
396
+ 'write',
397
+ data:
398
+ contents,
399
+ };
400
+ // append?
401
+ if ( append ) {
402
+ const
403
+ { size } =
404
+ await fileHandle.getFile();
405
+ params.position =
406
+ size;
407
+ }
408
+ await writable.write(
409
+ params);
410
+ await writable.close();
411
+ return RESULT_VOID;
412
+ });
413
+ }
@@ -0,0 +1,174 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+ /** ----------------------------------------------------------------------
4
+ * Copyright ©
5
+ * Jiang Jie
6
+ * 2024, 2025
7
+ * Pellegrino Prevete
8
+ * 2025
9
+ *
10
+ * All rights reserved
11
+ * ----------------------------------------------------------------------
12
+ *
13
+ * This program is free software: you can redistribute it and/or modify
14
+ * it under the terms of the GNU General Public License as published by
15
+ * the Free Software Foundation, either version 3 of the License, or
16
+ * (at your option) any later version.
17
+ *
18
+ * This program is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License
24
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
25
+ */
26
+
27
+ import { fetchT,
28
+ type FetchResponse,
29
+ type FetchTask } from '@happy-ts/fetch-t';
30
+ import { extname } from '@std/path/posix';
31
+ import { Err,
32
+ Ok } from 'happy-rusty';
33
+ import { assertAbsolutePath,
34
+ assertFileUrl } from './assertions.ts';
35
+ import type { DownloadFileTempResponse,
36
+ FsRequestInit } from './defines.ts';
37
+ import { createAbortError } from './helpers.ts';
38
+ import { writeFile } from './opfs_core.ts';
39
+ import { generateTempPath } from './utils.ts';
40
+
41
+ /**
42
+ * Downloads a file from a URL and saves it to a temporary file.
43
+ * The returned response will contain the temporary file path.
44
+ *
45
+ * @param fileUrl - The URL of the file to download.
46
+ * @param requestInit - Optional request initialization parameters.
47
+ * @returns A task that can be aborted and contains the result of the download.
48
+ */
49
+ export function
50
+ downloadFile(
51
+ fileUrl:
52
+ string,
53
+ requestInit?:
54
+ FsRequestInit):
55
+ FetchTask<DownloadFileTempResponse>;
56
+
57
+ /**
58
+ * Downloads a file from a URL and saves it to the specified path.
59
+ *
60
+ * @param fileUrl - The URL of the file to download.
61
+ * @param filePath - The path where the downloaded file will be saved.
62
+ * @param requestInit - Optional request initialization parameters.
63
+ * @returns A task that can be aborted and contains the result of the download.
64
+ */
65
+ export function
66
+ downloadFile(
67
+ fileUrl:
68
+ string,
69
+ filePath:
70
+ string,
71
+ requestInit?:
72
+ FsRequestInit):
73
+ FetchTask<Response>;
74
+ export function
75
+ downloadFile(
76
+ fileUrl:
77
+ string,
78
+ filePath?:
79
+ string | FsRequestInit,
80
+ requestInit?:
81
+ FsRequestInit):
82
+ FetchTask<Response | DownloadFileTempResponse> {
83
+ let
84
+ aborted:
85
+ boolean,
86
+ saveToTemp;
87
+ assertFileUrl(
88
+ fileUrl);
89
+ saveToTemp =
90
+ false;
91
+ if ( typeof filePath === 'string' ) {
92
+ assertAbsolutePath(
93
+ filePath);
94
+ }
95
+ else {
96
+ requestInit =
97
+ filePath;
98
+ // save to a temporary file, reserve the extension
99
+ filePath =
100
+ generateTempPath(
101
+ { extname:
102
+ extname(
103
+ fileUrl) });
104
+ saveToTemp =
105
+ true;
106
+ }
107
+ aborted =
108
+ false;
109
+ const
110
+ fetchTask =
111
+ fetchT(
112
+ fileUrl,
113
+ { redirect:
114
+ 'follow',
115
+ ...requestInit,
116
+ abortable:
117
+ true });
118
+ const
119
+ response =
120
+ ( async ():
121
+ FetchResponse<Response> => {
122
+ const
123
+ responseRes =
124
+ await fetchTask.response;
125
+ return responseRes.andThenAsync(
126
+ async response => {
127
+ const
128
+ blob =
129
+ await response.blob();
130
+ // maybe aborted
131
+ if ( aborted ) {
132
+ return Err(
133
+ createAbortError());
134
+ }
135
+ const
136
+ writeRes =
137
+ await writeFile(filePath, blob);
138
+ return writeRes.and(
139
+ Ok(response));
140
+ });
141
+ })();
142
+ return {
143
+ abort(
144
+ reason?:
145
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
146
+ any):
147
+ void {
148
+ aborted =
149
+ true;
150
+ fetchTask.abort(
151
+ reason);
152
+ },
153
+ get aborted():
154
+ boolean {
155
+ return aborted;
156
+ },
157
+ get response():
158
+ FetchResponse<Response | DownloadFileTempResponse> {
159
+ return saveToTemp ?
160
+ response.then(
161
+ res => {
162
+ return res.map<DownloadFileTempResponse>(
163
+ rawResponse => {
164
+ return {
165
+ tempFilePath:
166
+ filePath,
167
+ rawResponse,
168
+ };
169
+ });
170
+ }) :
171
+ response;
172
+ },
173
+ };
174
+ }