diff --git a/apps/cli b/apps/cli index ba6084d..f1d6811 160000 --- a/apps/cli +++ b/apps/cli @@ -1 +1 @@ -Subproject commit ba6084ddec23de61242bd51e6756e4d925ebc1d1 +Subproject commit f1d68118c25b06950a3cd45e8c6514dca7d39008 diff --git a/packages/api/types/app.d.ts b/packages/api/types/app.d.ts index 18fb2c2..012a28d 100644 --- a/packages/api/types/app.d.ts +++ b/packages/api/types/app.d.ts @@ -1,13 +1,9 @@ -import type { AppHttp } from './http'; import type { AppLogger } from './logger'; import type { AppPrompt } from './prompt'; -import type { AppStorage } from './storage'; import type { AppUtils } from './utils'; export type App = { log: AppLogger; - http: AppHttp; prompt: AppPrompt; - store: AppStorage; utils: AppUtils; }; diff --git a/packages/api/types/global.d.ts b/packages/api/types/global.d.ts index a03ce51..fa2b008 100644 --- a/packages/api/types/global.d.ts +++ b/packages/api/types/global.d.ts @@ -1,7 +1,9 @@ import { App } from './app'; import { AppStorage } from './storage'; +import { AppHttp } from './http'; declare global { const app: App; const storage: AppStorage; + const http: AppHttp; } diff --git a/packages/api/types/prompt.d.ts b/packages/api/types/prompt.d.ts index 3cb5678..0907e89 100644 --- a/packages/api/types/prompt.d.ts +++ b/packages/api/types/prompt.d.ts @@ -1,3 +1,10 @@ +export type PromptForm = { + title?: string; + subtitle?: string; +} & { + [field: string]: { label: string; defaultValue?: string }; +}; + export type PromptFormResponse = { [field: string]: string }; export type AppPrompt = { diff --git a/packages/api/types/storage.d.ts b/packages/api/types/storage.d.ts index 970f9aa..e3c90ac 100644 --- a/packages/api/types/storage.d.ts +++ b/packages/api/types/storage.d.ts @@ -1,5 +1,8 @@ -export type AppStorage = { - state: Record; - getState: (cookiesKey?: string | null) => Promise; - setState: >(data?: T) => Promise; -}; +export type AppStorage> = { + load(): Promise; + get(key: string): Promise; + set(key: string, value: any): Promise; + delete(key: string): Promise; + clear(): Promise; + save(items: T): Promise; +} & T; diff --git a/packages/core/lib/store.ts b/packages/core/lib/store.ts index e893498..83cdc5e 100644 --- a/packages/core/lib/store.ts +++ b/packages/core/lib/store.ts @@ -26,6 +26,58 @@ const getCookiesFromTxt = async (dir: string) => { return cookies; }; +export const createStorage = async (name: string) => { + const storageDir = initDir(join(getSettings().servicesDir, name)); + const storagePath = join(storageDir, `${name}.storage.json`); + + const configPath = join(storageDir, 'config.json'); + if (fs.exists(configPath)) await fs.rename(configPath, storagePath); + + const serializable = (obj: any) => { + const result: any = {}; + for (const [key, value] of Object.entries(obj)) { + if (typeof value !== 'function') result[key] = value; + } + return result; + }; + + const storage: Record = { + async load() { + const data = (await fs.readJson(storagePath).catch(() => {})) || {}; + for (const [key, value] of Object.entries(data)) storage[key] = value; + // Automatically load cookies from cookies.txt + const cookies = await getCookiesFromTxt(storagePath); + if (!!cookies.length) await storage.set('cookies', cookies); + }, + async get(key: string) { + const data = (await fs.readJson(storagePath).catch(() => {})) || {}; + return data[key]; + }, + async set(key: string, value: any) { + storage[key] = value; + await fs.writeJson(storagePath, serializable(storage)); + }, + async delete(key: string) { + delete storage[key]; + await fs.writeJson(storagePath, serializable(storage)); + }, + async clear() { + for (const [key, value] of Object.entries(storage)) { + const isFn = typeof value === 'function'; + if (!isFn) delete storage[key]; + } + await fs.writeJson(storagePath, serializable(storage)); + }, + async save(items?: Record) { + const data = items || serializable(storage); + for (const [key, value] of Object.entries(data)) storage[key] = value; + await fs.writeJson(storagePath, data); + }, + }; + + return storage; +}; + export const createStore = (name: string) => { const storePath = createStorePath(name); const state = {} as Record;