@puredesktop/puredesktop-ui-bridge 2.1.0 → 2.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puredesktop/puredesktop-ui-bridge",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "PureScience plugin SDK — bridge client, theme, and shared UI",
5
5
  "type": "module",
6
6
  "repository": {
@@ -20,6 +20,8 @@
20
20
  "./bridge/client": "./src/bridge/client.mjs",
21
21
  "./bridge/events": "./src/bridge/events.mjs",
22
22
  "./bridge/methods": "./src/bridge/methods.mjs",
23
+ "./bridge/network": "./src/bridge/network.mjs",
24
+ "./bridge/storage": "./src/bridge/storage.mjs",
23
25
  "./bridge/vision": "./src/bridge/vision.mjs",
24
26
  "./bridge/react/usePlatformBridge": "./src/bridge/react/usePlatformBridge.tsx",
25
27
  "./bridge/react/useIpc": "./src/bridge/react/useIpc.tsx",
@@ -1,5 +1,8 @@
1
- export interface PlatformDialogPathResult {
2
- path: string | null
3
- }
4
-
5
- export declare function openPlatformImageDialog(): Promise<string | null>
1
+ export interface PlatformDialogPathResult {
2
+ path: string | null
3
+ }
4
+
5
+ export declare function openPlatformFolderDialog(): Promise<string | null>
6
+ export declare function savePlatformFolderDialog(): Promise<string | null>
7
+ export declare function openPlatformImageDialog(): Promise<string | null>
8
+ export declare function openPlatformFileDialog(): Promise<string | null>
@@ -1,13 +1,43 @@
1
- import { bridge } from './client.mjs'
2
- import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
-
4
- /**
5
- * @returns {Promise<string | null>} Absolute path to the picked image, or null if cancelled.
6
- */
7
- export async function openPlatformImageDialog() {
1
+ import { bridge } from './client.mjs'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ /**
5
+ * @returns {Promise<string | null>} Absolute path to the picked folder, or null if cancelled.
6
+ */
7
+ export async function openPlatformFolderDialog() {
8
+ const result = await bridge.call(
9
+ PLATFORM_BRIDGE_METHODS.DIALOG_OPEN_FOLDER,
10
+ [],
11
+ )
12
+ return result?.path ?? null
13
+ }
14
+
15
+ /**
16
+ * @returns {Promise<string | null>} Absolute path to the picked parent folder, or null if cancelled.
17
+ */
18
+ export async function savePlatformFolderDialog() {
19
+ const result = await bridge.call(
20
+ PLATFORM_BRIDGE_METHODS.DIALOG_SAVE_FOLDER,
21
+ [],
22
+ )
23
+ return result?.path ?? null
24
+ }
25
+
26
+ /**
27
+ * @returns {Promise<string | null>} Absolute path to the picked image, or null if cancelled.
28
+ */
29
+ export async function openPlatformImageDialog() {
8
30
  const result = await bridge.call(
9
31
  PLATFORM_BRIDGE_METHODS.DIALOG_OPEN_IMAGE,
10
32
  [],
11
- )
12
- return result?.path ?? null
13
- }
33
+ )
34
+ return result?.path ?? null
35
+ }
36
+
37
+ /**
38
+ * @returns {Promise<string | null>} Absolute path to the picked file, or null if cancelled.
39
+ */
40
+ export async function openPlatformFileDialog() {
41
+ const result = await bridge.call(PLATFORM_BRIDGE_METHODS.DIALOG_OPEN_FILE, [])
42
+ return result?.path ?? null
43
+ }
@@ -0,0 +1,73 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ const bridgeCall = vi.hoisted(() => vi.fn())
5
+
6
+ vi.mock('./client.mjs', () => ({
7
+ bridge: {
8
+ call: bridgeCall,
9
+ },
10
+ }))
11
+
12
+ import {
13
+ openPlatformFileDialog,
14
+ openPlatformFolderDialog,
15
+ openPlatformImageDialog,
16
+ savePlatformFolderDialog,
17
+ } from './dialog.mjs'
18
+
19
+ beforeEach(() => {
20
+ bridgeCall.mockReset()
21
+ })
22
+
23
+ describe('dialog bridge helpers', () => {
24
+ it('opens a folder dialog using the shell method with no arguments', async () => {
25
+ bridgeCall.mockResolvedValue({ path: '/tmp' })
26
+
27
+ await expect(openPlatformFolderDialog()).resolves.toBe('/tmp')
28
+
29
+ expect(bridgeCall).toHaveBeenCalledWith(
30
+ PLATFORM_BRIDGE_METHODS.DIALOG_OPEN_FOLDER,
31
+ [],
32
+ )
33
+ })
34
+
35
+ it('opens a save folder dialog using the shell method with no arguments', async () => {
36
+ bridgeCall.mockResolvedValue({ path: '/tmp/project' })
37
+
38
+ await expect(savePlatformFolderDialog()).resolves.toBe('/tmp/project')
39
+
40
+ expect(bridgeCall).toHaveBeenCalledWith(
41
+ PLATFORM_BRIDGE_METHODS.DIALOG_SAVE_FOLDER,
42
+ [],
43
+ )
44
+ })
45
+
46
+ it('opens an image dialog using the shell method with no arguments', async () => {
47
+ bridgeCall.mockResolvedValue({ path: '/tmp/image.png' })
48
+
49
+ await expect(openPlatformImageDialog()).resolves.toBe('/tmp/image.png')
50
+
51
+ expect(bridgeCall).toHaveBeenCalledWith(
52
+ PLATFORM_BRIDGE_METHODS.DIALOG_OPEN_IMAGE,
53
+ [],
54
+ )
55
+ })
56
+
57
+ it('opens a file dialog using the shell method with no arguments', async () => {
58
+ bridgeCall.mockResolvedValue({ path: '/tmp/file.md' })
59
+
60
+ await expect(openPlatformFileDialog()).resolves.toBe('/tmp/file.md')
61
+
62
+ expect(bridgeCall).toHaveBeenCalledWith(
63
+ PLATFORM_BRIDGE_METHODS.DIALOG_OPEN_FILE,
64
+ [],
65
+ )
66
+ })
67
+
68
+ it('returns null when the shell dialog is cancelled', async () => {
69
+ bridgeCall.mockResolvedValue({ path: null })
70
+
71
+ await expect(openPlatformFolderDialog()).resolves.toBeNull()
72
+ })
73
+ })
@@ -1,15 +1,31 @@
1
- import type {
2
- PlatformFilePreviewUrlResult,
3
- PlatformFileReadBinaryResult,
4
- PlatformFileReadPreviewResult,
5
- } from './types.js'
1
+ import type {
2
+ PlatformFileCreateFolderResult,
3
+ PlatformFileDeleteResult,
4
+ PlatformFileListResult,
5
+ PlatformFilePreviewUrlResult,
6
+ PlatformFileReadBinaryResult,
7
+ PlatformFileReadPreviewResult,
8
+ PlatformFileRenameResult,
9
+ PlatformFileWriteResult,
10
+ } from './types.js'
6
11
 
