From c97c5f0b09aa6df08b4f80e40a9914029bb646f3 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Sun, 1 Dec 2024 10:50:24 +0500 Subject: [PATCH 1/3] refactor: move plugin api to separate package --- apps/cli | 2 +- package-lock.json | 280 +++++++++++++++++++++++++++++++ packages/api/.gitignore | 4 + packages/api/LICENSE | 21 +++ packages/api/eslint.config.mjs | 10 ++ packages/api/package.json | 55 ++++++ packages/api/prettier.config.mjs | 8 + packages/api/streamyx.d.ts | 7 + packages/api/streamyx.js | 0 packages/api/types/app.d.ts | 13 ++ packages/api/types/global.d.ts | 7 + packages/api/types/http.d.ts | 14 ++ packages/api/types/logger.d.ts | 8 + packages/api/types/prompt.d.ts | 6 + packages/api/types/storage.d.ts | 5 + packages/api/types/utils.d.ts | 24 +++ 16 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 packages/api/.gitignore create mode 100644 packages/api/LICENSE create mode 100644 packages/api/eslint.config.mjs create mode 100644 packages/api/package.json create mode 100644 packages/api/prettier.config.mjs create mode 100644 packages/api/streamyx.d.ts create mode 100644 packages/api/streamyx.js create mode 100644 packages/api/types/app.d.ts create mode 100644 packages/api/types/global.d.ts create mode 100644 packages/api/types/http.d.ts create mode 100644 packages/api/types/logger.d.ts create mode 100644 packages/api/types/prompt.d.ts create mode 100644 packages/api/types/storage.d.ts create mode 100644 packages/api/types/utils.d.ts diff --git a/apps/cli b/apps/cli index 24b8cde..ba6084d 160000 --- a/apps/cli +++ b/apps/cli @@ -1 +1 @@ -Subproject commit 24b8cdebfee13e5f23954e02f6bf393dcde53ef6 +Subproject commit ba6084ddec23de61242bd51e6756e4d925ebc1d1 diff --git a/package-lock.json b/package-lock.json index 244ceb3..d15126e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4634,6 +4634,10 @@ "solid-js": "^1.8.6" } }, + "node_modules/@streamyx/api": { + "resolved": "packages/api", + "link": true + }, "node_modules/@streamyx/browser": { "resolved": "packages/browser", "link": true @@ -19702,6 +19706,282 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "packages/api": { + "name": "@streamyx/api", + "version": "0.0.2", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@eslint/js": "^9.16.0", + "@types/node": "^22.10.1", + "eslint": "^9.16.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.12.0", + "prettier": "^3.4.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, + "packages/api/node_modules/@eslint/config-array": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "packages/api/node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/api/node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/api/node_modules/@eslint/js": { + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "packages/api/node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "packages/api/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "packages/api/node_modules/eslint": { + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", + "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.16.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.5", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "packages/api/node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/api/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/api/node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/api/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "packages/api/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "packages/api/node_modules/globals": { + "version": "15.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", + "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/api/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "packages/browser": { "name": "@streamyx/browser", "version": "0.0.1", diff --git a/packages/api/.gitignore b/packages/api/.gitignore new file mode 100644 index 0000000..becd09b --- /dev/null +++ b/packages/api/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +build +.DS_Store diff --git a/packages/api/LICENSE b/packages/api/LICENSE new file mode 100644 index 0000000..6ed8df4 --- /dev/null +++ b/packages/api/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Vitaly Gashkov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/api/eslint.config.mjs b/packages/api/eslint.config.mjs new file mode 100644 index 0000000..96072c8 --- /dev/null +++ b/packages/api/eslint.config.mjs @@ -0,0 +1,10 @@ +import globals from 'globals'; +import pluginJs from '@eslint/js'; +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; + +export default [ + { files: ['**/*.js'], languageOptions: { sourceType: 'commonjs' } }, + { languageOptions: { globals: globals.node } }, + pluginJs.configs.recommended, + eslintPluginPrettierRecommended, +]; diff --git a/packages/api/package.json b/packages/api/package.json new file mode 100644 index 0000000..5a04814 --- /dev/null +++ b/packages/api/package.json @@ -0,0 +1,55 @@ +{ + "name": "@streamyx/api", + "version": "0.0.2", + "description": "Type definitions for the latest Streamyx API", + "main": "streamyx.js", + "types": "streamyx.d.ts", + "files": [ + "streamyx.js", + "streamyx.d.ts", + "types" + ], + "scripts": { + "lint": "eslint . && prettier --check .", + "fix": "eslint . --fix && prettier --write ." + }, + "repository": { + "type": "git", + "url": "git+https://github.com/vitalygashkov/streamyx.git" + }, + "keywords": [ + "streamyx", + "types", + "api" + ], + "bugs": { + "url": "https://github.com/vitalygashkov/streamyx/issues", + "email": "vitalygashkov@vk.com" + }, + "author": "Vitaly Gashkov ", + "license": "MIT", + "readmeFilename": "README.md", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "engines": { + "node": "20 || 21 || 22 || 23" + }, + "devDependencies": { + "@eslint/js": "^9.16.0", + "@types/node": "^22.10.1", + "eslint": "^9.16.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.12.0", + "prettier": "^3.4.1", + "typescript": "^5.7.2" + } +} diff --git a/packages/api/prettier.config.mjs b/packages/api/prettier.config.mjs new file mode 100644 index 0000000..0edf463 --- /dev/null +++ b/packages/api/prettier.config.mjs @@ -0,0 +1,8 @@ +export default { + printWidth: 80, + singleQuote: true, + trailingComma: 'all', + tabWidth: 2, + useTabs: false, + semi: true, +}; diff --git a/packages/api/streamyx.d.ts b/packages/api/streamyx.d.ts new file mode 100644 index 0000000..84d19d3 --- /dev/null +++ b/packages/api/streamyx.d.ts @@ -0,0 +1,7 @@ +import './types/global'; + +export * from './types/app'; +export * from './types/http'; +export * from './types/logger'; +export * from './types/prompt'; +export * from './types/utils'; diff --git a/packages/api/streamyx.js b/packages/api/streamyx.js new file mode 100644 index 0000000..e69de29 diff --git a/packages/api/types/app.d.ts b/packages/api/types/app.d.ts new file mode 100644 index 0000000..18fb2c2 --- /dev/null +++ b/packages/api/types/app.d.ts @@ -0,0 +1,13 @@ +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 new file mode 100644 index 0000000..a03ce51 --- /dev/null +++ b/packages/api/types/global.d.ts @@ -0,0 +1,7 @@ +import { App } from './app'; +import { AppStorage } from './storage'; + +declare global { + const app: App; + const storage: AppStorage; +} diff --git a/packages/api/types/http.d.ts b/packages/api/types/http.d.ts new file mode 100644 index 0000000..a64cd07 --- /dev/null +++ b/packages/api/types/http.d.ts @@ -0,0 +1,14 @@ +export type AppHttp = { + headers: Record; + cookies: string[]; + userAgents: Record<'chromeWindows' | 'chromeMacOS' | 'chromeLinux' | 'smartTv' | 'tizen', string>; + fetch(resource: string | URL | Request, options?: RequestInit): Promise; + fetchAsChrome(resource: string | URL | Request, options?: RequestInit): Promise; + appendCookies(setCookie: string | string[]): void; + setAgent(proxy?: string | null): void; + setCookies(cookies: string[]): void; + setHeader(name: string, value: string): void; + setHeaders(headers: Record): void; + removeHeader(name: string): void; + destroySessions(): Promise; +}; diff --git a/packages/api/types/logger.d.ts b/packages/api/types/logger.d.ts new file mode 100644 index 0000000..0d0fad7 --- /dev/null +++ b/packages/api/types/logger.d.ts @@ -0,0 +1,8 @@ +export type LogFn = (msg: string, ...args: any[]) => void; + +export type AppLogger = { + info: LogFn; + warn: LogFn; + error: LogFn; + debug: LogFn; +}; diff --git a/packages/api/types/prompt.d.ts b/packages/api/types/prompt.d.ts new file mode 100644 index 0000000..3cb5678 --- /dev/null +++ b/packages/api/types/prompt.d.ts @@ -0,0 +1,6 @@ +export type PromptFormResponse = { [field: string]: string }; + +export type AppPrompt = { + ask(form: PromptForm): Promise; + listen(listener: (form: PromptForm) => Promise): void; +}; diff --git a/packages/api/types/storage.d.ts b/packages/api/types/storage.d.ts new file mode 100644 index 0000000..970f9aa --- /dev/null +++ b/packages/api/types/storage.d.ts @@ -0,0 +1,5 @@ +export type AppStorage = { + state: Record; + getState: (cookiesKey?: string | null) => Promise; + setState: >(data?: T) => Promise; +}; diff --git a/packages/api/types/utils.d.ts b/packages/api/types/utils.d.ts new file mode 100644 index 0000000..ed7192e --- /dev/null +++ b/packages/api/types/utils.d.ts @@ -0,0 +1,24 @@ +export type AppUtils = { + sanitizeString: (text: string) => string; + + execUrlPatterns: ( + url: string, + patterns: string[], + baseUrls: string[] + ) => { + pathname: Record; + search: Record; + }; + + safeEval: (jsObjectString: string) => T | null; + + extendEpisodes: (episodesBySeasons?: Map>) => { + items: Map>; + has: (episode?: number, season?: number) => boolean; + set: (episode?: number, season?: number) => void; + getMin: () => number; + getMax: () => number; + seasonsCount: number; + episodesCount: number; + }; +}; From 8c3fa75982dfbd83dda67a03ab05593836d71211 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Sun, 1 Dec 2024 13:05:51 +0500 Subject: [PATCH 2/3] feat(api): improve storage API, move store & http from app to global --- apps/cli | 2 +- packages/api/types/app.d.ts | 4 --- packages/api/types/global.d.ts | 2 ++ packages/api/types/prompt.d.ts | 7 +++++ packages/api/types/storage.d.ts | 13 +++++---- packages/core/lib/store.ts | 52 +++++++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 10 deletions(-) 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; From afc7f82d9a7018927c620867501afbbeb10fd63a Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Sun, 1 Dec 2024 13:29:25 +0500 Subject: [PATCH 3/3] feat: expose logger to plugin context --- apps/cli | 2 +- packages/api/types/global.d.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/cli b/apps/cli index f1d6811..6ae695a 160000 --- a/apps/cli +++ b/apps/cli @@ -1 +1 @@ -Subproject commit f1d68118c25b06950a3cd45e8c6514dca7d39008 +Subproject commit 6ae695aa63122001e5c2fe6500a32cb939392e22 diff --git a/packages/api/types/global.d.ts b/packages/api/types/global.d.ts index fa2b008..cb7c92a 100644 --- a/packages/api/types/global.d.ts +++ b/packages/api/types/global.d.ts @@ -1,9 +1,11 @@ import { App } from './app'; import { AppStorage } from './storage'; import { AppHttp } from './http'; +import { AppLogger } from './logger'; declare global { const app: App; const storage: AppStorage; const http: AppHttp; + const logger: AppLogger; }