@peers-app/peers-sdk 0.29.1 → 0.29.2

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.
@@ -211,6 +211,7 @@ async function isSelfTrustedContractCaller(userContext, remoteIdentity) {
211
211
  }
212
212
  const permissionDenied = (call, reason) => new Error(`Permission denied: ${call.member} '${call.name}'.${call.operation} on contract ${call.contractId}${reason ? ` (${reason})` : ""}`);
213
213
  const localOnlyContractIds = new Set([
214
+ system_ids_1.filesContractId,
214
215
  system_ids_1.groupMembersContractId,
215
216
  system_ids_1.hostToolsContractId,
216
217
  system_ids_1.desktopToolsContractId,
@@ -19,6 +19,7 @@ export * from "./system/app-updates-contract";
19
19
  export { CONTRACT_CATALOG_VERSION, contractCatalogProviderPackageId, getContractCatalogDefinition, type IContractCatalogConsumer, type IContractDefinitionWithPolicy, type IContractProviderInfo, type IContractToolPolicy, type IExposedContractInfo, type IExposedToolInfo, type IGetContractDefinitionInput, type IListContractProvidersInput, } from "./system/contract-catalog-contract";
20
20
  export * from "./system/desktop-tools-contract";
21
21
  export { DEVICE_OPERATIONS_CONTRACT_VERSION, DEVICE_OPERATIONS_MAX_QUERY_LENGTH, DEVICE_OPERATIONS_MAX_RESULT_BYTES, DEVICE_OPERATIONS_MAX_ROWS, DEVICE_OPERATIONS_MAX_TOOLS, type DeviceOperationCapability, deviceOperationsProviderPackageId, deviceOperationsToolIds, getDeviceOperationsContractDefinition, type IDeviceDatabaseQueryInput, type IDeviceDatabaseQueryResult, type IDeviceOperationStatus, type IDeviceToolListInput, type IDeviceToolLookupInput, type IDeviceToolLookupResult, type IDeviceToolRunInput, } from "./system/device-operations-contract";
22
+ export * from "./system/files-contract";
22
23
  export * from "./system/group-members-contract";
23
24
  export * from "./system/host-shell-contract";
24
25
  export * from "./system/host-tools-contract";
@@ -105,6 +105,7 @@ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_TOOLS", { enumerable: true
105
105
  Object.defineProperty(exports, "deviceOperationsProviderPackageId", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsProviderPackageId; } });
106
106
  Object.defineProperty(exports, "deviceOperationsToolIds", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsToolIds; } });
107
107
  Object.defineProperty(exports, "getDeviceOperationsContractDefinition", { enumerable: true, get: function () { return device_operations_contract_1.getDeviceOperationsContractDefinition; } });
108
+ __exportStar(require("./system/files-contract"), exports);
108
109
  __exportStar(require("./system/group-members-contract"), exports);
109
110
  __exportStar(require("./system/host-shell-contract"), exports);
110
111
  __exportStar(require("./system/host-tools-contract"), exports);
