@simplysm/capacitor-plugin-file-system 13.0.99 → 14.0.1
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/android/build.gradle +1 -0
- package/android/src/main/kotlin/kr/co/simplysm/capacitor/filesystem/FileSystemPlugin.kt +306 -0
- package/android/src/main/kotlin/kr/co/simplysm/capacitor/filesystem/FileSystemProvider.kt +5 -0
- package/dist/FileSystem.d.ts +24 -24
- package/dist/FileSystem.js +103 -97
- package/dist/FileSystem.js.map +1 -6
- package/dist/FileSystemPlugin.js +2 -1
- package/dist/FileSystemPlugin.js.map +1 -6
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -6
- package/dist/web/FileSystemWeb.d.ts +3 -3
- package/dist/web/FileSystemWeb.js +64 -64
- package/dist/web/FileSystemWeb.js.map +1 -6
- package/dist/web/VirtualFileSystem.d.ts +6 -6
- package/dist/web/VirtualFileSystem.js +33 -36
- package/dist/web/VirtualFileSystem.js.map +1 -6
- package/package.json +6 -6
- package/src/FileSystem.ts +25 -25
- package/src/index.ts +1 -1
- package/src/web/FileSystemWeb.ts +7 -7
- package/src/web/VirtualFileSystem.ts +6 -6
- package/README.md +0 -98
- package/android/src/main/java/kr/co/simplysm/capacitor/filesystem/FileSystemPlugin.java +0 -305
- package/android/src/main/java/kr/co/simplysm/capacitor/filesystem/FileSystemProvider.java +0 -6
|
@@ -1,72 +1,72 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
2
|
import { VirtualFileSystem } from "./VirtualFileSystem.js";
|
|
3
3
|
import { bytes } from "@simplysm/core-common";
|
|
4
|
-
class FileSystemWeb extends WebPlugin {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
async requestPermissions() {
|
|
12
|
-
}
|
|
13
|
-
async readdir(options) {
|
|
14
|
-
const entry = await this._fs.getEntry(options.path);
|
|
15
|
-
if (!entry || entry.kind !== "dir") {
|
|
16
|
-
throw new Error("Directory does not exist");
|
|
4
|
+
export class FileSystemWeb extends WebPlugin {
|
|
5
|
+
_fs = new VirtualFileSystem("capacitor_web_virtual_fs");
|
|
6
|
+
_textEncoder = new TextEncoder();
|
|
7
|
+
_textDecoder = new TextDecoder();
|
|
8
|
+
async checkPermissions() {
|
|
9
|
+
return Promise.resolve({ granted: true });
|
|
17
10
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Return the Blob URL of a file.
|
|
28
|
-
* @warning The returned URI must be released by calling `URL.revokeObjectURL(uri)` after use.
|
|
29
|
-
* Failure to release may cause memory leaks.
|
|
30
|
-
*/
|
|
31
|
-
async getUri(options) {
|
|
32
|
-
const entry = await this._fs.getEntry(options.path);
|
|
33
|
-
if (!entry || entry.kind !== "file" || entry.dataBase64 == null) {
|
|
34
|
-
throw new Error("File not found: " + options.path);
|
|
11
|
+
async requestPermissions() { }
|
|
12
|
+
async readdir(options) {
|
|
13
|
+
const entry = await this._fs.getEntry(options.path);
|
|
14
|
+
if (!entry || entry.kind !== "dir") {
|
|
15
|
+
throw new Error("디렉토리가 존재하지 않습니다");
|
|
16
|
+
}
|
|
17
|
+
const files = await this._fs.listChildren(options.path);
|
|
18
|
+
return { files };
|
|
35
19
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
async writeFile(options) {
|
|
41
|
-
const idx = options.path.lastIndexOf("/");
|
|
42
|
-
const dir = idx === -1 ? "." : options.path.substring(0, idx) || "/";
|
|
43
|
-
await this._fs.ensureDir(dir);
|
|
44
|
-
const dataBase64 = options.encoding === "base64" ? options.data : bytes.toBase64(this._textEncoder.encode(options.data));
|
|
45
|
-
await this._fs.putEntry({ path: options.path, kind: "file", dataBase64 });
|
|
46
|
-
}
|
|
47
|
-
async readFile(options) {
|
|
48
|
-
const entry = await this._fs.getEntry(options.path);
|
|
49
|
-
if (!entry || entry.kind !== "file" || entry.dataBase64 == null) {
|
|
50
|
-
throw new Error("File not found: " + options.path);
|
|
20
|
+
async getStoragePath(options) {
|
|
21
|
+
const storagePath = "/webfs/" + options.type;
|
|
22
|
+
await this._fs.ensureDir(storagePath);
|
|
23
|
+
return { path: storagePath };
|
|
51
24
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
25
|
+
/**
|
|
26
|
+
* 파일의 Blob URL을 반환합니다.
|
|
27
|
+
* @warning 반환된 URI는 사용 후 `URL.revokeObjectURL(uri)`를 호출하여 해제해야 합니다.
|
|
28
|
+
* 해제하지 않으면 메모리 누수가 발생할 수 있습니다.
|
|
29
|
+
*/
|
|
30
|
+
async getUri(options) {
|
|
31
|
+
const entry = await this._fs.getEntry(options.path);
|
|
32
|
+
if (!entry || entry.kind !== "file" || entry.dataBase64 == null) {
|
|
33
|
+
throw new Error("파일을 찾을 수 없습니다: " + options.path);
|
|
34
|
+
}
|
|
35
|
+
const data = bytes.fromBase64(entry.dataBase64);
|
|
36
|
+
const blob = new Blob([data]);
|
|
37
|
+
return { uri: URL.createObjectURL(blob) };
|
|
38
|
+
}
|
|
39
|
+
async writeFile(options) {
|
|
40
|
+
const idx = options.path.lastIndexOf("/");
|
|
41
|
+
const dir = idx === -1 ? "." : options.path.substring(0, idx) || "/";
|
|
42
|
+
await this._fs.ensureDir(dir);
|
|
43
|
+
const dataBase64 = options.encoding === "base64"
|
|
44
|
+
? options.data
|
|
45
|
+
: bytes.toBase64(this._textEncoder.encode(options.data));
|
|
46
|
+
await this._fs.putEntry({ path: options.path, kind: "file", dataBase64 });
|
|
47
|
+
}
|
|
48
|
+
async readFile(options) {
|
|
49
|
+
const entry = await this._fs.getEntry(options.path);
|
|
50
|
+
if (!entry || entry.kind !== "file" || entry.dataBase64 == null) {
|
|
51
|
+
throw new Error("파일을 찾을 수 없습니다: " + options.path);
|
|
52
|
+
}
|
|
53
|
+
const data = options.encoding === "base64"
|
|
54
|
+
? entry.dataBase64
|
|
55
|
+
: this._textDecoder.decode(bytes.fromBase64(entry.dataBase64));
|
|
56
|
+
return { data };
|
|
57
|
+
}
|
|
58
|
+
async remove(options) {
|
|
59
|
+
const ok = await this._fs.deleteByPrefix(options.path);
|
|
60
|
+
if (!ok) {
|
|
61
|
+
throw new Error("삭제에 실패했습니다");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async mkdir(options) {
|
|
65
|
+
await this._fs.ensureDir(options.path);
|
|
66
|
+
}
|
|
67
|
+
async exists(options) {
|
|
68
|
+
const entry = await this._fs.getEntry(options.path);
|
|
69
|
+
return { exists: !!entry };
|
|
59
70
|
}
|
|
60
|
-
}
|
|
61
|
-
async mkdir(options) {
|
|
62
|
-
await this._fs.ensureDir(options.path);
|
|
63
|
-
}
|
|
64
|
-
async exists(options) {
|
|
65
|
-
const entry = await this._fs.getEntry(options.path);
|
|
66
|
-
return { exists: !!entry };
|
|
67
|
-
}
|
|
68
71
|
}
|
|
69
|
-
|
|
70
|
-
FileSystemWeb
|
|
71
|
-
};
|
|
72
|
-
//# sourceMappingURL=FileSystemWeb.js.map
|
|
72
|
+
//# sourceMappingURL=FileSystemWeb.js.map
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/web/FileSystemWeb.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,iBAAiB;AAE1B,SAAS,yBAAyB;AAClC,SAAS,aAAa;AAEf,MAAM,sBAAsB,UAAsC;AAAA,EACtD,MAAM,IAAI,kBAAkB,0BAA0B;AAAA,EACtD,eAAe,IAAI,YAAY;AAAA,EAC/B,eAAe,IAAI,YAAY;AAAA,EAEhD,MAAM,mBAAkD;AACtD,WAAO,QAAQ,QAAQ,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,qBAAoC;AAAA,EAAC;AAAA,EAE3C,MAAM,QAAQ,SAA2D;AACvE,UAAM,QAAQ,MAAM,KAAK,IAAI,SAAS,QAAQ,IAAI;AAClD,QAAI,CAAC,SAAS,MAAM,SAAS,OAAO;AAClC,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AACA,UAAM,QAAQ,MAAM,KAAK,IAAI,aAAa,QAAQ,IAAI;AACtD,WAAO,EAAE,MAAM;AAAA,EACjB;AAAA,EAEA,MAAM,eAAe,SAA2D;AAC9E,UAAM,cAAc,YAAY,QAAQ;AACxC,UAAM,KAAK,IAAI,UAAU,WAAW;AACpC,WAAO,EAAE,MAAM,YAAY;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,SAAqD;AAChE,UAAM,QAAQ,MAAM,KAAK,IAAI,SAAS,QAAQ,IAAI;AAClD,QAAI,CAAC,SAAS,MAAM,SAAS,UAAU,MAAM,cAAc,MAAM;AAC/D,YAAM,IAAI,MAAM,qBAAqB,QAAQ,IAAI;AAAA,IACnD;AACA,UAAM,OAAO,MAAM,WAAW,MAAM,UAAU;AAC9C,UAAM,OAAO,IAAI,KAAK,CAAC,IAAgB,CAAC;AACxC,WAAO,EAAE,KAAK,IAAI,gBAAgB,IAAI,EAAE;AAAA,EAC1C;AAAA,EAEA,MAAM,UAAU,SAIE;AAChB,UAAM,MAAM,QAAQ,KAAK,YAAY,GAAG;AACxC,UAAM,MAAM,QAAQ,KAAK,MAAM,QAAQ,KAAK,UAAU,GAAG,GAAG,KAAK;AACjE,UAAM,KAAK,IAAI,UAAU,GAAG;AAC5B,UAAM,aACJ,QAAQ,aAAa,WACjB,QAAQ,OACR,MAAM,SAAS,KAAK,aAAa,OAAO,QAAQ,IAAI,CAAC;AAC3D,UAAM,KAAK,IAAI,SAAS,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,WAAW,CAAC;AAAA,EAC1E;AAAA,EAEA,MAAM,SAAS,SAGe;AAC5B,UAAM,QAAQ,MAAM,KAAK,IAAI,SAAS,QAAQ,IAAI;AAClD,QAAI,CAAC,SAAS,MAAM,SAAS,UAAU,MAAM,cAAc,MAAM;AAC/D,YAAM,IAAI,MAAM,qBAAqB,QAAQ,IAAI;AAAA,IACnD;AACA,UAAM,OACJ,QAAQ,aAAa,WACjB,MAAM,aACN,KAAK,aAAa,OAAO,MAAM,WAAW,MAAM,UAAU,CAAC;AACjE,WAAO,EAAE,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,OAAO,SAA0C;AACrD,UAAM,KAAK,MAAM,KAAK,IAAI,eAAe,QAAQ,IAAI;AACrD,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,MAAM,iBAAiB;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,SAA0C;AACpD,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,OAAO,SAAyD;AACpE,UAAM,QAAQ,MAAM,KAAK,IAAI,SAAS,QAAQ,IAAI;AAClD,WAAO,EAAE,QAAQ,CAAC,CAAC,MAAM;AAAA,EAC3B;AACF;",
|
|
5
|
-
"names": []
|
|
6
|
-
}
|
|
1
|
+
{"version":3,"file":"FileSystemWeb.js","sourceRoot":"","sources":["..\\..\\src\\web\\FileSystemWeb.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,12 +13,12 @@ export declare class VirtualFileSystem {
|
|
|
13
13
|
}): Promise<void>;
|
|
14
14
|
deleteByPrefix(pathPrefix: string): Promise<boolean>;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @param dirPath
|
|
18
|
-
* @returns
|
|
19
|
-
* @note
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* 디렉토리의 직접 하위 항목을 반환합니다.
|
|
17
|
+
* @param dirPath 조회할 디렉토리 경로
|
|
18
|
+
* @returns 하위 파일/디렉토리 목록
|
|
19
|
+
* @note 암시적 디렉토리 처리: 디렉토리 항목 없이 파일 경로만 존재하더라도
|
|
20
|
+
* 중간 경로를 디렉토리로 취급합니다. 예: "/a/b/c.txt"만 저장된 경우,
|
|
21
|
+
* listChildren("/a") 호출 시 "b"를 isDirectory: true로 반환합니다.
|
|
22
22
|
*/
|
|
23
23
|
listChildren(dirPath: string): Promise<FileInfo[]>;
|
|
24
24
|
ensureDir(dirPath: string): Promise<void>;
|
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
import { IndexedDbStore, IndexedDbVirtualFs } from "@simplysm/core-browser";
|
|
2
|
-
class VirtualFileSystem {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
2
|
+
export class VirtualFileSystem {
|
|
3
|
+
_STORE_NAME = "entries";
|
|
4
|
+
_db;
|
|
5
|
+
_vfs;
|
|
6
|
+
constructor(dbName) {
|
|
7
|
+
this._db = new IndexedDbStore(dbName, 1, [{ name: this._STORE_NAME, keyPath: "path" }]);
|
|
8
|
+
this._vfs = new IndexedDbVirtualFs(this._db, this._STORE_NAME, "path");
|
|
9
|
+
}
|
|
10
|
+
async getEntry(filePath) {
|
|
11
|
+
return this._vfs.getEntry(filePath);
|
|
12
|
+
}
|
|
13
|
+
async putEntry(entry) {
|
|
14
|
+
return this._vfs.putEntry(entry.path, entry.kind, entry.dataBase64);
|
|
15
|
+
}
|
|
16
|
+
async deleteByPrefix(pathPrefix) {
|
|
17
|
+
return this._vfs.deleteByPrefix(pathPrefix);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 디렉토리의 직접 하위 항목을 반환합니다.
|
|
21
|
+
* @param dirPath 조회할 디렉토리 경로
|
|
22
|
+
* @returns 하위 파일/디렉토리 목록
|
|
23
|
+
* @note 암시적 디렉토리 처리: 디렉토리 항목 없이 파일 경로만 존재하더라도
|
|
24
|
+
* 중간 경로를 디렉토리로 취급합니다. 예: "/a/b/c.txt"만 저장된 경우,
|
|
25
|
+
* listChildren("/a") 호출 시 "b"를 isDirectory: true로 반환합니다.
|
|
26
|
+
*/
|
|
27
|
+
async listChildren(dirPath) {
|
|
28
|
+
const prefix = dirPath === "/" ? "/" : dirPath + "/";
|
|
29
|
+
return this._vfs.listChildren(prefix);
|
|
30
|
+
}
|
|
31
|
+
async ensureDir(dirPath) {
|
|
32
|
+
return this._vfs.ensureDir((path) => path, dirPath);
|
|
33
|
+
}
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
VirtualFileSystem
|
|
37
|
-
};
|
|
38
|
-
//# sourceMappingURL=VirtualFileSystem.js.map
|
|
35
|
+
//# sourceMappingURL=VirtualFileSystem.js.map
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/web/VirtualFileSystem.ts"],
|
|
4
|
-
"mappings": "AAEA,SAAS,gBAAgB,0BAA0B;AAE5C,MAAM,kBAAkB;AAAA,EACZ,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EAEjB,YAAY,QAAgB;AAC1B,SAAK,MAAM,IAAI,eAAe,QAAQ,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,SAAS,OAAO,CAAC,CAAC;AACtF,SAAK,OAAO,IAAI,mBAAmB,KAAK,KAAK,KAAK,aAAa,MAAM;AAAA,EACvE;AAAA,EAEA,MAAM,SAAS,UAAuD;AACpE,WAAO,KAAK,KAAK,SAAS,QAAQ;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,OAAmF;AAChG,WAAO,KAAK,KAAK,SAAS,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU;AAAA,EACpE;AAAA,EAEA,MAAM,eAAe,YAAsC;AACzD,WAAO,KAAK,KAAK,eAAe,UAAU;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,SAAsC;AACvD,UAAM,SAAS,YAAY,MAAM,MAAM,UAAU;AACjD,WAAO,KAAK,KAAK,aAAa,MAAM;AAAA,EACtC;AAAA,EAEA,MAAM,UAAU,SAAgC;AAC9C,WAAO,KAAK,KAAK,UAAU,CAAC,SAAS,MAAM,OAAO;AAAA,EACpD;AACF;",
|
|
5
|
-
"names": []
|
|
6
|
-
}
|
|
1
|
+
{"version":3,"file":"VirtualFileSystem.js","sourceRoot":"","sources":["..\\..\\src\\web\\VirtualFileSystem.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5E,MAAM,OAAO,iBAAiB;IACX,WAAW,GAAG,SAAS,CAAC;IACxB,GAAG,CAAiB;IACpB,IAAI,CAAqB;IAE1C,YAAY,MAAc;QACxB,IAAI,CAAC,GAAG,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,IAAI,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAkE;QAC/E,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,UAAkB;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,MAAM,MAAM,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC;QACrD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAe;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/capacitor-plugin-file-system",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "14.0.1",
|
|
4
|
+
"description": "심플리즘 패키지 - Capacitor 파일 시스템 플러그인",
|
|
5
5
|
"author": "simplysm",
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/kslhunter/simplysm.git",
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
"android"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@simplysm/core-
|
|
22
|
-
"@simplysm/core-
|
|
21
|
+
"@simplysm/core-browser": "14.0.1",
|
|
22
|
+
"@simplysm/core-common": "14.0.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@capacitor/core": "^7.6.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@capacitor/core": "^7
|
|
28
|
+
"@capacitor/core": "^7"
|
|
29
29
|
},
|
|
30
30
|
"capacitor": {
|
|
31
31
|
"android": {
|
package/src/FileSystem.ts
CHANGED
|
@@ -11,14 +11,14 @@ const fileSystemPlugin = registerPlugin<FileSystemPlugin>("FileSystem", {
|
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* - Android 11+:
|
|
16
|
-
* - Android 10-: READ/WRITE_EXTERNAL_STORAGE
|
|
17
|
-
* - Browser: IndexedDB
|
|
14
|
+
* 파일 시스템 접근 플러그인
|
|
15
|
+
* - Android 11+: MANAGE_EXTERNAL_STORAGE 권한을 통한 전체 파일 시스템 접근
|
|
16
|
+
* - Android 10-: READ/WRITE_EXTERNAL_STORAGE 권한
|
|
17
|
+
* - Browser: IndexedDB 기반 에뮬레이션
|
|
18
18
|
*/
|
|
19
19
|
export abstract class FileSystem {
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* 권한 확인
|
|
22
22
|
*/
|
|
23
23
|
static async checkPermissions(): Promise<boolean> {
|
|
24
24
|
const result = await fileSystemPlugin.checkPermissions();
|
|
@@ -26,16 +26,16 @@ export abstract class FileSystem {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
* - Android 11+:
|
|
31
|
-
* - Android 10-:
|
|
29
|
+
* 권한 요청
|
|
30
|
+
* - Android 11+: 설정 화면으로 이동
|
|
31
|
+
* - Android 10-: 권한 대화상자 표시
|
|
32
32
|
*/
|
|
33
33
|
static async requestPermissions(): Promise<void> {
|
|
34
34
|
await fileSystemPlugin.requestPermissions();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* 디렉토리 읽기
|
|
39
39
|
*/
|
|
40
40
|
static async readdir(dirPath: string): Promise<FileInfo[]> {
|
|
41
41
|
const result = await fileSystemPlugin.readdir({ path: dirPath });
|
|
@@ -43,15 +43,15 @@ export abstract class FileSystem {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* @param type
|
|
48
|
-
* - external:
|
|
49
|
-
* - externalFiles:
|
|
50
|
-
* - externalCache:
|
|
51
|
-
* - externalMedia:
|
|
52
|
-
* - appData:
|
|
53
|
-
* - appFiles:
|
|
54
|
-
* - appCache:
|
|
46
|
+
* 저장소 경로 조회
|
|
47
|
+
* @param type 저장소 유형
|
|
48
|
+
* - external: 외부 저장소 루트 (Environment.getExternalStorageDirectory)
|
|
49
|
+
* - externalFiles: 앱 전용 외부 파일 디렉토리
|
|
50
|
+
* - externalCache: 앱 전용 외부 캐시 디렉토리
|
|
51
|
+
* - externalMedia: 앱 전용 외부 미디어 디렉토리
|
|
52
|
+
* - appData: 앱 데이터 디렉토리
|
|
53
|
+
* - appFiles: 앱 파일 디렉토리
|
|
54
|
+
* - appCache: 앱 캐시 디렉토리
|
|
55
55
|
*/
|
|
56
56
|
static async getStoragePath(type: StorageType): Promise<string> {
|
|
57
57
|
const result = await fileSystemPlugin.getStoragePath({ type });
|
|
@@ -59,7 +59,7 @@ export abstract class FileSystem {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
62
|
+
* 파일 URI 조회 (FileProvider)
|
|
63
63
|
*/
|
|
64
64
|
static async getUri(filePath: string): Promise<string> {
|
|
65
65
|
const result = await fileSystemPlugin.getUri({ path: filePath });
|
|
@@ -67,11 +67,11 @@ export abstract class FileSystem {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
70
|
+
* 파일 쓰기
|
|
71
71
|
*/
|
|
72
72
|
static async writeFile(filePath: string, data: string | Bytes): Promise<void> {
|
|
73
73
|
if (typeof data !== "string") {
|
|
74
|
-
// Bytes (Uint8Array) -
|
|
74
|
+
// Bytes (Uint8Array) - cross-realm 환경에서도 안전하게 동작
|
|
75
75
|
await fileSystemPlugin.writeFile({
|
|
76
76
|
path: filePath,
|
|
77
77
|
data: bytes.toBase64(data),
|
|
@@ -87,7 +87,7 @@ export abstract class FileSystem {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
|
-
*
|
|
90
|
+
* 파일 읽기 (기본: Bytes, encoding "utf8" 지정 시: string)
|
|
91
91
|
*/
|
|
92
92
|
static async readFile(filePath: string): Promise<Bytes>;
|
|
93
93
|
static async readFile(filePath: string, encoding: "utf8"): Promise<string>;
|
|
@@ -102,21 +102,21 @@ export abstract class FileSystem {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
*
|
|
105
|
+
* 파일/디렉토리 삭제 (재귀)
|
|
106
106
|
*/
|
|
107
107
|
static async remove(targetPath: string): Promise<void> {
|
|
108
108
|
await fileSystemPlugin.remove({ path: targetPath });
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
|
-
*
|
|
112
|
+
* 디렉토리 생성 (재귀)
|
|
113
113
|
*/
|
|
114
114
|
static async mkdir(targetPath: string): Promise<void> {
|
|
115
115
|
await fileSystemPlugin.mkdir({ path: targetPath });
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
|
-
*
|
|
119
|
+
* 존재 여부 확인
|
|
120
120
|
*/
|
|
121
121
|
static async exists(targetPath: string): Promise<boolean> {
|
|
122
122
|
const result = await fileSystemPlugin.exists({ path: targetPath });
|
package/src/index.ts
CHANGED
package/src/web/FileSystemWeb.ts
CHANGED
|
@@ -17,7 +17,7 @@ export class FileSystemWeb extends WebPlugin implements FileSystemPlugin {
|
|
|
17
17
|
async readdir(options: { path: string }): Promise<{ files: FileInfo[] }> {
|
|
18
18
|
const entry = await this._fs.getEntry(options.path);
|
|
19
19
|
if (!entry || entry.kind !== "dir") {
|
|
20
|
-
throw new Error("
|
|
20
|
+
throw new Error("디렉토리가 존재하지 않습니다");
|
|
21
21
|
}
|
|
22
22
|
const files = await this._fs.listChildren(options.path);
|
|
23
23
|
return { files };
|
|
@@ -30,14 +30,14 @@ export class FileSystemWeb extends WebPlugin implements FileSystemPlugin {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
* @warning
|
|
35
|
-
*
|
|
33
|
+
* 파일의 Blob URL을 반환합니다.
|
|
34
|
+
* @warning 반환된 URI는 사용 후 `URL.revokeObjectURL(uri)`를 호출하여 해제해야 합니다.
|
|
35
|
+
* 해제하지 않으면 메모리 누수가 발생할 수 있습니다.
|
|
36
36
|
*/
|
|
37
37
|
async getUri(options: { path: string }): Promise<{ uri: string }> {
|
|
38
38
|
const entry = await this._fs.getEntry(options.path);
|
|
39
39
|
if (!entry || entry.kind !== "file" || entry.dataBase64 == null) {
|
|
40
|
-
throw new Error("
|
|
40
|
+
throw new Error("파일을 찾을 수 없습니다: " + options.path);
|
|
41
41
|
}
|
|
42
42
|
const data = bytes.fromBase64(entry.dataBase64);
|
|
43
43
|
const blob = new Blob([data as BlobPart]);
|
|
@@ -65,7 +65,7 @@ export class FileSystemWeb extends WebPlugin implements FileSystemPlugin {
|
|
|
65
65
|
}): Promise<{ data: string }> {
|
|
66
66
|
const entry = await this._fs.getEntry(options.path);
|
|
67
67
|
if (!entry || entry.kind !== "file" || entry.dataBase64 == null) {
|
|
68
|
-
throw new Error("
|
|
68
|
+
throw new Error("파일을 찾을 수 없습니다: " + options.path);
|
|
69
69
|
}
|
|
70
70
|
const data =
|
|
71
71
|
options.encoding === "base64"
|
|
@@ -77,7 +77,7 @@ export class FileSystemWeb extends WebPlugin implements FileSystemPlugin {
|
|
|
77
77
|
async remove(options: { path: string }): Promise<void> {
|
|
78
78
|
const ok = await this._fs.deleteByPrefix(options.path);
|
|
79
79
|
if (!ok) {
|
|
80
|
-
throw new Error("
|
|
80
|
+
throw new Error("삭제에 실패했습니다");
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -25,12 +25,12 @@ export class VirtualFileSystem {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @param dirPath
|
|
30
|
-
* @returns
|
|
31
|
-
* @note
|
|
32
|
-
*
|
|
33
|
-
*
|
|
28
|
+
* 디렉토리의 직접 하위 항목을 반환합니다.
|
|
29
|
+
* @param dirPath 조회할 디렉토리 경로
|
|
30
|
+
* @returns 하위 파일/디렉토리 목록
|
|
31
|
+
* @note 암시적 디렉토리 처리: 디렉토리 항목 없이 파일 경로만 존재하더라도
|
|
32
|
+
* 중간 경로를 디렉토리로 취급합니다. 예: "/a/b/c.txt"만 저장된 경우,
|
|
33
|
+
* listChildren("/a") 호출 시 "b"를 isDirectory: true로 반환합니다.
|
|
34
34
|
*/
|
|
35
35
|
async listChildren(dirPath: string): Promise<FileInfo[]> {
|
|
36
36
|
const prefix = dirPath === "/" ? "/" : dirPath + "/";
|
package/README.md
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# @simplysm/capacitor-plugin-file-system
|
|
2
|
-
|
|
3
|
-
Simplysm Package - Capacitor File System Plugin. Provides file system access for Android (MANAGE_EXTERNAL_STORAGE on Android 11+) with IndexedDB-based browser emulation.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @simplysm/capacitor-plugin-file-system
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## API Overview
|
|
12
|
-
|
|
13
|
-
### File System
|
|
14
|
-
|
|
15
|
-
| API | Type | Description |
|
|
16
|
-
|-----|------|-------------|
|
|
17
|
-
| `FileSystem` | class | File system access plugin (static methods) |
|
|
18
|
-
| `FileSystemPlugin` | interface | Low-level Capacitor plugin interface for file system |
|
|
19
|
-
| `StorageType` | type | Storage location type |
|
|
20
|
-
| `FileInfo` | interface | File/directory entry information |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
### `StorageType`
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
type StorageType =
|
|
28
|
-
| "external" // External storage root (Environment.getExternalStorageDirectory)
|
|
29
|
-
| "externalFiles" // App-specific external files directory
|
|
30
|
-
| "externalCache" // App-specific external cache directory
|
|
31
|
-
| "externalMedia" // App-specific external media directory
|
|
32
|
-
| "appData" // App data directory
|
|
33
|
-
| "appFiles" // App files directory
|
|
34
|
-
| "appCache"; // App cache directory
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### `FileInfo`
|
|
38
|
-
|
|
39
|
-
| Field | Type | Description |
|
|
40
|
-
|-------|------|-------------|
|
|
41
|
-
| `name` | `string` | File or directory name |
|
|
42
|
-
| `isDirectory` | `boolean` | Whether the entry is a directory |
|
|
43
|
-
|
|
44
|
-
### `FileSystemPlugin`
|
|
45
|
-
|
|
46
|
-
| Method | Signature | Description |
|
|
47
|
-
|--------|-----------|-------------|
|
|
48
|
-
| `checkPermissions` | `() => Promise<{ granted: boolean }>` | Check file system permission |
|
|
49
|
-
| `requestPermissions` | `() => Promise<void>` | Request file system permission |
|
|
50
|
-
| `readdir` | `(options: { path: string }) => Promise<{ files: FileInfo[] }>` | Read directory contents |
|
|
51
|
-
| `getStoragePath` | `(options: { type: StorageType }) => Promise<{ path: string }>` | Get storage path by type |
|
|
52
|
-
| `getUri` | `(options: { path: string }) => Promise<{ uri: string }>` | Get FileProvider URI |
|
|
53
|
-
| `writeFile` | `(options: { path: string; data: string; encoding?: "utf8" \| "base64" }) => Promise<void>` | Write file |
|
|
54
|
-
| `readFile` | `(options: { path: string; encoding?: "utf8" \| "base64" }) => Promise<{ data: string }>` | Read file |
|
|
55
|
-
| `remove` | `(options: { path: string }) => Promise<void>` | Delete file/directory |
|
|
56
|
-
| `mkdir` | `(options: { path: string }) => Promise<void>` | Create directory |
|
|
57
|
-
| `exists` | `(options: { path: string }) => Promise<{ exists: boolean }>` | Check existence |
|
|
58
|
-
|
|
59
|
-
### `FileSystem`
|
|
60
|
-
|
|
61
|
-
Abstract class with static methods for file system access. Android 11+ uses MANAGE_EXTERNAL_STORAGE; Android 10- uses READ/WRITE_EXTERNAL_STORAGE; browser uses IndexedDB emulation.
|
|
62
|
-
|
|
63
|
-
| Method | Signature | Description |
|
|
64
|
-
|--------|-----------|-------------|
|
|
65
|
-
| `checkPermissions` | `() => Promise<boolean>` | Check permission |
|
|
66
|
-
| `requestPermissions` | `() => Promise<void>` | Request permission (Android 11+: settings, Android 10-: dialog) |
|
|
67
|
-
| `readdir` | `(dirPath: string) => Promise<FileInfo[]>` | Read directory |
|
|
68
|
-
| `getStoragePath` | `(type: StorageType) => Promise<string>` | Get storage path |
|
|
69
|
-
| `getUri` | `(filePath: string) => Promise<string>` | Get FileProvider URI |
|
|
70
|
-
| `writeFile` | `(filePath: string, data: string \| Bytes) => Promise<void>` | Write file (string or Uint8Array) |
|
|
71
|
-
| `readFile` | `(filePath: string) => Promise<Bytes>` | Read file as Bytes |
|
|
72
|
-
| `readFile` | `(filePath: string, encoding: "utf8") => Promise<string>` | Read file as UTF-8 string |
|
|
73
|
-
| `remove` | `(targetPath: string) => Promise<void>` | Delete file/directory (recursive) |
|
|
74
|
-
| `mkdir` | `(targetPath: string) => Promise<void>` | Create directory (recursive) |
|
|
75
|
-
| `exists` | `(targetPath: string) => Promise<boolean>` | Check existence |
|
|
76
|
-
|
|
77
|
-
## Usage Examples
|
|
78
|
-
|
|
79
|
-
### Read and write files
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
|
|
83
|
-
|
|
84
|
-
// Check and request permissions
|
|
85
|
-
if (!(await FileSystem.checkPermissions())) {
|
|
86
|
-
await FileSystem.requestPermissions();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Get storage path and write a file
|
|
90
|
-
const storagePath = await FileSystem.getStoragePath("appFiles");
|
|
91
|
-
await FileSystem.writeFile(`${storagePath}/data.txt`, "Hello, world!");
|
|
92
|
-
|
|
93
|
-
// Read it back
|
|
94
|
-
const content = await FileSystem.readFile(`${storagePath}/data.txt`, "utf8");
|
|
95
|
-
|
|
96
|
-
// List directory contents
|
|
97
|
-
const files = await FileSystem.readdir(storagePath);
|
|
98
|
-
```
|