@capacitor/filesystem 5.0.6-nightly-20230712T151609.0 → 5.1.1-nightly-20230713T150800.0
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/README.md +83 -2
- package/android/src/main/java/com/capacitorjs/plugins/filesystem/Filesystem.java +96 -1
- package/android/src/main/java/com/capacitorjs/plugins/filesystem/FilesystemPlugin.java +33 -1
- package/dist/docs.json +211 -2
- package/dist/esm/definitions.d.ts +78 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +8 -1
- package/dist/esm/web.js +54 -1
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +53 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +53 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/Filesystem.swift +157 -0
- package/ios/Plugin/FilesystemPlugin.m +1 -0
- package/ios/Plugin/FilesystemPlugin.swift +17 -0
- package/package.json +5 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Foundation
|
|
2
|
+
import Capacitor
|
|
2
3
|
|
|
3
4
|
@objc public class Filesystem: NSObject {
|
|
4
5
|
|
|
@@ -21,6 +22,8 @@ import Foundation
|
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
public typealias ProgressEmitter = (_ bytes: Int64, _ contentLength: Int64) -> Void
|
|
26
|
+
|
|
24
27
|
public func readFile(at fileUrl: URL, with encoding: String?) throws -> String {
|
|
25
28
|
if encoding != nil {
|
|
26
29
|
let data = try String(contentsOf: fileUrl, encoding: .utf8)
|
|
@@ -176,4 +179,158 @@ import Foundation
|
|
|
176
179
|
return URL(string: path)
|
|
177
180
|
}
|
|
178
181
|
}
|
|
182
|
+
|
|
183
|
+
// swiftlint:disable function_body_length
|
|
184
|
+
@objc public func downloadFile(call: CAPPluginCall, emitter: @escaping ProgressEmitter, config: InstanceConfiguration?) throws {
|
|
185
|
+
let directory = call.getString("directory", "DOCUMENTS")
|
|
186
|
+
guard let path = call.getString("path") else {
|
|
187
|
+
call.reject("Invalid file path")
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
func handleDownload(downloadLocation: URL?, response: URLResponse?, error: Error?) {
|
|
192
|
+
if let error = error {
|
|
193
|
+
CAPLog.print("Error on download file", String(describing: downloadLocation), String(describing: response), String(describing: error))
|
|
194
|
+
call.reject(error.localizedDescription, "DOWNLOAD", error, nil)
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if let httpResponse = response as? HTTPURLResponse {
|
|
199
|
+
HttpRequestHandler.setCookiesFromResponse(httpResponse, config)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
guard let location = downloadLocation else {
|
|
203
|
+
call.reject("Unable to get file after downloading")
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let fileManager = FileManager.default
|
|
208
|
+
|
|
209
|
+
if let foundDir = getDirectory(directory: directory) {
|
|
210
|
+
let dir = fileManager.urls(for: foundDir, in: .userDomainMask).first
|
|
211
|
+
|
|
212
|
+
do {
|
|
213
|
+
let dest = dir!.appendingPathComponent(path)
|
|
214
|
+
CAPLog.print("Attempting to write to file destination: \(dest.absoluteString)")
|
|
215
|
+
|
|
216
|
+
if !FileManager.default.fileExists(atPath: dest.deletingLastPathComponent().absoluteString) {
|
|
217
|
+
try FileManager.default.createDirectory(at: dest.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: nil)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if FileManager.default.fileExists(atPath: dest.relativePath) {
|
|
221
|
+
do {
|
|
222
|
+
CAPLog.print("File already exists. Attempting to remove file before writing.")
|
|
223
|
+
try fileManager.removeItem(at: dest)
|
|
224
|
+
} catch let error {
|
|
225
|
+
call.reject("Unable to remove existing file: \(error.localizedDescription)")
|
|
226
|
+
return
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
try fileManager.moveItem(at: location, to: dest)
|
|
231
|
+
CAPLog.print("Downloaded file successfully! \(dest.absoluteString)")
|
|
232
|
+
call.resolve(["path": dest.absoluteString])
|
|
233
|
+
} catch let error {
|
|
234
|
+
call.reject("Unable to download file: \(error.localizedDescription)", "DOWNLOAD", error)
|
|
235
|
+
return
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
call.reject("Unable to download file. Couldn't find directory \(directory)")
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
guard var urlString = call.getString("url") else { throw URLError(.badURL) }
|
|
243
|
+
let method = call.getString("method", "GET")
|
|
244
|
+
|
|
245
|
+
let headers = (call.getObject("headers") ?? [:]) as [String: Any]
|
|
246
|
+
let params = (call.getObject("params") ?? [:]) as [String: Any]
|
|
247
|
+
let responseType = call.getString("responseType", "text")
|
|
248
|
+
let connectTimeout = call.getDouble("connectTimeout")
|
|
249
|
+
let readTimeout = call.getDouble("readTimeout")
|
|
250
|
+
|
|
251
|
+
if urlString == urlString.removingPercentEncoding {
|
|
252
|
+
guard let encodedUrlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { throw URLError(.badURL) }
|
|
253
|
+
urlString = encodedUrlString
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
let progress = call.getBool("progress", false)
|
|
257
|
+
|
|
258
|
+
let request = try HttpRequestHandler.CapacitorHttpRequestBuilder()
|
|
259
|
+
.setUrl(urlString)
|
|
260
|
+
.setMethod(method)
|
|
261
|
+
.setUrlParams(params)
|
|
262
|
+
.openConnection()
|
|
263
|
+
.build()
|
|
264
|
+
|
|
265
|
+
request.setRequestHeaders(headers)
|
|
266
|
+
|
|
267
|
+
// Timeouts in iOS are in seconds. So read the value in millis and divide by 1000
|
|
268
|
+
let timeout = (connectTimeout ?? readTimeout ?? 600000.0) / 1000.0
|
|
269
|
+
request.setTimeout(timeout)
|
|
270
|
+
|
|
271
|
+
if let data = call.options["data"] as? JSValue {
|
|
272
|
+
do {
|
|
273
|
+
try request.setRequestBody(data)
|
|
274
|
+
} catch {
|
|
275
|
+
// Explicitly reject if the http request body was not set successfully,
|
|
276
|
+
// so as to not send a known malformed request, and to provide the developer with additional context.
|
|
277
|
+
call.reject(error.localizedDescription, (error as NSError).domain, error, nil)
|
|
278
|
+
return
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
var session: URLSession!
|
|
283
|
+
var task: URLSessionDownloadTask!
|
|
284
|
+
let urlRequest = request.getUrlRequest()
|
|
285
|
+
|
|
286
|
+
if progress {
|
|
287
|
+
class ProgressDelegate: NSObject, URLSessionDataDelegate, URLSessionDownloadDelegate {
|
|
288
|
+
private var handler: (URL?, URLResponse?, Error?) -> Void
|
|
289
|
+
private var downloadLocation: URL?
|
|
290
|
+
private var response: URLResponse?
|
|
291
|
+
private var emitter: (Int64, Int64) -> Void
|
|
292
|
+
private var lastEmitTimestamp: TimeInterval = 0.0
|
|
293
|
+
|
|
294
|
+
init(downloadHandler: @escaping (URL?, URLResponse?, Error?) -> Void, progressEmitter: @escaping (Int64, Int64) -> Void) {
|
|
295
|
+
handler = downloadHandler
|
|
296
|
+
emitter = progressEmitter
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
|
|
300
|
+
let currentTimestamp = Date().timeIntervalSince1970
|
|
301
|
+
let timeElapsed = currentTimestamp - lastEmitTimestamp
|
|
302
|
+
|
|
303
|
+
if totalBytesExpectedToWrite > 0 {
|
|
304
|
+
if timeElapsed >= 0.1 {
|
|
305
|
+
emitter(totalBytesWritten, totalBytesExpectedToWrite)
|
|
306
|
+
lastEmitTimestamp = currentTimestamp
|
|
307
|
+
}
|
|
308
|
+
} else {
|
|
309
|
+
emitter(totalBytesWritten, 0)
|
|
310
|
+
lastEmitTimestamp = currentTimestamp
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
|
|
315
|
+
downloadLocation = location
|
|
316
|
+
handler(downloadLocation, downloadTask.response, downloadTask.error)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
|
|
320
|
+
if error != nil {
|
|
321
|
+
handler(downloadLocation, task.response, error)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let progressDelegate = ProgressDelegate(downloadHandler: handleDownload, progressEmitter: emitter)
|
|
327
|
+
session = URLSession(configuration: .default, delegate: progressDelegate, delegateQueue: nil)
|
|
328
|
+
task = session.downloadTask(with: urlRequest)
|
|
329
|
+
} else {
|
|
330
|
+
task = URLSession.shared.downloadTask(with: urlRequest, completionHandler: handleDownload)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
task.resume()
|
|
334
|
+
}
|
|
335
|
+
// swiftlint:enable function_body_length
|
|
179
336
|
}
|
|
@@ -17,4 +17,5 @@ CAP_PLUGIN(FilesystemPlugin, "Filesystem",
|
|
|
17
17
|
CAP_PLUGIN_METHOD(copy, CAPPluginReturnPromise);
|
|
18
18
|
CAP_PLUGIN_METHOD(checkPermissions, CAPPluginReturnPromise);
|
|
19
19
|
CAP_PLUGIN_METHOD(requestPermissions, CAPPluginReturnPromise);
|
|
20
|
+
CAP_PLUGIN_METHOD(downloadFile, CAPPluginReturnPromise);
|
|
20
21
|
)
|
|
@@ -345,6 +345,23 @@ public class FilesystemPlugin: CAPPlugin {
|
|
|
345
345
|
])
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
+
@objc func downloadFile(_ call: CAPPluginCall) {
|
|
349
|
+
guard let url = call.getString("url") else { return call.reject("Must provide a URL") }
|
|
350
|
+
let progressEmitter: Filesystem.ProgressEmitter = { bytes, contentLength in
|
|
351
|
+
self.notifyListeners("progress", data: [
|
|
352
|
+
"url": url,
|
|
353
|
+
"bytes": bytes,
|
|
354
|
+
"contentLength": contentLength
|
|
355
|
+
])
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
do {
|
|
359
|
+
try implementation.downloadFile(call: call, emitter: progressEmitter, config: bridge?.config)
|
|
360
|
+
} catch let error {
|
|
361
|
+
call.reject(error.localizedDescription)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
348
365
|
/**
|
|
349
366
|
* Helper for handling errors
|
|
350
367
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor/filesystem",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1-nightly-20230713T150800.0",
|
|
4
4
|
"description": "The Filesystem API provides a NodeJS-like API for working with files on the device.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"publish:cocoapod": "pod trunk push ./CapacitorFilesystem.podspec --allow-warnings"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@capacitor/android": "^5.
|
|
49
|
-
"@capacitor/core": "^5.
|
|
48
|
+
"@capacitor/android": "^5.1.1",
|
|
49
|
+
"@capacitor/core": "^5.1.1",
|
|
50
50
|
"@capacitor/docgen": "0.2.0",
|
|
51
|
-
"@capacitor/ios": "^5.
|
|
51
|
+
"@capacitor/ios": "^5.1.1",
|
|
52
52
|
"@ionic/eslint-config": "^0.3.0",
|
|
53
53
|
"@ionic/prettier-config": "~1.0.1",
|
|
54
54
|
"@ionic/swiftlint-config": "^1.1.2",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"typescript": "~4.1.5"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@capacitor/core": "^5.
|
|
64
|
+
"@capacitor/core": "^5.1.1"
|
|
65
65
|
},
|
|
66
66
|
"prettier": "@ionic/prettier-config",
|
|
67
67
|
"swiftlint": "@ionic/swiftlint-config",
|