Skip to content

Commit a540cdb

Browse files
committed
add appStorage and workspaceConnectionStorage
1 parent a6164b1 commit a540cdb

3 files changed

Lines changed: 193 additions & 71 deletions

File tree

src/index.ts

Lines changed: 151 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
1-
import type { AppInfo, AppTheme, Column, ConfirmOptions, ConnectionInfo, JsonValue, OpenQueryTabOptions, OpenTableStructureTabOptions, OpenTableTableTabOptions, PluginErrorObject, PluginViewContext, PrimaryKey, QueryResult, RequestFileSaveOptions, RunQueryResult, Table, TableIndex, TableKey, WindowEventObject } from "./types";
1+
import type {
2+
AppInfo,
3+
AppTheme,
4+
Column,
5+
ConfirmOptions,
6+
ConnectionInfo,
7+
JsonValue,
8+
OpenQueryTabOptions,
9+
OpenTableStructureTabOptions,
10+
OpenTableTableTabOptions,
11+
PluginErrorObject,
12+
PluginViewContext,
13+
PrimaryKey,
14+
QueryResult,
15+
RequestFileSaveOptions,
16+
RunQueryResult,
17+
Table,
18+
TableIndex,
19+
TableKey,
20+
WindowEventObject,
21+
} from "./types";
222
import type { RequestMap } from "./internal";
323

