diff --git a/modules/desktop/electron/electron.ts b/modules/desktop/electron/electron.ts index a2d96e5b..40c25a3b 100644 --- a/modules/desktop/electron/electron.ts +++ b/modules/desktop/electron/electron.ts @@ -5,6 +5,7 @@ import serve from 'electron-serve'; import path from 'path'; import fs from 'fs'; +import { getInstalledPackages } from './libs/teaDir'; try { //@ts-ignore only used in dev should not be packaged inprod /* eslint-disable */ @@ -108,25 +109,7 @@ ipcMain.on('to-main', (event, count) => { }); ipcMain.handle('get-installed-packages', async () => { - const homePath = app.getPath('home'); - const teaPath = path.join(homePath, '.tea'); - const folders = await deepReadDir(teaPath); - return folders; + console.log('get installed pkgs: ipc'); + const pkgs = await getInstalledPackages(); + return pkgs; }); - -const deepReadDir = async (dirPath) => { - let arrayOfFiles; - try { - arrayOfFiles = fs.readdirSync(dirPath); - console.log(arrayOfFiles); - } catch (e) { - console.log(e); - } - // await Promise.all( - // (await readdir(dirPath, {withFileTypes: true})).map(async (dirent) => { - // const path = join(dirPath, dirent.name) - // return dirent.isDirectory() ? await deepReadDir(path) : path - // }), - // ) - return arrayOfFiles; -}; diff --git a/modules/desktop/electron/libs/teaDir.ts b/modules/desktop/electron/libs/teaDir.ts new file mode 100644 index 00000000..0cbe9d3e --- /dev/null +++ b/modules/desktop/electron/libs/teaDir.ts @@ -0,0 +1,88 @@ +// import { readDir, BaseDirectory } from '@tauri-apps/api/fs'; +import fs from 'fs'; +import path from 'path'; +import { app } from 'electron'; +import semver from 'semver'; + +type Dir = { + name: string; + path: string; + children?: Dir[]; +}; +export async function getInstalledPackages() { + const homePath = app.getPath('home'); + const pkgsPath = path.join(homePath, './.tea'); + + const folders = await deepReadDir({ + dir: pkgsPath, + continueDeeper: (name: string) => !semver.valid(name), + filter: (name: string) => !!semver.valid(name) + }); + + const pkgs = folders + .map((p: string) => p.split('.tea/')[1]) + .filter((p: string) => !p.includes('tea.xyz')) + .map((p: string) => { + const path = p.trim().split('/'); + const version = path.pop(); + return { + version: semver.clean(version || ''), + full_name: path.join('/') + }; + }); + + return pkgs; +} + +const semverTest = + /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/g; + +export const getPkgBottles = (packageDir: Dir): string[] => { + const bottles: string[] = []; + + const pkg = packageDir.path.split('.tea/')[1]; + const version = pkg.split('/v')[1]; + + const isVersion = semverTest.test(version) || !isNaN(+version) || version === '*'; + + if (version && isVersion) { + bottles.push(pkg); + } else if (packageDir?.children?.length) { + const childBottles = packageDir.children + .map(getPkgBottles) + .reduce((arr, bottles) => [...arr, ...bottles], []); + bottles.push(...childBottles); + } + + return bottles.filter((b) => b !== undefined).sort(); // ie: ["gohugo.io/v*", "gohugo.io/v0", "gohugo.io/v0.108", "gohugo.io/v0.108.0"] +}; + +const deepReadDir = async ({ + dir, + continueDeeper, + filter +}: { + dir: string; + continueDeeper?: (name: string) => boolean; + filter?: (name: string) => boolean; +}) => { + const arrayOfFiles: string[] = []; + try { + const files = fs.readdirSync(dir, { withFileTypes: true }); + for (const f of files) { + const nextPath = path.join(dir, f.name); + const deeper = continueDeeper ? continueDeeper(f.name) : true; + if (f.isDirectory() && deeper) { + const nextFiles = await deepReadDir({ dir: nextPath, continueDeeper, filter }); + arrayOfFiles.push(...nextFiles); + } else if (filter && filter(f.name)) { + arrayOfFiles.push(nextPath); + } else if (!filter) { + arrayOfFiles.push(nextPath); + } + } + } catch (e) { + console.log(e); + } + return arrayOfFiles; +}; diff --git a/modules/desktop/package.json b/modules/desktop/package.json index 14aa0b8e..790e0a4f 100644 --- a/modules/desktop/package.json +++ b/modules/desktop/package.json @@ -82,6 +82,7 @@ "fuse.js": "^6.6.2", "lodash": "^4.17.21", "lorem-ipsum": "^2.0.8", + "semver": "^7.3.8", "svelte-markdown": "^0.2.3", "svelte-watch-resize": "^1.0.3", "upath": "^2.0.1", diff --git a/modules/desktop/src/libs/api/mock.ts b/modules/desktop/src/libs/api/mock.ts index 83896aef..bfc12325 100644 --- a/modules/desktop/src/libs/api/mock.ts +++ b/modules/desktop/src/libs/api/mock.ts @@ -156,7 +156,6 @@ const packages: Package[] = [ ]; export async function getPackages(): Promise { - await getInstalledPackages(); return packages.map((pkg) => { return { ...pkg, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1dc11d32..3c5e2b20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,7 @@ importers: prettier: ^2.7.1 prettier-plugin-svelte: ^2.7.0 prettier-plugin-tailwindcss: ^0.2.0 + semver: ^7.3.8 svelte: ^3.55.1 svelte-check: ^2.8.0 svelte-markdown: ^0.2.3 @@ -76,6 +77,7 @@ importers: fuse.js: 6.6.2 lodash: 4.17.21 lorem-ipsum: 2.0.8 + semver: 7.3.8 svelte-markdown: 0.2.3_svelte@3.55.1 svelte-watch-resize: 1.0.3 upath: 2.0.1 @@ -9531,7 +9533,6 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - dev: true /lz-string/1.4.4: resolution: {integrity: sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==} @@ -11493,7 +11494,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /send/0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} @@ -13556,7 +13556,6 @@ packages: /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true /yaml/1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}