7
- export declare const PLATFORM_FILE_TEXT_PREVIEW_MAX_BYTES: number
8
- export declare const PLATFORM_FILE_BINARY_PREVIEW_MAX_BYTES: number
9
-
10
- export declare function readPlatformFilePreview(
11
- path: string,
12
- maxBytes?: number,
12
+ export declare const PLATFORM_FILE_TEXT_PREVIEW_MAX_BYTES: number
13
+ export declare const PLATFORM_FILE_BINARY_PREVIEW_MAX_BYTES: number
14
+
15
+ export declare function listPlatformFiles(
16
+ rootPath: string,
17
+ ): Promise<PlatformFileListResult>
18
+
19
+ export declare function readPlatformTextFile(path: string): Promise<string>
20
+
21
+ export declare function writePlatformTextFile(
22
+ path: string,
23
+ content: string,
24
+ ): Promise<PlatformFileWriteResult>
25
+
26
+ export declare function readPlatformFilePreview(
27
+ path: string,
28
+ maxBytes?: number,
13
29
  ): Promise<PlatformFileReadPreviewResult>
14
30
 
15
31
  export declare function readPlatformFileBinary(
@@ -35,7 +51,17 @@ export declare function writePlatformFileBinary(
35
51
  base64: string,
36
52
  ): Promise<{ ok: true }>
37
53
 
38
- export declare function createPlatformFolder(
39
- parentPath: string,
40
- name: string,
41
- ): Promise<{ path: string }>
54
+ export declare function createPlatformFolder(
55
+ parentPath: string,
56
+ name: string,
57
+ ): Promise<PlatformFileCreateFolderResult>
58
+
59
+ export declare function renamePlatformFile(
60
+ path: string,
61
+ name: string,
62
+ ): Promise<PlatformFileRenameResult>
63
+
64
+ export declare function deletePlatformFile(
65
+ path: string,
66
+ recursive?: boolean,
67
+ ): Promise<PlatformFileDeleteResult>
package/src/bridge/fs.mjs CHANGED
@@ -5,13 +5,38 @@ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
5
5
  export const PLATFORM_FILE_TEXT_PREVIEW_MAX_BYTES = 64 * 1024
6
6
 
7
7
  /** Default binary preview cap for legacy inline image reads. Prefer `fs.previewUrl`. */
8
- export const PLATFORM_FILE_BINARY_PREVIEW_MAX_BYTES = 5 * 1024 * 1024
9
-
10
- /**
11
- * @param {string} path
12
- * @returns {Promise<import('./types.ts').PlatformFilePreviewUrlResult>}
13
- */
14
- export async function readPlatformFilePreviewUrl(path) {
8
+ export const PLATFORM_FILE_BINARY_PREVIEW_MAX_BYTES = 5 * 1024 * 1024
9
+
10
+ /**
11
+ * @param {string} rootPath
12
+ * @returns {Promise<import('./types.ts').PlatformFileListResult>}
13
+ */
14
+ export async function listPlatformFiles(rootPath) {
15
+ return bridge.call(PLATFORM_BRIDGE_METHODS.FS_LIST, [{ rootPath }])
16
+ }
17
+
18
+ /**
19
+ * @param {string} path
20
+ * @returns {Promise<string>}
21
+ */
22
+ export async function readPlatformTextFile(path) {
23
+ return bridge.call(PLATFORM_BRIDGE_METHODS.FS_READ, [path])
24
+ }
25
+
26
+ /**
27
+ * @param {string} path
28
+ * @param {string} content
29
+ * @returns {Promise<import('./types.ts').PlatformFileWriteResult>}
30
+ */
31
+ export async function writePlatformTextFile(path, content) {
32
+ return bridge.call(PLATFORM_BRIDGE_METHODS.FS_WRITE, [path, content])
33
+ }
34
+
35
+ /**
36
+ * @param {string} path
37
+ * @returns {Promise<import('./types.ts').PlatformFilePreviewUrlResult>}
38
+ */
39
+ export async function readPlatformFilePreviewUrl(path) {
15
40
  return bridge.call(PLATFORM_BRIDGE_METHODS.FS_PREVIEW_URL, [{ path }])
16
41
  }
17
42
 
@@ -75,8 +100,27 @@ export async function writePlatformFileBinary(path, base64) {
75
100
  * @param {string} name
76
101
  * @returns {Promise<{ path: string }>}
77
102
  */
78
- export async function createPlatformFolder(parentPath, name) {
79
- return bridge.call(PLATFORM_BRIDGE_METHODS.FS_CREATE_FOLDER, [
80
- { parentPath, name },
81
- ])
82
- }
103
+ export async function createPlatformFolder(parentPath, name) {
104
+ return bridge.call(PLATFORM_BRIDGE_METHODS.FS_CREATE_FOLDER, [
105
+ { parentPath, name },
106
+ ])
107
+ }
108
+
109
+ /**
110
+ * @param {string} path
111
+ * @param {string} name
112
+ * @returns {Promise<import('./types.ts').PlatformFileRenameResult>}
113
+ */
114
+ export async function renamePlatformFile(path, name) {
115
+ return bridge.call(PLATFORM_BRIDGE_METHODS.FS_RENAME, [{ path, name }])
116
+ }
117
+
118
+ /**
119
+ * @param {string} path
120
+ * @param {boolean | undefined} recursive
121
+ * @returns {Promise<import('./types.ts').PlatformFileDeleteResult>}
122
+ */
123
+ export async function deletePlatformFile(path, recursive) {
124
+ const request = recursive === undefined ? { path } : { path, recursive }
125
+ return bridge.call(PLATFORM_BRIDGE_METHODS.FS_DELETE, [request])
126
+ }
@@ -1,9 +1,30 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { dataUrlFromFileBinary } from './fs.mjs'
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ const bridgeCall = vi.hoisted(() => vi.fn())
5
+
6
+ vi.mock('./client.mjs', () => ({
7
+ bridge: {
8
+ call: bridgeCall,
9
+ },
10
+ }))
11
+
12
+ import {
13
+ dataUrlFromFileBinary,
14
+ deletePlatformFile,
15
+ listPlatformFiles,
16
+ readPlatformTextFile,
17
+ renamePlatformFile,
18
+ writePlatformTextFile,
19
+ } from './fs.mjs'
20
+
21
+ beforeEach(() => {
22
+ bridgeCall.mockReset()
23
+ })
3
24
 
4
- describe('dataUrlFromFileBinary', () => {
5
- it('builds a data URL from bridge binary result', () => {
6
- expect(
25
+ describe('dataUrlFromFileBinary', () => {
26
+ it('builds a data URL from bridge binary result', () => {
27
+ expect(
7
28
  dataUrlFromFileBinary({
8
29
  path: '/tmp/image.png',
9
30
  mimeType: 'image/png',
@@ -11,6 +32,59 @@ describe('dataUrlFromFileBinary', () => {
11
32
  truncated: false,
12
33
  byteLength: 3,
13
34
  }),
14
- ).toBe('data:image/png;base64,abc123')
15
- })
16
- })
35
+ ).toBe('data:image/png;base64,abc123')
36
+ })
37
+ })
38
+
39
+ describe('filesystem bridge helpers', () => {
40
+ it('lists files using the shell request object shape', async () => {
41
+ bridgeCall.mockResolvedValue({ entries: [] })
42
+
43
+ await listPlatformFiles('/tmp')
44
+
45
+ expect(bridgeCall).toHaveBeenCalledWith(PLATFORM_BRIDGE_METHODS.FS_LIST, [
46
+ { rootPath: '/tmp' },
47
+ ])
48
+ })
49
+
50
+ it('reads text files using the shell path argument shape', async () => {
51
+ bridgeCall.mockResolvedValue('hello')
52
+
53
+ await readPlatformTextFile('/tmp/a.md')
54
+
55
+ expect(bridgeCall).toHaveBeenCalledWith(PLATFORM_BRIDGE_METHODS.FS_READ, [
56
+ '/tmp/a.md',
57
+ ])
58
+ })
59
+
60
+ it('writes text files using the shell path and content argument shape', async () => {
61
+ bridgeCall.mockResolvedValue({ ok: true })
62
+
63
+ await writePlatformTextFile('/tmp/a.md', 'hello')
64
+
65
+ expect(bridgeCall).toHaveBeenCalledWith(PLATFORM_BRIDGE_METHODS.FS_WRITE, [
66
+ '/tmp/a.md',
67
+ 'hello',
68
+ ])
69
+ })
70
+
71
+ it('renames files using the shell request object shape', async () => {
72
+ bridgeCall.mockResolvedValue({ path: '/tmp/b.md' })
73
+
74
+ await renamePlatformFile('/tmp/a.md', 'b.md')
75
+
76
+ expect(bridgeCall).toHaveBeenCalledWith(PLATFORM_BRIDGE_METHODS.FS_RENAME, [
77
+ { path: '/tmp/a.md', name: 'b.md' },
78
+ ])
79
+ })
80
+
81
+ it('deletes files using the shell request object shape', async () => {
82
+ bridgeCall.mockResolvedValue({ ok: true })
83
+
84
+ await deletePlatformFile('/tmp/a.md', true)
85
+
86
+ expect(bridgeCall).toHaveBeenCalledWith(PLATFORM_BRIDGE_METHODS.FS_DELETE, [
87
+ { path: '/tmp/a.md', recursive: true },
88
+ ])
89
+ })
90
+ })
package/src/bridge/fs.ts CHANGED
@@ -1,10 +1,28 @@
1
- export {
2
- dataUrlFromFileBinary,
3
- readPlatformFileBinary,
4
- readPlatformFileBinaryDataUrl,
5
- readPlatformFilePreview,
6
- readPlatformFilePreviewUrl,
7
- writePlatformFileBinary,
8
- PLATFORM_FILE_BINARY_PREVIEW_MAX_BYTES,
9
- PLATFORM_FILE_TEXT_PREVIEW_MAX_BYTES,
10
- } from './fs.mjs'
1
+ export {
2
+ createPlatformFolder,
3
+ dataUrlFromFileBinary,
4
+ deletePlatformFile,
5
+ listPlatformFiles,
6
+ readPlatformFileBinary,
7
+ readPlatformFileBinaryDataUrl,
8
+ readPlatformFilePreview,
9
+ readPlatformFilePreviewUrl,
10
+ readPlatformTextFile,
11
+ renamePlatformFile,
12
+ writePlatformFileBinary,
13
+ writePlatformTextFile,
14
+ PLATFORM_FILE_BINARY_PREVIEW_MAX_BYTES,
15
+ PLATFORM_FILE_TEXT_PREVIEW_MAX_BYTES,
16
+ } from './fs.mjs'
17
+
18
+ export type {
19
+ PlatformFileCreateFolderResult,
20
+ PlatformFileDeleteResult,
21
+ PlatformFileEntry,
22
+ PlatformFileListResult,
23
+ PlatformFilePreviewUrlResult,
24
+ PlatformFileReadBinaryResult,
25
+ PlatformFileReadPreviewResult,
26
+ PlatformFileRenameResult,
27
+ PlatformFileWriteResult,
28
+ } from './types.js'
@@ -0,0 +1,17 @@
1
+ export interface PlatformNetworkFetchRequest {
2
+ url: string
3
+ method?: string
4
+ headers?: Record<string, string>
5
+ body?: string
6
+ }
7
+
8
+ export interface PlatformNetworkFetchResponse {
9
+ status: number
10
+ ok: boolean
11
+ headers: Record<string, string>
12
+ body: string
13
+ }
14
+
15
+ export declare function networkFetch(
16
+ request: PlatformNetworkFetchRequest,
17
+ ): Promise<PlatformNetworkFetchResponse>
@@ -0,0 +1,22 @@
1
+ import { bridge } from './client.mjs'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ /**
5
+ * Fetch an HTTP(S) resource through the shell network bridge.
6
+ *
7
+ * @param {{
8
+ * url: string,
9
+ * method?: string,
10
+ * headers?: Record<string, string>,
11
+ * body?: string,
12
+ * }} request
13
+ * @returns {Promise<{
14
+ * status: number,
15
+ * ok: boolean,
16
+ * headers: Record<string, string>,
17
+ * body: string,
18
+ * }>}
19
+ */
20
+ export async function networkFetch(request) {
21
+ return bridge.call(PLATFORM_BRIDGE_METHODS.NETWORK_FETCH, [request])
22
+ }
@@ -0,0 +1,27 @@
1
+ export interface PlatformStorageJsonRequest {
2
+ appSlug: string
3
+ fileName: string
4
+ }
5
+
6
+ export interface PlatformStorageJsonReadResult {
7
+ path: string
8
+ value: unknown | null
9
+ }
10
+
11
+ export interface PlatformStorageJsonWriteRequest
12
+ extends PlatformStorageJsonRequest {
13
+ value: unknown
14
+ }
15
+
16
+ export interface PlatformStorageJsonWriteResult {
17
+ path: string
18
+ ok: true
19
+ }
20
+
21
+ export declare function readPlatformStorageJson(
22
+ request: PlatformStorageJsonRequest,
23
+ ): Promise<PlatformStorageJsonReadResult>
24
+
25
+ export declare function writePlatformStorageJson(
26
+ request: PlatformStorageJsonWriteRequest,
27
+ ): Promise<PlatformStorageJsonWriteResult>
@@ -0,0 +1,18 @@
1
+ import { bridge } from './client.mjs'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ /**
5
+ * @param {{ appSlug: string, fileName: string }} request
6
+ * @returns {Promise<{ path: string, value: unknown | null }>}
7
+ */
8
+ export async function readPlatformStorageJson(request) {
9
+ return bridge.call(PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON, [request])
10
+ }
11
+
12
+ /**
13
+ * @param {{ appSlug: string, fileName: string, value: unknown }} request
14
+ * @returns {Promise<{ path: string, ok: true }>}
15
+ */
16
+ export async function writePlatformStorageJson(request) {
17
+ return bridge.call(PLATFORM_BRIDGE_METHODS.STORAGE_WRITE_JSON, [request])
18
+ }
@@ -0,0 +1,49 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { PLATFORM_BRIDGE_METHODS } from './methods.mjs'
3
+
4
+ const bridgeCall = vi.hoisted(() => vi.fn())
5
+
6
+ vi.mock('./client.mjs', () => ({
7
+ bridge: {
8
+ call: bridgeCall,
9
+ },
10
+ }))
11
+
12
+ import {
13
+ readPlatformStorageJson,
14
+ writePlatformStorageJson,
15
+ } from './storage.mjs'
16
+
17
+ beforeEach(() => {
18
+ bridgeCall.mockReset()
19
+ })
20
+
21
+ describe('storage bridge helpers', () => {
22
+ it('reads JSON storage using the shell request object shape', async () => {
23
+ const request = { appSlug: 'puretasks', fileName: 'tasks.json' }
24
+ bridgeCall.mockResolvedValue({ path: '/tmp/tasks.json', value: null })
25
+
26
+ await readPlatformStorageJson(request)
27
+
28
+ expect(bridgeCall).toHaveBeenCalledWith(
29
+ PLATFORM_BRIDGE_METHODS.STORAGE_READ_JSON,
30
+ [request],
31
+ )
32
+ })
33
+
34
+ it('writes JSON storage using the shell request object shape', async () => {
35
+ const request = {
36
+ appSlug: 'puretasks',
37
+ fileName: 'tasks.json',
38
+ value: { tasks: [] },
39
+ }
40
+ bridgeCall.mockResolvedValue({ path: '/tmp/tasks.json', ok: true })
41
+
42
+ await writePlatformStorageJson(request)
43
+
44
+ expect(bridgeCall).toHaveBeenCalledWith(
45
+ PLATFORM_BRIDGE_METHODS.STORAGE_WRITE_JSON,
46
+ [request],
47
+ )
48
+ })
49
+ })
@@ -255,31 +255,64 @@ export interface PlatformAppInstallState {
255
255
  pluginRoot?: string
256
256
  }
257
257
 
258
- export interface PlatformFileReadPreviewResult {
259
- path: string
260
- content: string | null
261
- truncated: boolean
262
- encoding: 'utf-8'
263
- }
264
-
265
- export interface PlatformFileReadBinaryResult {
266
- path: string
267
- mimeType: string
268
- base64: string
269
- truncated: boolean
270
- byteLength: number
271
- }
272
-
273
- export interface PlatformFilePreviewUrlResult {
274
- path: string
275
- url: string
276
- mimeType: string
277
- byteLength: number
278
- }
279
-
280
- /** Minimal file entry fields required for inline preview in plugin iframes. */
281
- export interface PlatformFilePreviewEntry {
282
- path: string
258
+ export interface PlatformFileReadPreviewResult {
259
+ path: string
260
+ content: string | null
261
+ truncated: boolean
262
+ encoding: 'utf-8'
263
+ }
264
+
265
+ export interface PlatformFileEntry {
266
+ path: string
267
+ name: string
268
+ extension: string
269
+ kind: PlatformFileKind
270
+ mimeType: string
271
+ byteLength: number
272
+ modifiedAt: string
273
+ isDirectory: boolean
274
+ }
275
+
276
+ export interface PlatformFileListResult {
277
+ rootPath: string
278
+ parentPath: string | null
279
+ entries: PlatformFileEntry[]
280
+ }
281
+
282
+ export interface PlatformFileReadBinaryResult {
283
+ path: string
284
+ mimeType: string
285
+ base64: string
286
+ truncated: boolean
287
+ byteLength: number
288
+ }
289
+
290
+ export interface PlatformFilePreviewUrlResult {
291
+ path: string
292
+ url: string
293
+ mimeType: string
294
+ byteLength: number
295
+ }
296
+
297
+ export interface PlatformFileCreateFolderResult {
298
+ path: string
299
+ }
300
+
301
+ export interface PlatformFileRenameResult {
302
+ path: string
303
+ }
304
+
305
+ export interface PlatformFileWriteResult {
306
+ ok: true
307
+ }
308
+
309
+ export interface PlatformFileDeleteResult {
310
+ ok: true
311
+ }
312
+
313
+ /** Minimal file entry fields required for inline preview in plugin iframes. */
314
+ export interface PlatformFilePreviewEntry {
315
+ path: string
283
316
  name: string
284
317
  extension: string
285
318
  kind: PlatformFileKind