1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-15 09:04:04 +02:00
joplin/packages/tools/bundleDefaultPlugins.ts

97 lines
4.1 KiB
TypeScript

import { join } from 'path';
import { pathExists, mkdir, readFile, move, remove, writeFile } from 'fs-extra';
import { DefaultPluginsInfo } from '@joplin/lib/services/plugins/PluginService';
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
import { execCommand } from '@joplin/utils';
const fetch = require('node-fetch');
interface PluginAndVersion {
[pluginId: string]: string;
}
interface PluginIdAndName {
[pluginId: string]: string;
}
export const localPluginsVersion = async (defaultPluginDir: string, defaultPluginsInfo: DefaultPluginsInfo): Promise<PluginAndVersion> => {
if (!await pathExists(join(defaultPluginDir))) await mkdir(defaultPluginDir);
const localPluginsVersions: PluginAndVersion = {};
for (const pluginId of Object.keys(defaultPluginsInfo)) {
if (!await pathExists(join(defaultPluginDir, pluginId))) {
localPluginsVersions[pluginId] = '0.0.0';
continue;
}
const data = await readFile(`${defaultPluginDir}/${pluginId}/manifest.json`, 'utf8');
const manifest = JSON.parse(data);
localPluginsVersions[pluginId] = manifest.version;
}
return localPluginsVersions;
};
async function downloadFile(url: string, outputPath: string) {
const response = await fetch(url);
if (!response.ok) {
const responseText = await response.text();
throw new Error(`Cannot download file from ${url} : ${responseText.substr(0, 500)}`);
}
await writeFile(outputPath, await response.buffer());
}
export async function extractPlugins(currentDir: string, defaultPluginDir: string, downloadedPluginsNames: PluginIdAndName): Promise<void> {
for (const pluginId of Object.keys(downloadedPluginsNames)) {
await execCommand(`tar xzf ${currentDir}/${downloadedPluginsNames[pluginId]}`, { quiet: true });
await move(`package/publish/${pluginId}.jpl`, `${defaultPluginDir}/${pluginId}/plugin.jpl`, { overwrite: true });
await move(`package/publish/${pluginId}.json`, `${defaultPluginDir}/${pluginId}/manifest.json`, { overwrite: true });
await remove(`${downloadedPluginsNames[pluginId]}`);
await remove('package');
}
}
export const downloadPlugins = async (localPluginsVersions: PluginAndVersion, defaultPluginsInfo: DefaultPluginsInfo, manifests: any): Promise<PluginIdAndName> => {
const downloadedPluginsNames: PluginIdAndName = {};
for (const pluginId of Object.keys(defaultPluginsInfo)) {
if (localPluginsVersions[pluginId] === defaultPluginsInfo[pluginId].version) continue;
const response = await fetch(`https://registry.npmjs.org/${manifests[pluginId]._npm_package_name}`);
if (!response.ok) {
const responseText = await response.text();
throw new Error(`Cannot fetch ${manifests[pluginId]._npm_package_name} release info from NPM : ${responseText.substr(0, 500)}`);
}
const releaseText = await response.text();
const release = JSON.parse(releaseText);
const pluginUrl = release.versions[defaultPluginsInfo[pluginId].version].dist.tarball;
const pluginName = `${manifests[pluginId]._npm_package_name}-${defaultPluginsInfo[pluginId].version}.tgz`;
await downloadFile(pluginUrl, pluginName);
downloadedPluginsNames[pluginId] = pluginName;
}
return downloadedPluginsNames;
};
async function start(): Promise<void> {
const defaultPluginDir = join(__dirname, '..', '..', 'packages', 'app-desktop', 'build', 'defaultPlugins');
const defaultPluginsInfo = getDefaultPluginsInfo();
const manifestData = await fetch('https://raw.githubusercontent.com/joplin/plugins/master/manifests.json');
const manifests = JSON.parse(await manifestData.text());
if (!manifests) throw new Error('Invalid or missing JSON');
const localPluginsVersions = await localPluginsVersion(defaultPluginDir, defaultPluginsInfo);
const downloadedPluginNames: PluginIdAndName = await downloadPlugins(localPluginsVersions, defaultPluginsInfo, manifests);
await extractPlugins(__dirname, defaultPluginDir, downloadedPluginNames);
}
if (require.main === module) {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
start().catch((error) => {
console.error('Fatal error');
console.error(error);
process.exit(1);
});
}