You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2026-01-20 00:46:28 +02:00
Compare commits
1 Commits
plugin-gen
...
release_se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca7392a704 |
@@ -7,30 +7,29 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"bootstrap": "lerna bootstrap --no-ci",
|
||||
"bootstrapIgnoreScripts": "lerna bootstrap --ignore-scripts --no-ci",
|
||||
"build": "lerna run build && npm run tsc",
|
||||
"buildApiDoc": "npm start --prefix=packages/app-cli -- apidoc ../../readme/api/references/rest_api.md",
|
||||
"buildDoc": "./packages/tools/build-all.sh",
|
||||
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out docs/api/references/plugin_api packages/lib/services/plugins/api/",
|
||||
"buildTranslations": "npm run tsc && node packages/tools/build-translation.js",
|
||||
"buildTranslationsNoTsc": "node packages/tools/build-translation.js",
|
||||
"buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc",
|
||||
"circularDependencyCheck": "npx madge --warning --circular --extensions js ./",
|
||||
"clean": "lerna clean -y && lerna run clean",
|
||||
"circularDependencyCheck": "npx madge --warning --circular --extensions js ./",
|
||||
"generateDatabaseTypes": "node packages/tools/generate-database-types",
|
||||
"linkChecker": "linkchecker https://joplinapp.org",
|
||||
"linter-ci": "./node_modules/.bin/eslint --resolve-plugins-relative-to . --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter-precommit": "./node_modules/.bin/eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter": "./node_modules/.bin/eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"bootstrap": "lerna bootstrap --no-ci",
|
||||
"bootstrapIgnoreScripts": "lerna bootstrap --ignore-scripts --no-ci",
|
||||
"postinstall": "npm run bootstrap --no-ci && npm run build",
|
||||
"build": "lerna run build && npm run tsc",
|
||||
"publishAll": "git pull && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "node packages/tools/release-android.js",
|
||||
"releaseCli": "node packages/tools/release-cli.js",
|
||||
"releaseClipper": "node packages/tools/release-clipper.js",
|
||||
"releaseDesktop": "node packages/tools/release-electron.js",
|
||||
"releasePluginGenerator": "node packages/tools/release-plugin-generator.js",
|
||||
"releaseServer": "node packages/tools/release-server.js",
|
||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||
"test-ci": "lerna run test-ci --stream",
|
||||
"test": "lerna run test --stream",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
|
||||
const { newPluginService, newPluginScript, setupDatabaseAndSynchronizer, switchClient, afterEachCleanUp } = require('../../../test-utils');
|
||||
@@ -50,26 +49,4 @@ describe('JoplinWorkspace', () => {
|
||||
await service.destroy();
|
||||
});
|
||||
|
||||
test('should return the selected folder', async () => {
|
||||
const service = new newPluginService() as PluginService;
|
||||
|
||||
const pluginScript = newPluginScript(`
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
const folder = await joplin.workspace.selectedFolder();
|
||||
await joplin.data.put(['folders', folder.id], null, { title: "changedtitle" });
|
||||
},
|
||||
});
|
||||
`);
|
||||
|
||||
const folder = await Folder.save({ title: 'folder' });
|
||||
Setting.setValue('activeFolderId', folder.id);
|
||||
|
||||
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
|
||||
await service.runPlugin(plugin);
|
||||
|
||||
const modFolder = await Folder.load(folder.id);
|
||||
expect(modFolder.title).toBe('changedtitle');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
Binary file not shown.
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,8 +18,7 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"left-pad": "^1.3.0"
|
||||
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
19
packages/app-cli/tests/support/plugins/package.json
Normal file
19
packages/app-cli/tests/support/plugins/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "test_plugin",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
"copy-webpack-plugin": "^6.0.3",
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,7 +18,6 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
Binary file not shown.
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,8 +18,7 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"uslug": "^1.0.4"
|
||||
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"keywords": ["joplin-plugin"],
|
||||
"keywords": {},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
@@ -18,8 +18,7 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"typescript": "^3.9.3",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"chalk": "^4.1.0"
|
||||
"webpack-cli": "^3.3.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"left-pad": "^1.3.0"
|
||||
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
2
packages/app-desktop/package-lock.json
generated
2
packages/app-desktop/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "1.6.2",
|
||||
"version": "1.6.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "1.6.2",
|
||||
"version": "1.6.1",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -3,20 +3,12 @@
|
||||
const Generator = require('yeoman-generator');
|
||||
const chalk = require('chalk');
|
||||
const yosay = require('yosay');
|
||||
const slugify = require('slugify');
|
||||
|
||||
function mergePackageKey(parentKey, source, dest) {
|
||||
const output = Object.assign({}, dest);
|
||||
|
||||
for (const k in source) {
|
||||
if (k === 'keywords' && !Array.isArray(output[k])) {
|
||||
// Fix an earlier bugs where keywords were set to an empty object
|
||||
output[k] = source[k];
|
||||
} else if (k === 'keywords') {
|
||||
// For keywords, make sure to add the "joplin-plugin" one
|
||||
if (!output['keywords']) output['keywords'] = [];
|
||||
if (output['keywords'].indexOf('joplin-plugin') < 0) output['keywords'].push('joplin-plugin');
|
||||
} else if (!(k in output)) {
|
||||
if (!(k in output)) {
|
||||
// If the key doesn't exist in the destination, add it
|
||||
output[k] = source[k];
|
||||
} else if (parentKey === 'devDependencies') {
|
||||
@@ -35,18 +27,6 @@ function mergePackageKey(parentKey, source, dest) {
|
||||
return output;
|
||||
}
|
||||
|
||||
function packageNameFromPluginName(pluginName) {
|
||||
return `joplin-plugin-${slugify(pluginName, {
|
||||
lower: true,
|
||||
})}`;
|
||||
}
|
||||
|
||||
function addDerivedProps(props) {
|
||||
return Object.assign({}, props, {
|
||||
packageName: packageNameFromPluginName(props.pluginName),
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = class extends Generator {
|
||||
|
||||
constructor(args, opts) {
|
||||
@@ -106,11 +86,6 @@ module.exports = class extends Generator {
|
||||
name: 'pluginAuthor',
|
||||
message: 'Author:',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'pluginRepositoryUrl',
|
||||
message: 'Repository URL:',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'pluginHomepageUrl',
|
||||
@@ -123,10 +98,10 @@ module.exports = class extends Generator {
|
||||
for (const prompt of prompts) {
|
||||
props[prompt.name] = '';
|
||||
}
|
||||
this.props = addDerivedProps(props);
|
||||
this.props = props;
|
||||
} else {
|
||||
return this.prompt(prompts).then(props => {
|
||||
this.props = addDerivedProps(props);
|
||||
this.props = props;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -139,10 +114,9 @@ module.exports = class extends Generator {
|
||||
|
||||
const files = [
|
||||
'.gitignore_TEMPLATE',
|
||||
'.npmignore_TEMPLATE',
|
||||
'GENERATOR_DOC.md',
|
||||
'package_TEMPLATE.json',
|
||||
'README.md',
|
||||
'GENERATOR_DOC.md',
|
||||
'tsconfig.json',
|
||||
'webpack.config.js',
|
||||
];
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
dist/
|
||||
dist/*
|
||||
node_modules/
|
||||
publish/
|
||||
*.jpl
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.md
|
||||
!README.md
|
||||
/*.jpl
|
||||
/api
|
||||
/src
|
||||
/dist
|
||||
tsconfig.json
|
||||
webpack.config.js
|
||||
@@ -37,16 +37,6 @@ To build the plugin, simply run `npm run dist`.
|
||||
|
||||
The project is setup to use TypeScript, although you can change the configuration to use plain JavaScript.
|
||||
|
||||
## Publishing the plugin
|
||||
|
||||
To publish the plugin, add it to npmjs.com by running `npm publish`. Later on, a script will pick up your plugin and add it automatically to the Joplin plugin repository as long as the package satisfies these conditions:
|
||||
|
||||
- In `package.json`, the name starts with "joplin-plugin-". For example, "joplin-plugin-toc".
|
||||
- In `package.json`, the keywords include "joplin-plugin".
|
||||
- In the `publish/` directory, there should be a .jpl and .json file (which are built by `npm run dist`)
|
||||
|
||||
In general all this is done automatically by the plugin generator, which will set the name and keywords of package.json, and will put the right files in the "publish" directory. But if something doesn't work and your plugin doesn't appear in the repository, double-check the above conditions.
|
||||
|
||||
## Updating the plugin framework
|
||||
|
||||
To update the plugin framework, run `yo joplin --update`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { FolderEntity } from '../../database/types';
|
||||
import { Disposable } from './types';
|
||||
declare enum ItemChangeEventType {
|
||||
Create = 1,
|
||||
@@ -54,13 +53,6 @@ export default class JoplinWorkspace {
|
||||
* Gets the currently selected note
|
||||
*/
|
||||
selectedNote(): Promise<any>;
|
||||
/**
|
||||
* Gets the currently selected folder. In some cases, for example during
|
||||
* search or when viewing a tag, no folder is actually selected in the user
|
||||
* interface. In that case, that function would return the last selected
|
||||
* folder.
|
||||
*/
|
||||
selectedFolder(): Promise<FolderEntity>;
|
||||
/**
|
||||
* Gets the IDs of the selected notes (can be zero, one, or many). Use the data API to retrieve information about these notes.
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
{
|
||||
"name": "<%= packageName %>",
|
||||
"name": "joplin_plugin",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dist": "webpack",
|
||||
"prepare": "npm run dist"
|
||||
"postinstall": "npm run dist"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"joplin-plugin"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.14",
|
||||
"chalk": "^4.1.0",
|
||||
"copy-webpack-plugin": "^6.1.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"glob": "^7.1.6",
|
||||
|
||||
@@ -6,6 +6,5 @@
|
||||
"name": "<%= pluginName %>",
|
||||
"description": "<%= pluginDescription %>",
|
||||
"author": "<%= pluginAuthor %>",
|
||||
"homepage_url": "<%= pluginHomepageUrl %>",
|
||||
"repository_url": "<%= pluginRepositoryUrl %>"
|
||||
"homepage_url": "<%= pluginHomepageUrl %>"
|
||||
}
|
||||
@@ -1,61 +1,9 @@
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const WebpackOnBuildPlugin = require('on-build-webpack');
|
||||
const tar = require('tar');
|
||||
const glob = require('glob');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const publishDir = path.resolve(rootDir, 'publish');
|
||||
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const packageJsonPath = `${rootDir}/package.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const pluginArchiveFilePath = path.resolve(publishDir, `${manifest.id}.jpl`);
|
||||
const pluginInfoFilePath = path.resolve(publishDir, `${manifest.id}.json`);
|
||||
|
||||
fs.removeSync(distDir);
|
||||
fs.removeSync(publishDir);
|
||||
fs.mkdirpSync(publishDir);
|
||||
|
||||
function validatePackageJson() {
|
||||
const content = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
if (!content.name || content.name.indexOf('joplin-plugin-') !== 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package name should start with "joplin-plugin-" (found "${content.name}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (!content.keywords || content.keywords.indexOf('joplin-plugin') < 0) {
|
||||
console.warn(chalk.yellow(`WARNING: To publish the plugin, the package keywords should include "joplin-plugin" (found "${JSON.stringify(content.keywords)}") in ${packageJsonPath}`));
|
||||
}
|
||||
|
||||
if (content.scripts && content.scripts.postinstall) {
|
||||
console.warn(chalk.yellow(`WARNING: package.json contains a "postinstall" script. It is recommended to use a "prepare" script instead so that it is executed before publish. In ${packageJsonPath}`));
|
||||
}
|
||||
}
|
||||
|
||||
function fileSha256(filePath) {
|
||||
const content = fs.readFileSync(filePath);
|
||||
return crypto.createHash('sha256').update(content).digest('hex');
|
||||
}
|
||||
|
||||
function currentGitInfo() {
|
||||
try {
|
||||
let branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
const commit = execSync('git rev-parse HEAD', { stdio: 'pipe' }).toString().trim();
|
||||
if (branch === 'HEAD') branch = 'master';
|
||||
return `${branch}:${commit}`;
|
||||
} catch (error) {
|
||||
const messages = error.message ? error.message.split('\n') : [''];
|
||||
console.info(chalk.cyan('Could not get git commit (not a git repo?):', messages[0].trim()));
|
||||
console.info(chalk.cyan('Git information will not be stored in plugin info file'));
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestPath) {
|
||||
const content = fs.readFileSync(manifestPath, 'utf8');
|
||||
@@ -71,7 +19,7 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
if (!distFiles.length) {
|
||||
// Usually means there's an error, which is going to be printed by
|
||||
// webpack
|
||||
console.warn(chalk.yellow('Plugin archive was not created because the "dist" directory is empty'));
|
||||
console.info('Plugin archive was not created because the "dist" directory is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,27 +36,21 @@ function createPluginArchive(sourceDir, destPath) {
|
||||
distFiles
|
||||
);
|
||||
|
||||
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
|
||||
console.info(`Plugin archive has been created in ${destPath}`);
|
||||
}
|
||||
|
||||
function createPluginInfo(manifestPath, destPath, jplFilePath) {
|
||||
const contentText = fs.readFileSync(manifestPath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
content._publish_hash = `sha256:${fileSha256(jplFilePath)}`;
|
||||
content._publish_commit = currentGitInfo();
|
||||
fs.writeFileSync(destPath, JSON.stringify(content, null, '\t'), 'utf8');
|
||||
}
|
||||
const rootDir = path.resolve(__dirname);
|
||||
const distDir = path.resolve(rootDir, 'dist');
|
||||
const srcDir = path.resolve(rootDir, 'src');
|
||||
const manifestPath = `${srcDir}/manifest.json`;
|
||||
const manifest = readManifest(manifestPath);
|
||||
const archiveFilePath = path.resolve(__dirname, `${manifest.id}.jpl`);
|
||||
|
||||
function onBuildCompleted() {
|
||||
createPluginArchive(distDir, pluginArchiveFilePath);
|
||||
createPluginInfo(manifestPath, pluginInfoFilePath, pluginArchiveFilePath);
|
||||
validatePackageJson();
|
||||
}
|
||||
fs.removeSync(distDir);
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'production',
|
||||
target: 'node',
|
||||
stats: 'errors-only',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
@@ -151,7 +93,7 @@ const lastStepConfig = {
|
||||
|
||||
// Currently we don't support JS files for the main
|
||||
// plugin script. We support it for content scripts,
|
||||
// but they should be declared in manifest.json,
|
||||
// but theyr should be declared in manifest.json,
|
||||
// and then they are also compiled and copied to
|
||||
// /dist. So wse also don't need to copy JS files.
|
||||
'**/*.js',
|
||||
@@ -160,7 +102,9 @@ const lastStepConfig = {
|
||||
},
|
||||
],
|
||||
}),
|
||||
new WebpackOnBuildPlugin(onBuildCompleted),
|
||||
new WebpackOnBuildPlugin(function() {
|
||||
createPluginArchive(distDir, archiveFilePath);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user