@@ -0,0 +1,6 @@
1
+ import type { IContractDefinition } from "../types";
2
+ export * from "./files-shared";
3
+ /** Version of the local-only System Files contract. */
4
+ export declare const FILES_CONTRACT_VERSION = 1;
5
+ /** Return the System Files v1 declaration. Tool identities are derived by the catalog. */
6
+ export declare function getFilesContractDefinition(): IContractDefinition;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.FILES_CONTRACT_VERSION = void 0;
18
+ exports.getFilesContractDefinition = getFilesContractDefinition;
19
+ const system_ids_1 = require("../../system-ids");
20
+ const field_type_1 = require("../../types/field-type");
21
+ const system_contracts_1 = require("../system-contracts");
22
+ const files_shared_1 = require("./files-shared");
23
+ __exportStar(require("./files-shared"), exports);
24
+ /** Version of the local-only System Files contract. */
25
+ exports.FILES_CONTRACT_VERSION = 1;
26
+ const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
27
+ /** Return the System Files v1 declaration. Tool identities are derived by the catalog. */
28
+ function getFilesContractDefinition() {
29
+ const size = `${files_shared_1.FILES_MAX_CALL_BYTES / (1024 * 1024)} MiB`;
30
+ return {
31
+ contractId: system_ids_1.filesContractId,
32
+ version: exports.FILES_CONTRACT_VERSION,
33
+ devTag: "dev",
34
+ name: "System Files",
35
+ description: "Save and read files in the caller's own data context.",
36
+ tables: [],
37
+ observables: [],
38
+ events: [],
39
+ tools: [
40
+ {
41
+ name: "save",
42
+ usageDescription: `Save a new file of up to ${size} in this context and return its id.`,
43
+ inputFields: [
44
+ field("name", field_type_1.FieldType.string, "File name, such as avatar.jpg."),
45
+ field("mimeType", field_type_1.FieldType.string, "MIME type, such as image/jpeg.", {
46
+ optional: true,
47
+ }),
48
+ field("bytes", field_type_1.FieldType.blob, `The whole file, at most ${size}.`),
49
+ ],
50
+ outputFields: [
51
+ field("fileId", field_type_1.FieldType.id, "Id to read the file with."),
52
+ field("name", field_type_1.FieldType.string, "File name."),
53
+ field("fileSize", field_type_1.FieldType.number, "Size in bytes."),
54
+ field("fileHash", field_type_1.FieldType.string, "Hash of the file's chunk hashes."),
55
+ field("mimeType", field_type_1.FieldType.string, "MIME type.", { optional: true }),
56
+ ],
57
+ },
58
+ {
59
+ name: "read",
60
+ usageDescription: `Read up to ${size} of a file in this context, from an offset.`,
61
+ inputFields: [
62
+ field("fileId", field_type_1.FieldType.id, "File to read."),
63
+ field("offset", field_type_1.FieldType.number, "First byte to return. Defaults to 0.", {
64
+ optional: true,
65
+ }),
66
+ field("length", field_type_1.FieldType.number, `Most bytes to return. Defaults to the rest, up to ${size}.`, {
67
+ optional: true,
68
+ }),
69
+ ],
70
+ outputFields: [
71
+ field("bytes", field_type_1.FieldType.blob, "The bytes read."),
72
+ field("fileSize", field_type_1.FieldType.number, "Size of the whole file."),
73
+ field("name", field_type_1.FieldType.string, "File name."),
74
+ field("mimeType", field_type_1.FieldType.string, "MIME type.", { optional: true }),
75
+ ],
76
+ },
77
+ ],
78
+ };
79
+ }
80
+ (0, system_contracts_1.registerSystemContract)({
81
+ providerPackageId: system_ids_1.peersSystemPackageId,
82
+ contractId: system_ids_1.filesContractId,
83
+ version: exports.FILES_CONTRACT_VERSION,
84
+ getDefinition: getFilesContractDefinition,
85
+ });
@@ -0,0 +1,59 @@
1
+ import type { IContractConsumerBase } from "../contract-proxy";
2
+ /** Largest file `save` accepts, and the most bytes one `read` returns. */
3
+ export declare const FILES_MAX_CALL_BYTES: number;
4
+ /** Input for {@link IFilesConsumer tools.save}. */
5
+ export interface IFilesSaveInput {
6
+ /** File name, such as `avatar.jpg`. Shown to people; not a path. */
7
+ name: string;
8
+ /** MIME type, such as `image/jpeg`, returned by later reads. */
9
+ mimeType?: string;
10
+ /** The whole file, at most {@link FILES_MAX_CALL_BYTES}. */
11
+ bytes: Uint8Array;
12
+ }
13
+ /** A saved file's description. Keep `fileId` to read it again. */
14
+ export interface IFilesSaveResult {
15
+ fileId: string;
16
+ name: string;
17
+ fileSize: number;
18
+ /** Hash of the file's chunk hashes; equal bytes give an equal hash. */
19
+ fileHash: string;
20
+ mimeType?: string;
21
+ }
22
+ /** Input for {@link IFilesConsumer tools.read}. */
23
+ export interface IFilesReadInput {
24
+ fileId: string;
25
+ /** First byte to return. Defaults to 0. */
26
+ offset?: number;
27
+ /**
28
+ * Most bytes to return: the rest of the file, up to {@link FILES_MAX_CALL_BYTES}, when
29
+ * omitted. A larger `length` is refused; read a larger file in ranges, or with
30
+ * {@link readWholeFile}.
31
+ */
32
+ length?: number;
33
+ }
34
+ /** Bytes read from a file, with its description. */
35
+ export interface IFilesReadResult {
36
+ bytes: Uint8Array;
37
+ /** Size of the whole file, so a caller knows how many ranges to read. */
38
+ fileSize: number;
39
+ name: string;
40
+ mimeType?: string;
41
+ }
42
+ /**
43
+ * Consumer shape for System Files: save and read files in the caller's own data context.
44
+ * Files sync to the context's other devices, as every file does.
45
+ */
46
+ export interface IFilesConsumer extends IContractConsumerBase {
47
+ tools: {
48
+ save(input: IFilesSaveInput): Promise<IFilesSaveResult>;
49
+ read(input: IFilesReadInput): Promise<IFilesReadResult>;
50
+ };
51
+ }
52
+ /**
53
+ * Read a whole file through System Files, in ranges of {@link FILES_MAX_CALL_BYTES}.
54
+ *
55
+ * @param read - The consumer's `read` tool, from a package, a screen or the host.
56
+ * @param fileId - File to read.
57
+ * @returns The file's bytes, name and MIME type.
58
+ */
59
+ export declare function readWholeFile(read: IFilesConsumer["tools"]["read"], fileId: string): Promise<IFilesReadResult>;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FILES_MAX_CALL_BYTES = void 0;
4
+ exports.readWholeFile = readWholeFile;
5
+ // System Files' limits, shapes and read helper, without the contract's registration, so package
6
+ // code can import them from `@peers-app/peers-sdk/define`.
7
+ /** Largest file `save` accepts, and the most bytes one `read` returns. */
8
+ exports.FILES_MAX_CALL_BYTES = 8 * 1024 * 1024;
9
+ /**
10
+ * Read a whole file through System Files, in ranges of {@link FILES_MAX_CALL_BYTES}.
11
+ *
12
+ * @param read - The consumer's `read` tool, from a package, a screen or the host.
13
+ * @param fileId - File to read.
14
+ * @returns The file's bytes, name and MIME type.
15
+ */
16
+ async function readWholeFile(read, fileId) {
17
+ const first = await read({ fileId, length: exports.FILES_MAX_CALL_BYTES });
18
+ if (first.bytes.length >= first.fileSize)
19
+ return first;
20
+ const bytes = new Uint8Array(first.fileSize);
21
+ bytes.set(first.bytes);
22
+ let offset = first.bytes.length;
23
+ while (offset < first.fileSize) {
24
+ const part = await read({ fileId, offset, length: exports.FILES_MAX_CALL_BYTES });
25
+ if (part.bytes.length === 0)
26
+ throw new Error(`File ${fileId} ended early at ${offset} bytes`);
27
+ bytes.set(part.bytes, offset);
28
+ offset += part.bytes.length;
29
+ }
30
+ return { ...first, bytes };
31
+ }
@@ -3,6 +3,11 @@ import { Table } from "../orm";
3
3
  import { type IFile, type IFileInput } from "./file.types";
