@palettelab/sdk 0.1.9 → 0.1.10
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 +36 -1
- package/dist/index.d.mts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +48 -0
- package/dist/index.mjs +48 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -195,7 +195,7 @@ Included clients:
|
|
|
195
195
|
|
|
196
196
|
- `palette.user.current()` and `palette.user.updateProfile()`
|
|
197
197
|
- `palette.organization.currentId()`, `currentRole()`, and `listMine()`
|
|
198
|
-
- `palette.dataRooms.list()`, `create()`, `get()`, `folder()`, and `uploadFile()`
|
|
198
|
+
- `palette.dataRooms.list()`, `create()`, `get()`, `folder()`, `createFolder()`, `ensureFolder()`, `findRoomByName()`, `findFolderByName()`, `resolveFolderPath()`, `findFileByName()`, and `uploadFile()`
|
|
199
199
|
- `palette.config.get()` and `palette.config.update(values)`, with optional plugin ID override
|
|
200
200
|
- `palette.permissions.has()`, `hasAny()`, and `hasAll()`
|
|
201
201
|
- `palette.storage.uploadToSignedUrl()`
|
|
@@ -204,6 +204,41 @@ Included clients:
|
|
|
204
204
|
These helpers are intentionally thin wrappers over platform APIs. Apps can still
|
|
205
205
|
use `apiFetch()` directly for custom backend routes.
|
|
206
206
|
|
|
207
|
+
### Data Room Folders By Name
|
|
208
|
+
|
|
209
|
+
Apps can create or reuse custom Data Room folders by name:
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
const palette = createPaletteClient(usePlatform())
|
|
213
|
+
|
|
214
|
+
const room = await palette.dataRooms.ensureRoom("Finance")
|
|
215
|
+
const invoices = await palette.dataRooms.ensureFolder(room.id, "Invoices")
|
|
216
|
+
|
|
217
|
+
await palette.dataRooms.uploadFile(room.id, file, {
|
|
218
|
+
folderId: invoices.id,
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Apps can also resolve nested folders:
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
const folder = await palette.dataRooms.resolveFolderPath(
|
|
226
|
+
room.id,
|
|
227
|
+
"Clients/Acme/Invoices",
|
|
228
|
+
{ create: true },
|
|
229
|
+
)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
To read existing files by name:
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
const room = await palette.dataRooms.requireRoomByName("Finance")
|
|
236
|
+
const folder = await palette.dataRooms.resolveFolderPath(room.id, "Clients/Acme/Invoices")
|
|
237
|
+
const file = folder
|
|
238
|
+
? await palette.dataRooms.findFileByName(room.id, "jan.pdf", { folderId: folder.id })
|
|
239
|
+
: null
|
|
240
|
+
```
|
|
241
|
+
|
|
207
242
|
## Permissions
|
|
208
243
|
|
|
209
244
|
Use permission helpers to keep UI actions aligned with backend permission gates.
|
package/dist/index.d.mts
CHANGED
|
@@ -63,7 +63,14 @@ interface DataRoomUploadOptions {
|
|
|
63
63
|
folderId?: number | null;
|
|
64
64
|
contentType?: string;
|
|
65
65
|
}
|
|
66
|
+
interface FindByNameOptions {
|
|
67
|
+
caseSensitive?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface EnsureFolderOptions extends FindByNameOptions {
|
|
70
|
+
parentFolderId?: number | null;
|
|
71
|
+
}
|
|
66
72
|
declare class DataRoomClient {
|
|
73
|
+
private matchesName;
|
|
67
74
|
list(): Promise<DataRoom[]>;
|
|
68
75
|
create(input: {
|
|
69
76
|
name: string;
|
|
@@ -71,6 +78,21 @@ declare class DataRoomClient {
|
|
|
71
78
|
}): Promise<DataRoom>;
|
|
72
79
|
get(roomId: number): Promise<DataRoomContents>;
|
|
73
80
|
folder(roomId: number, folderId: number): Promise<DataRoomContents>;
|
|
81
|
+
findRoomByName(name: string, options?: FindByNameOptions): Promise<DataRoom | null>;
|
|
82
|
+
requireRoomByName(name: string, options?: FindByNameOptions): Promise<DataRoom>;
|
|
83
|
+
ensureRoom(name: string, description?: string | null): Promise<DataRoom>;
|
|
84
|
+
createFolder(roomId: number, input: {
|
|
85
|
+
name: string;
|
|
86
|
+
parentFolderId?: number | null;
|
|
87
|
+
}): Promise<DataRoomFolder>;
|
|
88
|
+
findFolderByName(roomId: number, name: string, options?: EnsureFolderOptions): Promise<DataRoomFolder | null>;
|
|
89
|
+
ensureFolder(roomId: number, name: string, options?: EnsureFolderOptions): Promise<DataRoomFolder>;
|
|
90
|
+
resolveFolderPath(roomId: number, path: string | string[], options?: FindByNameOptions & {
|
|
91
|
+
create?: boolean;
|
|
92
|
+
}): Promise<DataRoomFolder | null>;
|
|
93
|
+
findFileByName(roomId: number, name: string, options?: FindByNameOptions & {
|
|
94
|
+
folderId?: number | null;
|
|
95
|
+
}): Promise<DataRoomFile | null>;
|
|
74
96
|
requestUpload(roomId: number, file: File, options?: DataRoomUploadOptions): Promise<{
|
|
75
97
|
upload_url: string;
|
|
76
98
|
blob_path: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -63,7 +63,14 @@ interface DataRoomUploadOptions {
|
|
|
63
63
|
folderId?: number | null;
|
|
64
64
|
contentType?: string;
|
|
65
65
|
}
|
|
66
|
+
interface FindByNameOptions {
|
|
67
|
+
caseSensitive?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface EnsureFolderOptions extends FindByNameOptions {
|
|
70
|
+
parentFolderId?: number | null;
|
|
71
|
+
}
|
|
66
72
|
declare class DataRoomClient {
|
|
73
|
+
private matchesName;
|
|
67
74
|
list(): Promise<DataRoom[]>;
|
|
68
75
|
create(input: {
|
|
69
76
|
name: string;
|
|
@@ -71,6 +78,21 @@ declare class DataRoomClient {
|
|
|
71
78
|
}): Promise<DataRoom>;
|
|
72
79
|
get(roomId: number): Promise<DataRoomContents>;
|
|
73
80
|
folder(roomId: number, folderId: number): Promise<DataRoomContents>;
|
|
81
|
+
findRoomByName(name: string, options?: FindByNameOptions): Promise<DataRoom | null>;
|
|
82
|
+
requireRoomByName(name: string, options?: FindByNameOptions): Promise<DataRoom>;
|
|
83
|
+
ensureRoom(name: string, description?: string | null): Promise<DataRoom>;
|
|
84
|
+
createFolder(roomId: number, input: {
|
|
85
|
+
name: string;
|
|
86
|
+
parentFolderId?: number | null;
|
|
87
|
+
}): Promise<DataRoomFolder>;
|
|
88
|
+
findFolderByName(roomId: number, name: string, options?: EnsureFolderOptions): Promise<DataRoomFolder | null>;
|
|
89
|
+
ensureFolder(roomId: number, name: string, options?: EnsureFolderOptions): Promise<DataRoomFolder>;
|
|
90
|
+
resolveFolderPath(roomId: number, path: string | string[], options?: FindByNameOptions & {
|
|
91
|
+
create?: boolean;
|
|
92
|
+
}): Promise<DataRoomFolder | null>;
|
|
93
|
+
findFileByName(roomId: number, name: string, options?: FindByNameOptions & {
|
|
94
|
+
folderId?: number | null;
|
|
95
|
+
}): Promise<DataRoomFile | null>;
|
|
74
96
|
requestUpload(roomId: number, file: File, options?: DataRoomUploadOptions): Promise<{
|
|
75
97
|
upload_url: string;
|
|
76
98
|
blob_path: string;
|
package/dist/index.js
CHANGED
|
@@ -231,6 +231,10 @@ function withPluginProvider(element, platform = {}) {
|
|
|
231
231
|
|
|
232
232
|
// src/data-rooms.ts
|
|
233
233
|
var DataRoomClient = class {
|
|
234
|
+
matchesName(actual, expected, options = {}) {
|
|
235
|
+
if (options.caseSensitive) return actual === expected;
|
|
236
|
+
return actual.localeCompare(expected, void 0, { sensitivity: "accent" }) === 0;
|
|
237
|
+
}
|
|
234
238
|
async list() {
|
|
235
239
|
const res = await apiFetch("/api/v1/data-rooms");
|
|
236
240
|
return res.json();
|
|
@@ -250,6 +254,50 @@ var DataRoomClient = class {
|
|
|
250
254
|
const res = await apiFetch(`/api/v1/data-rooms/${roomId}/folders/${folderId}`);
|
|
251
255
|
return res.json();
|
|
252
256
|
}
|
|
257
|
+
async findRoomByName(name, options = {}) {
|
|
258
|
+
const rooms = await this.list();
|
|
259
|
+
return rooms.find((room) => this.matchesName(room.name, name, options)) ?? null;
|
|
260
|
+
}
|
|
261
|
+
async requireRoomByName(name, options = {}) {
|
|
262
|
+
const room = await this.findRoomByName(name, options);
|
|
263
|
+
if (!room) throw new Error(`Data Room not found: ${name}`);
|
|
264
|
+
return room;
|
|
265
|
+
}
|
|
266
|
+
async ensureRoom(name, description) {
|
|
267
|
+
return await this.findRoomByName(name) ?? this.create({ name, description });
|
|
268
|
+
}
|
|
269
|
+
async createFolder(roomId, input) {
|
|
270
|
+
const res = await apiFetch(`/api/v1/data-rooms/${roomId}/folders`, {
|
|
271
|
+
method: "POST",
|
|
272
|
+
body: JSON.stringify({
|
|
273
|
+
name: input.name,
|
|
274
|
+
parent_folder_id: input.parentFolderId ?? null
|
|
275
|
+
})
|
|
276
|
+
});
|
|
277
|
+
return res.json();
|
|
278
|
+
}
|
|
279
|
+
async findFolderByName(roomId, name, options = {}) {
|
|
280
|
+
const contents = options.parentFolderId ? await this.folder(roomId, options.parentFolderId) : await this.get(roomId);
|
|
281
|
+
return contents.folders.find((folder) => this.matchesName(folder.name, name, options)) ?? null;
|
|
282
|
+
}
|
|
283
|
+
async ensureFolder(roomId, name, options = {}) {
|
|
284
|
+
return await this.findFolderByName(roomId, name, options) ?? this.createFolder(roomId, { name, parentFolderId: options.parentFolderId ?? null });
|
|
285
|
+
}
|
|
286
|
+
async resolveFolderPath(roomId, path, options = {}) {
|
|
287
|
+
const parts = Array.isArray(path) ? path : path.split("/").map((part) => part.trim()).filter(Boolean);
|
|
288
|
+
let parentFolderId = null;
|
|
289
|
+
let current = null;
|
|
290
|
+
for (const part of parts) {
|
|
291
|
+
current = options.create ? await this.ensureFolder(roomId, part, { ...options, parentFolderId }) : await this.findFolderByName(roomId, part, { ...options, parentFolderId });
|
|
292
|
+
if (!current) return null;
|
|
293
|
+
parentFolderId = current.id;
|
|
294
|
+
}
|
|
295
|
+
return current;
|
|
296
|
+
}
|
|
297
|
+
async findFileByName(roomId, name, options = {}) {
|
|
298
|
+
const contents = options.folderId ? await this.folder(roomId, options.folderId) : await this.get(roomId);
|
|
299
|
+
return contents.files.find((file) => this.matchesName(file.original_filename, name, options)) ?? null;
|
|
300
|
+
}
|
|
253
301
|
async requestUpload(roomId, file, options = {}) {
|
|
254
302
|
const res = await apiFetch(`/api/v1/data-rooms/${roomId}/files/request-upload`, {
|
|
255
303
|
method: "POST",
|
package/dist/index.mjs
CHANGED
|
@@ -177,6 +177,10 @@ function withPluginProvider(element, platform = {}) {
|
|
|
177
177
|
|
|
178
178
|
// src/data-rooms.ts
|
|
179
179
|
var DataRoomClient = class {
|
|
180
|
+
matchesName(actual, expected, options = {}) {
|
|
181
|
+
if (options.caseSensitive) return actual === expected;
|
|
182
|
+
return actual.localeCompare(expected, void 0, { sensitivity: "accent" }) === 0;
|
|
183
|
+
}
|
|
180
184
|
async list() {
|
|
181
185
|
const res = await apiFetch("/api/v1/data-rooms");
|
|
182
186
|
return res.json();
|
|
@@ -196,6 +200,50 @@ var DataRoomClient = class {
|
|
|
196
200
|
const res = await apiFetch(`/api/v1/data-rooms/${roomId}/folders/${folderId}`);
|
|
197
201
|
return res.json();
|
|
198
202
|
}
|
|
203
|
+
async findRoomByName(name, options = {}) {
|
|
204
|
+
const rooms = await this.list();
|
|
205
|
+
return rooms.find((room) => this.matchesName(room.name, name, options)) ?? null;
|
|
206
|
+
}
|
|
207
|
+
async requireRoomByName(name, options = {}) {
|
|
208
|
+
const room = await this.findRoomByName(name, options);
|
|
209
|
+
if (!room) throw new Error(`Data Room not found: ${name}`);
|
|
210
|
+
return room;
|
|
211
|
+
}
|
|
212
|
+
async ensureRoom(name, description) {
|
|
213
|
+
return await this.findRoomByName(name) ?? this.create({ name, description });
|
|
214
|
+
}
|
|
215
|
+
async createFolder(roomId, input) {
|
|
216
|
+
const res = await apiFetch(`/api/v1/data-rooms/${roomId}/folders`, {
|
|
217
|
+
method: "POST",
|
|
218
|
+
body: JSON.stringify({
|
|
219
|
+
name: input.name,
|
|
220
|
+
parent_folder_id: input.parentFolderId ?? null
|
|
221
|
+
})
|
|
222
|
+
});
|
|
223
|
+
return res.json();
|
|
224
|
+
}
|
|
225
|
+
async findFolderByName(roomId, name, options = {}) {
|
|
226
|
+
const contents = options.parentFolderId ? await this.folder(roomId, options.parentFolderId) : await this.get(roomId);
|
|
227
|
+
return contents.folders.find((folder) => this.matchesName(folder.name, name, options)) ?? null;
|
|
228
|
+
}
|
|
229
|
+
async ensureFolder(roomId, name, options = {}) {
|
|
230
|
+
return await this.findFolderByName(roomId, name, options) ?? this.createFolder(roomId, { name, parentFolderId: options.parentFolderId ?? null });
|
|
231
|
+
}
|
|
232
|
+
async resolveFolderPath(roomId, path, options = {}) {
|
|
233
|
+
const parts = Array.isArray(path) ? path : path.split("/").map((part) => part.trim()).filter(Boolean);
|
|
234
|
+
let parentFolderId = null;
|
|
235
|
+
let current = null;
|
|
236
|
+
for (const part of parts) {
|
|
237
|
+
current = options.create ? await this.ensureFolder(roomId, part, { ...options, parentFolderId }) : await this.findFolderByName(roomId, part, { ...options, parentFolderId });
|
|
238
|
+
if (!current) return null;
|
|
239
|
+
parentFolderId = current.id;
|
|
240
|
+
}
|
|
241
|
+
return current;
|
|
242
|
+
}
|
|
243
|
+
async findFileByName(roomId, name, options = {}) {
|
|
244
|
+
const contents = options.folderId ? await this.folder(roomId, options.folderId) : await this.get(roomId);
|
|
245
|
+
return contents.files.find((file) => this.matchesName(file.original_filename, name, options)) ?? null;
|
|
246
|
+
}
|
|
199
247
|
async requestUpload(roomId, file, options = {}) {
|
|
200
248
|
const res = await apiFetch(`/api/v1/data-rooms/${roomId}/files/request-upload`, {
|
|
201
249
|
method: "POST",
|