From c785d49fa5c0d98261de7d7b0c39f85c21316156 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Mon, 4 Sep 2023 22:28:08 -0500 Subject: [PATCH] feat(plugins)!: new method to obtain plugins (#114) BREAKING CHANGE: older versions of cli does not have plugins command functional --- src/commands/plugins.ts | 60 +++++++++++++++++++++++++++++++++-------- src/prompts/plugin.ts | 18 +++---------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/commands/plugins.ts b/src/commands/plugins.ts index 57d6da3..a9a195e 100644 --- a/src/commands/plugins.ts +++ b/src/commands/plugins.ts @@ -4,18 +4,62 @@ import prompt from 'prompts'; import { fetch } from 'undici'; import { pluginsQ } from '../prompts/plugin.js'; import { fromCwd } from '../utilities/fromCwd.js'; +import esbuild from 'esbuild' +import { getLang } from '../utilities/getLang.js'; +import { resolve } from 'path' +import { require } from '../utilities/require.js' +interface PluginData { + "description" : string, + "hash" : string, + "name" : string, + "author" : string[], + "link" : string, + "example" : string, + "version" : "1.0.0" +} /** * Installs plugins to project */ export async function plugins() { - const e: string[] = (await prompt([await pluginsQ()])).list; + const e: PluginData[] = (await prompt([await pluginsQ()])).list; if (!e) process.exit(1); - for await (const url of e) { - await download(url); + const lang = await getLang(); + for await (const plgData of e) { + const pluginText = await download(plgData.link); + const dir = fromCwd('/src/plugins'); + const linkNoExtension = `${process.cwd()}/src/plugins/${plgData.name}`; + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + if(lang === 'typescript') { + fs.writeFileSync(linkNoExtension+".ts", pluginText); + } else { + const { type=undefined } = require(resolve('package.json')) + const format = (type === undefined || type === 'cjs') ? 'cjs' : 'esm' + const transformResult = await esbuild.transform(pluginText, { + target: 'node18', + format, + loader: 'ts', + banner: `/**\n Partial information: ${plgData.description}\n @author ${plgData.author}\n @example${plgData.example}*/` + }); + if(transformResult.warnings.length > 0) { + console.log(transformResult + .warnings + .map(msg => msg.text) + .join('\n')) + } + console.warn("transforming plugins with js strips comments"); + console.warn("We provided some minimal information at top of file, or view the documentation for this plugin here:") + console.warn(plgData.link); + fs.writeFileSync(linkNoExtension+".js", transformResult.code); + } } - const pluginNames = e.map((e) => e.split('/').pop()); + + const pluginNames = e.map((data) => { + return "Installed " + data.name+" "+"from "+data.author.join(','); + }); console.log(`Successfully downloaded plugin(s):\n${greenBright(pluginNames.join('\n'))}`); } @@ -26,11 +70,5 @@ async function download(url: string) { if (!data) throw new Error('Download failed! Kindly contact developers'); - const dir = `${fromCwd('/src/plugins')}`; - const filedir = `${process.cwd()}/src/plugins/${url.split('/').pop()}`; - - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - fs.writeFileSync(filedir, data); + return data } diff --git a/src/prompts/plugin.ts b/src/prompts/plugin.ts index 7d1b8fb..b994505 100644 --- a/src/prompts/plugin.ts +++ b/src/prompts/plugin.ts @@ -1,28 +1,18 @@ import type { Choice, PromptObject } from 'prompts'; import { fetch } from 'undici'; -import { getLang } from '../utilities/getLang.js'; -function upperCase(string: string | null) { - if (string === null) { - console.error('Lang property not found!'); - process.exit(0); - } - return string === 'typescript' ? 'TypeScript' : 'JavaScript'; -} async function gimmechoices(): Promise { - const lang = upperCase(await getLang().catch(() => null)); - - const link = `https://api.github.com/repos/sern-handler/awesome-plugins/contents/${lang}`; + const link = `https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/pluginlist.json`; const resp = await fetch(link).catch(() => null); if (!resp) return [{ title: 'No plugins found!', value: '', disabled: true }]; - const data = (await resp.json()) as Data[]; const choices = data.map((e) => ({ title: e.name, - value: e.download_url, + value: e, })); + return choices; } @@ -38,5 +28,5 @@ export async function pluginsQ(): Promise { interface Data { name: string; - download_url: string; + link: string; }