424
export * from "./types";
@@ -26,29 +46,47 @@ export async function getTables(schema?: string): Promise<Table[]> {
2646
*
2747
* @since Beekeeper Studio 5.3.0
2848
**/
29-
export async function getColumns(table: string, schema?: string): Promise<Column[]> {
49+
export async function getColumns(
50+
table: string,
51+
schema?: string,
52+
): Promise<Column[]> {
3053
return await request({ name: "getColumns", args: { table, schema } });
3154
}
3255

3356
/** @since Beekeeper Studio 5.4.0 */
34-
export async function getTableKeys(table: string, schema?: string): Promise<TableKey[]> {
57+
export async function getTableKeys(
58+
table: string,
59+
schema?: string,
60+
): Promise<TableKey[]> {
3561
return await request({ name: "getTableKeys", args: { table, schema } });
3662
}
3763

3864
/** @since Beekeeper Studio 5.5.0 */
39-
export async function getTableIndexes(table: string, schema?: string): Promise<TableIndex[]> {
65+
export async function getTableIndexes(
66+
table: string,
67+
schema?: string,
68+
): Promise<TableIndex[]> {
4069
return await request({ name: "getTableIndexes", args: { table, schema } });
4170
}
4271

43-
export async function getPrimaryKeys(table: string, schema?: string): Promise<PrimaryKey[]> {
72+
export async function getPrimaryKeys(
73+
table: string,
74+
schema?: string,
75+
): Promise<PrimaryKey[]> {
4476
return await request({ name: "getPrimaryKeys", args: { table, schema } });
4577
}
4678

47-
export async function getIncomingKeys(table: string, schema?: string): Promise<TableKey[]> {
79+
export async function getIncomingKeys(
80+
table: string,
81+
schema?: string,
82+
): Promise<TableKey[]> {
4883
return await request({ name: "getIncomingKeys", args: { table, schema } });
4984
}
5085

51-
export async function getOutgoingKeys(table: string, schema?: string): Promise<TableKey[]> {
86+
export async function getOutgoingKeys(
87+
table: string,
88+
schema?: string,
89+
): Promise<TableKey[]> {
5290
return await request({ name: "getOutgoingKeys", args: { table, schema } });
5391
}
5492

@@ -70,7 +108,9 @@ export async function getAppInfo(): Promise<AppInfo> {
70108
* Get the version of Beekeeper Studio
71109
* @since Beekeeper Studio 5.3.0
72110
**/
73-
export async function getAppVersion(): Promise<"5.3" | (string & { __brand?: never })> {
111+
export async function getAppVersion(): Promise<
112+
"5.3" | (string & { __brand?: never })
113+
> {
74114
try {
75115
const appInfo = await getAppInfo();
76116
return appInfo.version;
@@ -161,33 +201,6 @@ export async function openExternal(link: string): Promise<void> {
161201
return await request({ name: "openExternal", args: { link } });
162202
}
163203

164-
/** @since Beekeeper Studio 5.3.0 */
165-
export async function getData<T = unknown>(key: string = "default"): Promise<T> {
166-
return await request({ name: "getData", args: { key } });
167-
}
168-
169-
/**
170-
* Store data that can be retrieved later.
171-
*
172-
* @example
173-
* // Store with custom key
174-
* await setData("myKey", { name: "John" });
175-
*
176-
* // Store with default key (equivalent to setData("default", value))
177-
* await setData({ name: "John" });
178-
*
179-
* @since Beekeeper Studio 5.3.0
180-
*/
181-
export async function setData<T = unknown>(key: string, value: T): Promise<void>;
182-
export async function setData<T = unknown>(value: T): Promise<void>;
183-
export async function setData<T = unknown>(keyOrValue: string | T, value?: T): Promise<void> {
184-
if (value !== undefined) {
185-
return await request({ name: "setData", args: { key: keyOrValue as string, value } });
186-
} else {
187-
return await request({ name: "setData", args: { key: "default", value: keyOrValue as T } });
188-
}
189-
}
190-
191204
/** @since Beekeeper Studio 5.3.0 */
192205
export async function getEncryptedData<T>(key: string): Promise<T> {
193206
return await request({ name: "getEncryptedData", args: { key } });
@@ -205,31 +218,54 @@ export async function getEncryptedData<T>(key: string): Promise<T> {
205218
*
206219
* @since Beekeeper Studio 5.3.0
207220
*/
208-
export async function setEncryptedData<T = unknown>(key: string, value: T): Promise<void>;
221+
export async function setEncryptedData<T = unknown>(
222+
key: string,
223+
value: T,
224+
): Promise<void>;
209225
export async function setEncryptedData<T = unknown>(value: T): Promise<void>;
210-
export async function setEncryptedData<T = unknown>(keyOrValue: string | T, value?: T): Promise<void> {
226+
export async function setEncryptedData<T = unknown>(
227+
keyOrValue: string | T,
228+
value?: T,
229+
): Promise<void> {
211230
if (value !== undefined) {
212-
return await request({ name: "setEncryptedData", args: { key: keyOrValue as string, value } });
231+
return await request({
232+
name: "setEncryptedData",
233+
args: { key: keyOrValue as string, value },
234+
});
213235
} else {
214-
return await request({ name: "setEncryptedData", args: { key: "default", value: keyOrValue as T } });
236+
return await request({
237+
name: "setEncryptedData",
238+
args: { key: "default", value: keyOrValue as T },
239+
});
215240
}
216241
}
217242

218243
/** @since Beekeeper Studio 5.4.0 */
219-
export async function openTab(type: "query", options?: OpenQueryTabOptions): Promise<void>;
220-
export async function openTab(type: "tableTable", options: OpenTableTableTabOptions): Promise<void>;
221-
export async function openTab(type: "tableStructure", options: OpenTableStructureTabOptions): Promise<void>;
244+
export async function openTab(
245+
type: "query",
246+
options?: OpenQueryTabOptions,
247+
): Promise<void>;
248+
export async function openTab(
249+
type: "tableTable",
250+
options: OpenTableTableTabOptions,
251+
): Promise<void>;
252+
export async function openTab(
253+
type: "tableStructure",
254+
options: OpenTableStructureTabOptions,
255+
): Promise<void>;
222256
export async function openTab(
223257
type: "query" | "tableTable" | "tableStructure",
224258
options?:
225-
OpenQueryTabOptions
259+
| OpenQueryTabOptions
226260
| OpenTableTableTabOptions
227-
| OpenTableStructureTabOptions
261+
| OpenTableStructureTabOptions,
228262
): Promise<void> {
229263
return await request({ name: "openTab", args: { type, ...options } });
230264
}
231265

232-
export async function requestFileSave(options: RequestFileSaveOptions): Promise<void> {
266+
export async function requestFileSave(
267+
options: RequestFileSaveOptions,
268+
): Promise<void> {
233269
return await request({ name: "requestFileSave", args: options });
234270
}
235271

@@ -247,7 +283,11 @@ export async function toggleStatusBarUI(): Promise<void> {
247283
}
248284

249285
/** @since Beekeeper Studio 5.5.? */
250-
export async function confirm(title?: string, message?: string, options?: ConfirmOptions): Promise<boolean> {
286+
export async function confirm(
287+
title?: string,
288+
message?: string,
289+
options?: ConfirmOptions,
290+
): Promise<boolean> {
251291
return await request({ name: "confirm", args: { title, message, options } });
252292
}
253293

@@ -261,26 +301,32 @@ export const broadcast = {
261301
handler(params.message);
262302
});
263303
},
264-
}
304+
};
265305

266-
/** @since Beekeeper Studio 5.3.0 */
267-
export const log = {
306+
class PluginLog {
268307
error(err: string | Error): void {
308+
const logStack = new Error().stack!;
309+
269310
if (typeof err === "string") {
270311
return notify("pluginError", {
271312
name: "Error",
272313
message: err,
273-
stack: undefined,
314+
stack: logStack,
315+
logStack,
274316
});
275317
}
276318
return notify("pluginError", {
277319
name: err.name || "Error",
278320
message: err.message,
279321
stack: err.stack,
322+
logStack,
280323
});
281-
},
324+
}
282325
}
283326

327+
/** @since Beekeeper Studio 5.3.0 */
328+
export const log = new PluginLog();
329+
284330
/** Clipboard interface. */
285331
export const clipboard = {
286332
/** Write text to the Electron clipboard.
@@ -311,6 +357,43 @@ export const clipboard = {
311357
// async read() {},
312358
};
313359

360+
/**
361+
* Similar to `localStorage`, `appStorage` is a persistent storage that persists
362+
* across sessions. The data is stored in the local database of the app and
363+
* scoped to the plugin.
364+
*
365+
* @since Beekeeper Studio 5.3.0
366+
**/
367+
export const appStorage = {
368+
async getItem<T = unknown>(key: string): Promise<T | null> {
369+
return await request({ name: "getData", args: { key } });
370+
},
371+
async setItem<T = unknown>(key: string, value: T): Promise<void> {
372+
return await request({ name: "setData", args: { key, value } });
373+
},
374+
// TODO
375+
// async removeItem(key: string): Promise<void> {},
376+
// async clear(): Promise<void> {},
377+
};
378+
379+
export const workspaceConnectionStorage = {
380+
async getItem<T = unknown>(key: string): Promise<T | null> {
381+
return await request({
382+
name: "workspaceConnectionStorage.getItem",
383+
args: { key },
384+
});
385+
},
386+
async setItem<T = unknown>(key: string, value: T): Promise<void> {
387+
return await request({
388+
name: "workspaceConnectionStorage.setItem",
389+
args: { key, value },
390+
});
391+
},
392+
// TODO
393+
// async removeItem(key: string): Promise<void> {},
394+
// async clear(): Promise<void> {},
395+
};
396+
314397
/** @since Beekeeper Studio 5.5.? */
315398
export const noty = {
316399
async success(message: string): Promise<void> {
@@ -337,7 +420,7 @@ export const noty = {
337420
args: { message },
338421
});
339422
},
340-
}
423+
};
341424

342425
let debugComms = false;
343426

@@ -347,7 +430,7 @@ export function setDebugComms(enabled: boolean) {
347430

348431
export function notify<Message extends JsonValue = JsonValue>(
349432
name: "broadcast",
350-
args: { message: Message; }
433+
args: { message: Message },
351434
): void;
352435
export function notify(name: "pluginError", args: PluginErrorObject): void;
353436
export function notify(name: "windowEvent", args: WindowEventObject): void;
@@ -369,12 +452,16 @@ export function addNotificationListener(
369452
): void;
370453
export function addNotificationListener<Message extends JsonValue = JsonValue>(
371454
name: "broadcast",
372-
handler: (args: { message: Message; }) => void,
455+
handler: (args: { message: Message }) => void,
373456
): void;
374457
export function addNotificationListener(
375458
name: "themeChanged",
376459
handler: (args: AppTheme) => void,
377460
): void;
461+
export function addNotificationListener(
462+
name: "dataPollSucceeded",
463+
handler: () => void,
464+
): void;
378465
export function addNotificationListener(
379466
name: string,
380467
handler: (args: any) => void,
@@ -387,19 +474,18 @@ export function addNotificationListener(
387474

388475
export function removeNotificationListener(
389476
name: "tablesChanged",
390-
handler: (args: any) => void
391-
): void;
392-
export function removeNotificationListener<Message extends JsonValue = JsonValue>(
393-
name: "broadcast",
394-
handler: (args: any) => void
477+
handler: (args: any) => void,
395478
): void;
479+
export function removeNotificationListener<
480+
Message extends JsonValue = JsonValue,
481+
>(name: "broadcast", handler: (args: any) => void): void;
396482
export function removeNotificationListener(
397483
name: "themeChanged",
398-
handler: (args: any) => void
484+
handler: (args: any) => void,
399485
): void;
400486
export function removeNotificationListener(
401487
name: string,
402-
handler: (args: any) => void
488+
handler: (args: any) => void,
403489
) {
404490
const handlers = notificationListeners.get(name);
405491
if (handlers) {
@@ -420,9 +506,10 @@ const pendingRequests = new Map<
420506
}
421507
>();
422508

423-
export async function request<T extends keyof RequestMap>(
424-
raw: { name: T; args: RequestMap[T]["args"] }
425-
): Promise<RequestMap[T]["return"]> {
509+
export async function request<T extends keyof RequestMap>(raw: {
510+
name: T;
511+
args: RequestMap[T]["args"];
512+
}): Promise<RequestMap[T]["return"]> {
426513
const payload = { id: generateUUID(), ...raw };
427514

428515
if (debugComms) {
@@ -500,4 +587,3 @@ function generateUUID() {
500587
hex.substring(20),
501588
].join("-");
502589
}
503-

0 commit comments

Comments
 (0)