Compare commits

..
Author SHA1 Message Date
Laurent Cozic e795ffe6de update 2026-11-11 23:59:39 +00:00
20 changed files with 68 additions and 86 deletions

No files matched your search

@@ -76,10 +76,3 @@ runs:
- uses: actions/setup-python@v6
with:
python-version: '3.14'
# Building the default plugins from source takes several minutes on Windows. Must be restored
# before "yarn install", which builds them.
- uses: actions/cache@v6
with:
path: packages/default-plugins/build-cache
key: default-plugins-${{ runner.os }}-${{ hashFiles('packages/default-plugins/pluginRepositories.json', 'packages/default-plugins/plugin-patches/**', 'packages/default-plugins/buildDefaultPlugins.ts') }}
+1
View File
@@ -66,6 +66,7 @@ docs/**/*.mustache
.yarn/*
!.yarn/patches
!.yarn/joplin-empty-package
!.yarn/joplin-missing-package
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
+5
View File
@@ -0,0 +1,5 @@
// Unlike joplin-empty-package, this throws so that optional dependency checks such as
// jsdom's `try { require('canvas') }` treat the package as not installed.
const error = new Error('Cannot find module (excluded via joplin-missing-package)');
error.code = 'MODULE_NOT_FOUND';
throw error;
+11
View File
@@ -0,0 +1,11 @@
{
"name": "@joplin/missing",
"version": "0.0.0",
"description": "A package that behaves as if it was not installed, used to exclude optional dependencies from build",
"private": true,
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/laurent22/joplin.git"
}
}
-2
View File
@@ -19,8 +19,6 @@ logFilters:
- code: YN0013
level: discard
nmHoistingLimits: workspaces
nodeLinker: node-modules
npmMinimalAgeGate: 1w
+1
View File
@@ -78,6 +78,7 @@ ENV PM2_HOME=/opt/pm2
USER $user
COPY --chown=$user:$user --from=builder /build/node_modules /home/$user/node_modules
COPY --chown=$user:$user --from=builder /build/packages /home/$user/packages
COPY --chown=$user:$user --from=builder /usr/bin/tini /usr/local/bin/tini
+1 -1
View File
@@ -126,7 +126,7 @@
"pdfjs-dist@2.16.105": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"pdfjs-dist@*": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"pdfjs-dist@3.11.174": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
"canvas@npm:^2.11.2": "link:./.yarn/joplin-empty-package/",
"canvas@npm:^2.11.2": "link:./.yarn/joplin-missing-package/",
"@huggingface/transformers/sharp": "link:./.yarn/joplin-empty-package/",
"node-gyp@npm:^9.0.0": "12.4.0",
"node-gyp@npm:11.2.0": "12.4.0",
+3
View File
@@ -1,6 +1,9 @@
{
"name": "@joplin/app-desktop",
"version": "3.7.22",
"installConfig": {
"hoistingLimits": "workspaces"
},
"description": "Joplin for Desktop",
"main": "main.bundle.js",
"private": true,
+2 -1
View File
@@ -51,7 +51,8 @@ const remappedPackages = {
: path.resolve(__dirname, 'config', 'config.default.js'),
};
const watchedFolders = [];
// Dependencies of the local packages are hoisted to the root node_modules
const watchedFolders = [path.resolve(__dirname, '../../node_modules')];
for (const [, v] of Object.entries(localPackages)) {
watchedFolders.push(v);
}
+3
View File
@@ -3,6 +3,9 @@
"description": "Joplin for Mobile",
"license": "AGPL-3.0-or-later",
"version": "3.7.0",
"installConfig": {
"hoistingLimits": "workspaces"
},
"private": true,
"scripts": {
"start": "BROWSERSLIST_IGNORE_OLD_DATA=true react-native start --reset-cache",
+1 -2
View File
@@ -1,3 +1,2 @@
built-plugins/
plugin-sources/*
build-cache/
plugin-sources/*
@@ -1,10 +1,9 @@
/* eslint-disable no-console */
import { copy, exists, remove, readdir, mkdtemp, readFile } from 'fs-extra';
import { join, resolve, basename } from 'path';
import { copy, exists, remove, readdir, mkdtemp } from 'fs-extra';
import { join, resolve, basename, dirname } from 'path';
import { tmpdir } from 'os';
import { createHash } from 'crypto';
import { chdir, cwd } from 'process';
import { execCommand } from '@joplin/utils';
import { glob } from 'glob';
@@ -17,22 +16,8 @@ interface Options {
outputParentDir: string|null;
beforeInstall: (buildDir: string, pluginName: string)=> Promise<void>;
beforePatch: ()=> Promise<void>;
useBuildCache: boolean;
}
// Increment to invalidate cached builds, for example after changing how plugins are built
const buildCacheVersion = 1;
const buildCacheDir = process.env.JOPLIN_DEFAULT_PLUGINS_CACHE_DIR || join(__dirname, 'build-cache');
const getBuildCachePath = async (pluginId: string, repositoryData: RepositoryData) => {
const patchFile = getPathToPatchFileFor(pluginId);
const patch = await exists(patchFile) ? await readFile(patchFile, 'utf8') : '';
const hash = createHash('sha256')
.update(JSON.stringify([buildCacheVersion, pluginId, repositoryData.cloneUrl, repositoryData.commit, patch]))
.digest('hex');
return join(buildCacheDir, `${pluginId}-${hash.substring(0, 16)}.jpl`);
};
const buildDefaultPlugins = async (options: Options) => {
const pluginRepositoryData = await readRepositoryJson(join(__dirname, 'pluginRepositories.json'));
@@ -41,23 +26,7 @@ const buildDefaultPlugins = async (options: Options) => {
const outputPath = options.outputParentDir && join(options.outputParentDir, `${pluginId}.jpl`);
if (repositoryData.type === BuiltInPluginType.Built) {
const cachePath = options.useBuildCache && outputPath ? await getBuildCachePath(pluginId, repositoryData) : null;
if (cachePath && await exists(cachePath)) {
logStatus('Using cached build of', pluginId, 'from', cachePath);
await copy(cachePath, outputPath);
continue;
}
const sourceHasLocalChanges = await buildPlugin(pluginId, repositoryData, outputPath, options);
if (cachePath) {
if (sourceHasLocalChanges) {
logStatus('Not caching build of', pluginId, ': its source checkout has local changes');
} else {
await copy(outputPath, cachePath);
logStatus('Saved build of', pluginId, 'to', cachePath);
}
}
await buildPlugin(pluginId, repositoryData, outputPath, options);
} else {
if (!outputPath) {
console.warn('Skipping NPM plugin,', pluginId, ': missing output path.');
@@ -65,7 +34,7 @@ const buildDefaultPlugins = async (options: Options) => {
}
logStatus('Copying plugin', pluginId, 'JPL file to', outputPath);
await copy(join(__dirname, 'node_modules', repositoryData.package, 'publish', `${pluginId}.jpl`), outputPath);
await copy(join(dirname(require.resolve(`${repositoryData.package}/package.json`)), 'publish', `${pluginId}.jpl`), outputPath);
logStatus('Copied.');
}
}
@@ -111,9 +80,6 @@ const buildPlugin = async (pluginId: string, repositoryData: RepositoryData, out
throw new Error(`Unable to checkout commit ${expectedCommitHash}`);
}
// Local changes are included in the build but not in the build cache key
const sourceHasLocalChanges = (await execCommand(['git', 'status', '--porcelain'], { showStdout: false })).trim() !== '';
logStatus('Copying repository files...');
await copy(pluginDir, buildDir, {
filter: fileName => {
@@ -156,8 +122,6 @@ const buildPlugin = async (pluginId: string, repositoryData: RepositoryData, out
} else {
console.warn('No output directory specified. Not copying built .jpl files.');
}
return sourceHasLocalChanges;
} catch (error) {
console.error(error);
console.log('Build directory', buildDir);
@@ -5,7 +5,6 @@ const buildAll = (outputDirectory: string) => {
outputParentDir: outputDirectory,
beforeInstall: async () => { },
beforePatch: async () => { },
useBuildCache: true,
});
};
@@ -10,7 +10,6 @@ const editPatch = async (targetPluginId: string, outputParentDir: string|null) =
await buildDefaultPlugins({
outputParentDir: outputParentDir,
useBuildCache: false,
beforePatch: async () => {
// To make updating just the patch possible, a commit is created just before applying
// the patch.
+3
View File
@@ -1,6 +1,9 @@
{
"name": "@joplin/doc-builder",
"version": "0.0.0",
"installConfig": {
"hoistingLimits": "workspaces"
},
"private": true,
"scripts": {
"docusaurus": "docusaurus",
+1 -3
View File
@@ -23,9 +23,7 @@
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"resolveJsonModule": true,
"typeRoots": [
"./node_modules/@types",
],
"types": ["node", "jest"],
},
"include": ["src"],
"exclude": [
+26 -25
View File
@@ -9,6 +9,7 @@ function dirname(path) {
const rootDir = dirname(__dirname);
const assetsDir = `${rootDir}/assets`;
const packageDir = name => dirname(require.resolve(`${name}/package.json`));
async function copyFile(source, dest) {
const fullDest = `${assetsDir}/${dest}`;
@@ -20,35 +21,35 @@ async function copyFile(source, dest) {
async function main() {
await fs.remove(assetsDir);
await copyFile(`${rootDir}/node_modules/katex/dist/katex.min.css`, 'katex/katex.css');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Main-Regular.woff2`, 'katex/fonts/KaTeX_Main-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Main-Bold.woff2`, 'katex/fonts/KaTeX_Main-Bold.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Main-BoldItalic.woff2`, 'katex/fonts/KaTeX_Main-BoldItalic.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Main-Italic.woff2`, 'katex/fonts/KaTeX_Main-Italic.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Math-Italic.woff2`, 'katex/fonts/KaTeX_Math-Italic.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Math-BoldItalic.woff2`, 'katex/fonts/KaTeX_Math-BoldItalic.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Size1-Regular.woff2`, 'katex/fonts/KaTeX_Size1-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Size2-Regular.woff2`, 'katex/fonts/KaTeX_Size2-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Size3-Regular.woff2`, 'katex/fonts/KaTeX_Size3-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Size4-Regular.woff2`, 'katex/fonts/KaTeX_Size4-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_AMS-Regular.woff2`, 'katex/fonts/KaTeX_AMS-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff2`, 'katex/fonts/KaTeX_Caligraphic-Bold.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff2`, 'katex/fonts/KaTeX_Caligraphic-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Fraktur-Bold.woff2`, 'katex/fonts/KaTeX_Fraktur-Bold.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Fraktur-Regular.woff2`, 'katex/fonts/KaTeX_Fraktur-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_SansSerif-Bold.woff2`, 'katex/fonts/KaTeX_SansSerif-Bold.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_SansSerif-Italic.woff2`, 'katex/fonts/KaTeX_SansSerif-Italic.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_SansSerif-Regular.woff2`, 'katex/fonts/KaTeX_SansSerif-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Script-Regular.woff2`, 'katex/fonts/KaTeX_Script-Regular.woff2');
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Typewriter-Regular.woff2`, 'katex/fonts/KaTeX_Typewriter-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/katex.min.css`, 'katex/katex.css');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Main-Regular.woff2`, 'katex/fonts/KaTeX_Main-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Main-Bold.woff2`, 'katex/fonts/KaTeX_Main-Bold.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Main-BoldItalic.woff2`, 'katex/fonts/KaTeX_Main-BoldItalic.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Main-Italic.woff2`, 'katex/fonts/KaTeX_Main-Italic.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Math-Italic.woff2`, 'katex/fonts/KaTeX_Math-Italic.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Math-BoldItalic.woff2`, 'katex/fonts/KaTeX_Math-BoldItalic.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Size1-Regular.woff2`, 'katex/fonts/KaTeX_Size1-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Size2-Regular.woff2`, 'katex/fonts/KaTeX_Size2-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Size3-Regular.woff2`, 'katex/fonts/KaTeX_Size3-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Size4-Regular.woff2`, 'katex/fonts/KaTeX_Size4-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_AMS-Regular.woff2`, 'katex/fonts/KaTeX_AMS-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Caligraphic-Bold.woff2`, 'katex/fonts/KaTeX_Caligraphic-Bold.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Caligraphic-Regular.woff2`, 'katex/fonts/KaTeX_Caligraphic-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Fraktur-Bold.woff2`, 'katex/fonts/KaTeX_Fraktur-Bold.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Fraktur-Regular.woff2`, 'katex/fonts/KaTeX_Fraktur-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_SansSerif-Bold.woff2`, 'katex/fonts/KaTeX_SansSerif-Bold.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_SansSerif-Italic.woff2`, 'katex/fonts/KaTeX_SansSerif-Italic.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_SansSerif-Regular.woff2`, 'katex/fonts/KaTeX_SansSerif-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Script-Regular.woff2`, 'katex/fonts/KaTeX_Script-Regular.woff2');
await copyFile(`${packageDir('katex')}/dist/fonts/KaTeX_Typewriter-Regular.woff2`, 'katex/fonts/KaTeX_Typewriter-Regular.woff2');
await copyFile(`${rootDir}/node_modules/highlight.js/styles/atom-one-light.css`, 'highlight.js/atom-one-light.css');
await copyFile(`${rootDir}/node_modules/highlight.js/styles/atom-one-dark-reasonable.css`, 'highlight.js/atom-one-dark-reasonable.css');
await copyFile(`${packageDir('highlight.js')}/styles/atom-one-light.css`, 'highlight.js/atom-one-light.css');
await copyFile(`${packageDir('highlight.js')}/styles/atom-one-dark-reasonable.css`, 'highlight.js/atom-one-dark-reasonable.css');
await copyFile(`${rootDir}/node_modules/mermaid/dist/mermaid.min.js`, 'mermaid/mermaid.min.js');
await copyFile(`${packageDir('mermaid')}/dist/mermaid.min.js`, 'mermaid/mermaid.min.js');
await copyFile(`${rootDir}/MdToHtml/rules/mermaid_render.js`, 'mermaid/mermaid_render.js');
await copyFile(`${rootDir}/node_modules/abcjs/dist/abcjs-basic-min.js`, 'abc/abcjs-basic-min.js');
await copyFile(`${packageDir('abcjs')}/dist/abcjs-basic-min.js`, 'abc/abcjs-basic-min.js');
await copyFile(`${rootDir}/MdToHtml/rules/abc_render.js`, 'abc/abc_render.js');
}
+3
View File
@@ -1,6 +1,9 @@
{
"name": "@joplin/server",
"version": "3.7.5",
"installConfig": {
"hoistingLimits": "workspaces"
},
"private": true,
"scripts": {
"start-dev": "yarn build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/index.js --env dev",
@@ -11,7 +11,7 @@ export default class SqliteQueue implements BaseQueue {
private sqlite: Knex<Knex.Table>;
private name: string;
private maintenanceIntervalRef: NodeJS.Timer | undefined;
private maintenanceIntervalRef: ReturnType<typeof setInterval> | undefined;
private isMaintenanceRunning = false;
private options: QueueConfiguration;
+2 -2
View File
@@ -23707,9 +23707,9 @@ __metadata:
languageName: node
linkType: hard
"canvas@link:./.yarn/joplin-empty-package/::locator=root%40workspace%3A.":
"canvas@link:./.yarn/joplin-missing-package/::locator=root%40workspace%3A.":
version: 0.0.0-use.local
resolution: "canvas@link:./.yarn/joplin-empty-package/::locator=root%40workspace%3A."
resolution: "canvas@link:./.yarn/joplin-missing-package/::locator=root%40workspace%3A."
languageName: node
linkType: soft