4
4
  import { FileReadStream } from "./file-read-stream";
5
5
  import { FileWriteStream } from "./file-write-stream";
6
+ /**
7
+ * The chunked, content-hashed file store of one data context. Rows describe files; the bytes
8
+ * live in chunks on disk, shared by hash, and a device fetches a missing chunk from a connected
9
+ * device when it reads. Write through {@link FilesTable.saveFile}, never the table methods.
10
+ */
6
11
  export declare class FilesTable extends Table<IFile> {
7
12
  /** @deprecated Direct inserts forbidden; use saveFile() or saveFileRecord() */
8
13
  insert(..._args: Parameters<Table<any>["insert"]>): never;
@@ -12,6 +17,11 @@ export declare class FilesTable extends Table<IFile> {
12
17
  delete(..._args: Parameters<Table<any>["delete"]>): never;
13
18
  /** @deprecated Direct save forbidden; use saveFile() or saveFileRecord() */
14
19
  save(..._args: Parameters<Table<any>["save"]>): never;
20
+ /**
21
+ * Start writing a file in chunks; `finalize()` saves its row.
22
+ *
23
+ * @param metadata - The new file's id, name, size and MIME type.
24
+ */
15
25
  createWriteStream(metadata: IFileInput): Promise<FileWriteStream>;
16
26
  /**
17
27
  * Note: Use `saveFile` to write a file to disk. This method is for managing
@@ -20,13 +30,58 @@ export declare class FilesTable extends Table<IFile> {
20
30
  * @returns The inserted file record
21
31
  */
22
32
  saveFileRecord(fileRecord: IFile): Promise<IFile>;
33
+ /**
34
+ * Open a file for chunked reads.
35
+ *
36
+ * @param fileId - File to read.
37
+ * @param preloadChunksCount - Chunks to fetch ahead of the reader.
38
+ * @param skipVerification - Skip checking chunk hashes (only for trusted local data).
39
+ * @returns The stream, or null when no such file row exists.
40
+ */
23
41
  openReadStream(fileId: string, preloadChunksCount?: number, skipVerification?: boolean): Promise<FileReadStream | null>;
42
+ /**
43
+ * Save a whole file: chunk it, store the chunks and write its row.
44
+ *
45
+ * @param metaData - The file's id, name and MIME type. `fileSize` is taken from `data`.
46
+ * @param data - The bytes, or a string saved as UTF-8.
47
+ * @returns The saved row.
48
+ */
24
49
  saveFile(metaData: IFileInput, data: Uint8Array | string): Promise<IFile>;
50
+ /**
51
+ * Read a whole file, fetching missing chunks from connected devices.
52
+ *
53
+ * @param fileId - File to read.
54
+ * @param opts.skipVerification - Skip checking chunk hashes (only for trusted local data).
55
+ * @returns The bytes, or null when no such file row exists.
56
+ */
25
57
  getFileContents(fileId: string, opts?: {
26
58
  skipVerification?: boolean;
27
59
  }): Promise<Uint8Array | null>;
60
+ /**
61
+ * Delete a file's row, and its index file's. Chunks stay on disk: other files may share them.
62
+ *
63
+ * @param fileId - File to delete. A missing file is not an error.
64
+ */
28
65
  deleteFile(fileId: string): Promise<void>;
66
+ /**
67
+ * Save a large file's chunk hashes as an index file, itself chunked when large.
68
+ *
69
+ * @param chunkHashes - The large file's chunk hashes, in order.
70
+ * @returns The index file's id.
71
+ */
29
72
  createIndexFileRecursively(chunkHashes: string[]): Promise<string>;
73
+ /**
74
+ * Read a large file's chunk hashes back from its index file.
75
+ *
76
+ * @param indexFileId - The index file's id.
77
+ * @returns The chunk hashes, in order.
78
+ */
30
79
  loadChunkHashesRecursively(indexFileId: string): Promise<string[]>;
31
80
  }
81
+ /**
82
+ * The Files table of a data context.
83
+ *
84
+ * @param dataContext - The context; defaults to the user context's default (the active group,
85
+ * or the personal context). Pass it explicitly in host code.
86
+ */
32
87
  export declare function Files(dataContext?: DataContext): FilesTable;
@@ -10,6 +10,11 @@ const table_definitions_system_1 = require("../orm/table-definitions.system");
10
10
  const file_types_1 = require("./file.types");
11
11
  const file_read_stream_1 = require("./file-read-stream");
12
12
  const file_write_stream_1 = require("./file-write-stream");
13
+ /**
14
+ * The chunked, content-hashed file store of one data context. Rows describe files; the bytes
15
+ * live in chunks on disk, shared by hash, and a device fetches a missing chunk from a connected
16
+ * device when it reads. Write through {@link FilesTable.saveFile}, never the table methods.
17
+ */
13
18
  class FilesTable extends orm_1.Table {
14
19
  /** @deprecated Direct inserts forbidden; use saveFile() or saveFileRecord() */
15
20
  insert(..._args) {
@@ -27,6 +32,11 @@ class FilesTable extends orm_1.Table {
27
32
  save(..._args) {
28
33
  throw new Error("Direct saves forbidden; use saveFile() or saveFileRecord()");
29
34
  }
35
+ /**
36
+ * Start writing a file in chunks; `finalize()` saves its row.
37
+ *
38
+ * @param metadata - The new file's id, name, size and MIME type.
39
+ */
30
40
  async createWriteStream(metadata) {
31
41
  return new file_write_stream_1.FileWriteStream(metadata, this);
32
42
  }
@@ -39,6 +49,14 @@ class FilesTable extends orm_1.Table {
39
49
  async saveFileRecord(fileRecord) {
40
50
  return await super.save(fileRecord);
41
51
  }
52
+ /**
53
+ * Open a file for chunked reads.
54
+ *
55
+ * @param fileId - File to read.
56
+ * @param preloadChunksCount - Chunks to fetch ahead of the reader.
57
+ * @param skipVerification - Skip checking chunk hashes (only for trusted local data).
58
+ * @returns The stream, or null when no such file row exists.
59
+ */
42
60
  async openReadStream(fileId, preloadChunksCount, skipVerification) {
43
61
  const fileRecord = await this.get(fileId);
44
62
  if (!fileRecord) {
@@ -46,6 +64,13 @@ class FilesTable extends orm_1.Table {
46
64
  }
47
65
  return new file_read_stream_1.FileReadStream(fileRecord, this, preloadChunksCount, skipVerification);
48
66
  }
67
+ /**
68
+ * Save a whole file: chunk it, store the chunks and write its row.
69
+ *
70
+ * @param metaData - The file's id, name and MIME type. `fileSize` is taken from `data`.
71
+ * @param data - The bytes, or a string saved as UTF-8.
72
+ * @returns The saved row.
73
+ */
49
74
  async saveFile(metaData, data) {
50
75
  // Use FileWriteStream internally to ensure consistent chunking logic
51
76
  const writeStream = await this.createWriteStream({
@@ -60,6 +85,13 @@ class FilesTable extends orm_1.Table {
60
85
  // Finalize and return the result
61
86
  return await writeStream.finalize();
62
87
  }
88
+ /**
89
+ * Read a whole file, fetching missing chunks from connected devices.
90
+ *
91
+ * @param fileId - File to read.
92
+ * @param opts.skipVerification - Skip checking chunk hashes (only for trusted local data).
93
+ * @returns The bytes, or null when no such file row exists.
94
+ */
63
95
  async getFileContents(fileId, opts) {
64
96
  // Use FileReadStream internally to ensure consistent chunk reading logic
65
97
  const readStream = await this.openReadStream(fileId, undefined, opts?.skipVerification);
@@ -69,6 +101,11 @@ class FilesTable extends orm_1.Table {
69
101
  // Read the entire file using the streaming implementation
70
102
  return await readStream.readAll();
71
103
  }
104
+ /**
105
+ * Delete a file's row, and its index file's. Chunks stay on disk: other files may share them.
106
+ *
107
+ * @param fileId - File to delete. A missing file is not an error.
108
+ */
72
109
  async deleteFile(fileId) {
73
110
  // Get file metadata from database
74
111
  const fileRecord = await super.get(fileId);
@@ -85,7 +122,12 @@ class FilesTable extends orm_1.Table {
85
122
  // Delete file record from database
86
123
  await super.delete(fileId);
87
124
  }
88
- // Create an index file recursively for large files
125
+ /**
126
+ * Save a large file's chunk hashes as an index file, itself chunked when large.
127
+ *
128
+ * @param chunkHashes - The large file's chunk hashes, in order.
129
+ * @returns The index file's id.
130
+ */
89
131
  async createIndexFileRecursively(chunkHashes) {
90
132
  // Create JSON content with chunk hashes
91
133
  const indexContent = JSON.stringify(chunkHashes);
@@ -104,7 +146,12 @@ class FilesTable extends orm_1.Table {
104
146
  await this.saveFile(indexMetadata, indexBuffer);
105
147
  return indexFileId;
106
148
  }
107
- // Load chunk hashes recursively from an index file
149
+ /**
150
+ * Read a large file's chunk hashes back from its index file.
151
+ *
152
+ * @param indexFileId - The index file's id.
153
+ * @returns The chunk hashes, in order.
154
+ */
108
155
  async loadChunkHashesRecursively(indexFileId) {
109
156
  // Recursively load the index file
110
157
  const indexBuffer = await this.getFileContents(indexFileId);
@@ -118,18 +165,17 @@ class FilesTable extends orm_1.Table {
118
165
  }
119
166
  exports.FilesTable = FilesTable;
120
167
  (0, table_definitions_system_1.registerSystemTableDefinition)(file_types_1.filesMetaData, file_types_1.fileSchema, FilesTable);
168
+ /**
169
+ * The Files table of a data context.
170
+ *
171
+ * @param dataContext - The context; defaults to the user context's default (the active group,
172
+ * or the personal context). Pass it explicitly in host code.
173
+ */
121
174
  function Files(dataContext) {
122
175
  return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(file_types_1.filesMetaData, file_types_1.fileSchema);
123
176
  }
124
- // TODO implement permissions check for file access
125
- rpc_types_1.rpcServerCalls.getFileContents = async (fileId, encoding = "utf8") => {
126
- const data = await Files().getFileContents(fileId);
127
- if (data === null) {
128
- throw new Error(`File not found: ${fileId}`);
129
- }
130
- return Buffer.from(data).toString(encoding);
131
- };
132
- // Get file contents as base64 - useful for binary data like images
177
+ // Deprecated RPCs, kept only for Family Hub 0.3.x until its port is Home's version. New code
178
+ // uses System Files, which is bound to the caller's own data context.
133
179
  rpc_types_1.rpcServerCalls.getFileContentsBase64 = async (fileId) => {
134
180
  const data = await Files().getFileContents(fileId);
135
181
  if (data === null) {
@@ -137,7 +183,6 @@ rpc_types_1.rpcServerCalls.getFileContentsBase64 = async (fileId) => {
137
183
  }
138
184
  return Buffer.from(data).toString("base64");
139
185
  };
140
- // Save a file from the UI - data should be base64 encoded for binary files
141
186
  rpc_types_1.rpcServerCalls.saveFile = async (input) => {
142
187
  const fileId = input.fileId || (0, utils_1.newid)();
143
188
  const encoding = input.encoding || "utf8";
@@ -138,3 +138,12 @@ export declare const SystemContractCatalog: import("./contract-ref").IContractRe
138
138
  }>;
139
139
  getContractDefinition(input: import("../contracts/system/contract-catalog-contract").IGetContractDefinitionInput): Promise<import("../contracts/system/contract-catalog-contract").IContractDefinitionWithPolicy>;
140
140
  }>;
141
+ /**
142
+ * System Files v1: save a file and read it back, in the package's own data context. Files sync
143
+ * to the context's other devices. Declare it with `pkg.consumes(SystemFiles)`.
144
+ */
145
+ export declare const SystemFiles: import("./contract-ref").IContractRef<{
146
+ save(input: import("../contracts/system/files-shared").IFilesSaveInput): Promise<import("../contracts/system/files-shared").IFilesSaveResult>;
147
+ read(input: import("../contracts/system/files-shared").IFilesReadInput): Promise<import("../contracts/system/files-shared").IFilesReadResult>;
148
+ }>;
149
+ export { FILES_MAX_CALL_BYTES, type IFilesReadInput, type IFilesReadResult, type IFilesSaveInput, type IFilesSaveResult, readWholeFile, } from "../contracts/system/files-shared";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SystemContractCatalog = exports.SystemScheduler = exports.SystemGroupMembers = exports.SystemIdentity = exports.SystemHttp = void 0;
3
+ exports.readWholeFile = exports.FILES_MAX_CALL_BYTES = exports.SystemFiles = exports.SystemContractCatalog = exports.SystemScheduler = exports.SystemGroupMembers = exports.SystemIdentity = exports.SystemHttp = void 0;
4
4
  const system_ids_1 = require("../system-ids");
5
5
  const contract_ref_1 = require("./contract-ref");
6
6
  /**
@@ -23,3 +23,11 @@ exports.SystemScheduler = (0, contract_ref_1.contractRef)(system_ids_1.scheduler
23
23
  * `pkg.consumes(SystemContractCatalog)`.
24
24
  */
25
25
  exports.SystemContractCatalog = (0, contract_ref_1.contractRef)(system_ids_1.contractCatalogContractId, 1);
26
+ /**
27
+ * System Files v1: save a file and read it back, in the package's own data context. Files sync
28
+ * to the context's other devices. Declare it with `pkg.consumes(SystemFiles)`.
29
+ */
30
+ exports.SystemFiles = (0, contract_ref_1.contractRef)(system_ids_1.filesContractId, 1);
31
+ var files_shared_1 = require("../contracts/system/files-shared");
32
+ Object.defineProperty(exports, "FILES_MAX_CALL_BYTES", { enumerable: true, get: function () { return files_shared_1.FILES_MAX_CALL_BYTES; } });
33
+ Object.defineProperty(exports, "readWholeFile", { enumerable: true, get: function () { return files_shared_1.readWholeFile; } });
package/dist/index.d.ts CHANGED
@@ -8,6 +8,8 @@ export { getLogger, type IWorkflowLog, WorkflowLogs, workflowLogSchema, } from "
8
8
  export { type AnyContractTools, type ContractClientTool, type ContractClientTools, type ContractEventPayloadsOf, type ContractIdOf, type ContractObservableValuesOf, type ContractObservableWritabilityOf, type ContractTableInputsOf, type ContractTableRowsOf, type ContractToolsOf, type ContractVersionOf, contractRef, type IContractClient, type IContractRef, } from "./define/contract-ref";
9
9
  export type { IPackageContract, IPackageDefinition, } from "./define/define-package";
10
10
  export { buildPackageManifest } from "./define/manifest";
11
+ /** System Files, for package screens as well as providers: `hostContract(SystemFiles)`. */
12
+ export { SystemFiles } from "./define/system-contracts";
11
13
  export * from "./device/binary-peer-connection-v2";
12
14
  export * from "./device/connection";
13
15
  export * from "./device/device";
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.buildPackageManifest = exports.contractRef = exports.workflowLogSchema = exports.WorkflowLogs = exports.getLogger = exports.orm = exports.data = void 0;
17
+ exports.SystemFiles = exports.buildPackageManifest = exports.contractRef = exports.workflowLogSchema = exports.WorkflowLogs = exports.getLogger = exports.orm = exports.data = void 0;
18
18
  __exportStar(require("./context"), exports);
19
19
  __exportStar(require("./contracts"), exports);
20
20
  __exportStar(require("./data"), exports);
@@ -30,6 +30,9 @@ var contract_ref_1 = require("./define/contract-ref");
30
30
  Object.defineProperty(exports, "contractRef", { enumerable: true, get: function () { return contract_ref_1.contractRef; } });
31
31
  var manifest_1 = require("./define/manifest");
32
32
  Object.defineProperty(exports, "buildPackageManifest", { enumerable: true, get: function () { return manifest_1.buildPackageManifest; } });
33
+ /** System Files, for package screens as well as providers: `hostContract(SystemFiles)`. */
34
+ var system_contracts_1 = require("./define/system-contracts");
35
+ Object.defineProperty(exports, "SystemFiles", { enumerable: true, get: function () { return system_contracts_1.SystemFiles; } });
33
36
  __exportStar(require("./device/binary-peer-connection-v2"), exports);
34
37
  __exportStar(require("./device/connection"), exports);
35
38
  __exportStar(require("./device/device"), exports);
@@ -29,8 +29,15 @@ export interface IRemoteLogsQueryInput {
29
29
  export declare const rpcServerCalls: {
30
30
  encryptData: (value: string, groupId?: string) => Promise<string>;
31
31
  tableMethodCall: (dataContextId: string, tableName: string, methodName: string, ...args: any[]) => Promise<any>;
32
- getFileContents: (fileId: string, encoding?: BufferEncoding) => Promise<string>;
32
+ /**
33
+ * @deprecated Use System Files (`SystemFiles`, `readWholeFile`). Kept only for Family Hub
34
+ * 0.3.x; deleted once its port is Home's version.
35
+ */
33
36
  getFileContentsBase64: (fileId: string) => Promise<string>;
37
+ /**
38
+ * @deprecated Use System Files (`SystemFiles`). Kept only for Family Hub 0.3.x; deleted once
39
+ * its port is Home's version.
40
+ */
34
41
  saveFile: (input: {
35
42
  name: string;
36
43
  mimeType?: string;
package/dist/rpc-types.js CHANGED
@@ -14,11 +14,15 @@ function rpcStub(rpcName) {
14
14
  exports.rpcServerCalls = {
15
15
  encryptData: rpcStub("encryptData"),
16
16
  tableMethodCall: rpcStub("tableMethodCall"),
17
- // TODO lock this down so not all code can get any file contents
18
- getFileContents: rpcStub("getFileContents"),
19
- // Get file contents as base64 - useful for binary data like images
17
+ /**
18
+ * @deprecated Use System Files (`SystemFiles`, `readWholeFile`). Kept only for Family Hub
19
+ * 0.3.x; deleted once its port is Home's version.
20
+ */
20
21
  getFileContentsBase64: rpcStub("getFileContentsBase64"),
21
- // Save a file from the UI - data should be base64 encoded for binary files
22
+ /**
23
+ * @deprecated Use System Files (`SystemFiles`). Kept only for Family Hub 0.3.x; deleted once
24
+ * its port is Home's version.
25
+ */
22
26
  saveFile: rpcStub("saveFile"),
23
27
  deleteLocalDatabase: rpcStub("deleteLocalDatabase"),
24
28
  /** Returns info about the pre-migration data directory, or `null` if already cleaned up. */
@@ -215,3 +215,5 @@ export declare const packagesContractId = "00mvdhk66tdqrj3hy0bacmj32";
215
215
  export declare const hostShellContractId = "00mveexhw7ezjfghxomlo011g";
216
216
  /** Local-only System Group Members v1; allocated once with newid(). */
217
217
  export declare const groupMembersContractId = "00mvzfzkuf4djwjrsxq9cnaxt";
218
+ /** Local-only System Files v1: save and read files in the caller's own context; allocated once with newid(). */
219
+ export declare const filesContractId = "00mw1pvs1eupopu6sttetmki0";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.groupMembersContractId = exports.hostShellContractId = exports.packagesContractId = exports.desktopToolsContractId = exports.hostToolsContractId = exports.toolCatalogContractId = exports.schedulerToolIds = exports.schedulerContractId = exports.contractCatalogToolIds = exports.contractCatalogContractId = exports.httpToolIds = exports.httpContractId = exports.localFoldersToolIds = exports.localFoldersContractId = exports.identityToolIds = exports.identityContractId = exports.invitesToolIds = exports.invitesContractId = exports.toolAccessControlToolIds = exports.toolAccessControlContractId = exports.syncCheckContractId = exports.appUpdatesContractId = exports.networkControlContractId = exports.networkDiagnosticsContractId = exports.deviceOperationsContractId = exports.logsContractId = exports.peersSystemPackageId = exports.peersCoreRevokedPublishPublicKeys = exports.peersCorePublishPublicKey = exports.peersCorePackageRepoUrl = exports.peersCorePackageId = exports.createGroupToolId = exports.queryDatabaseToolId = exports.runWorkflowToolId = exports.defaultSendMessageToolId = exports.defaultAssistantRunnerToolId = exports.adminAssistantId = exports.openCodeAssistantId = exports.defaultAssistantId = exports.peersRootUserId = void 0;
3
+ exports.filesContractId = exports.groupMembersContractId = exports.hostShellContractId = exports.packagesContractId = exports.desktopToolsContractId = exports.hostToolsContractId = exports.toolCatalogContractId = exports.schedulerToolIds = exports.schedulerContractId = exports.contractCatalogToolIds = exports.contractCatalogContractId = exports.httpToolIds = exports.httpContractId = exports.localFoldersToolIds = exports.localFoldersContractId = exports.identityToolIds = exports.identityContractId = exports.invitesToolIds = exports.invitesContractId = exports.toolAccessControlToolIds = exports.toolAccessControlContractId = exports.syncCheckContractId = exports.appUpdatesContractId = exports.networkControlContractId = exports.networkDiagnosticsContractId = exports.deviceOperationsContractId = exports.logsContractId = exports.peersSystemPackageId = exports.peersCoreRevokedPublishPublicKeys = exports.peersCorePublishPublicKey = exports.peersCorePackageRepoUrl = exports.peersCorePackageId = exports.createGroupToolId = exports.queryDatabaseToolId = exports.runWorkflowToolId = exports.defaultSendMessageToolId = exports.defaultAssistantRunnerToolId = exports.adminAssistantId = exports.openCodeAssistantId = exports.defaultAssistantId = exports.peersRootUserId = void 0;
4
4
  /** Stable user ID that owns built-in Peers system records. */
5
5
  exports.peersRootUserId = "000peers0user000000000001";
6
6
  /** Default assistant used when no user-selected assistant is available. */
@@ -222,3 +222,5 @@ exports.packagesContractId = "00mvdhk66tdqrj3hy0bacmj32";
222
222
  exports.hostShellContractId = "00mveexhw7ezjfghxomlo011g";
223
223
  /** Local-only System Group Members v1; allocated once with newid(). */
224
224
  exports.groupMembersContractId = "00mvzfzkuf4djwjrsxq9cnaxt";
225
+ /** Local-only System Files v1: save and read files in the caller's own context; allocated once with newid(). */
226
+ exports.filesContractId = "00mw1pvs1eupopu6sttetmki0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peers-app/peers-sdk",
3
- "version": "0.29.1",
3
+ "version": "0.29.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/peers-app/peers-sdk.git"