use trilium version number in asset paths to avoid caching issues WIP

pull/255/head
zadam 2022-10-26 23:50:54 +07:00
parent 441a59305b
commit b499640db8
28 changed files with 124 additions and 83 deletions

@ -2,7 +2,7 @@ image:
file: .gitpod.dockerfile
tasks:
- before: nvm install 16.15.0 && nvm use 16.15.0
- before: nvm install 16.18.0 && nvm use 16.18.0
init: npm install
command: npm run start-server

@ -1,5 +1,5 @@
# !!! Don't try to build this Dockerfile directly, run it through bin/build-docker.sh script !!!
FROM node:16.15.0-alpine
FROM node:16.18.0-alpine
# Create app directory
WORKDIR /usr/src/app

@ -1,7 +1,7 @@
#!/usr/bin/env bash
PKG_DIR=dist/trilium-linux-x64-server
NODE_VERSION=16.15.0
NODE_VERSION=16.18.0
if [ "$1" != "DONTCOPY" ]
then

@ -5,7 +5,7 @@ if [[ $# -eq 0 ]] ; then
exit 1
fi
n exec 16.15.0 npm run webpack
n exec 16.18.0 npm run webpack
DIR=$1
@ -30,7 +30,7 @@ cp -r electron.js $DIR/
cp webpack-* $DIR/
# run in subshell (so we return to original dir)
(cd $DIR && n exec 16.15.0 npm install --only=prod)
(cd $DIR && n exec 16.18.0 npm install --only=prod)
# cleanup of useless files in dependencies
rm -r $DIR/node_modules/image-q/demo

@ -6,7 +6,7 @@ It is meant as a last resort solution when the standard mean to access your data
## Installation
This tool requires node.js, testing has been done on 16.15.0, but it will probably work on other versions as well.
This tool requires node.js, testing has been done on 16.18.0, but it will probably work on other versions as well.
```
npm install

4
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "trilium",
"version": "0.56.0-beta",
"version": "0.56.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "trilium",
"version": "0.56.0-beta",
"version": "0.56.1",
"hasInstallScript": true,
"license": "AGPL-3.0-only",
"dependencies": {

@ -4,7 +4,7 @@ const Branch = require('../../src/becca/entities/branch');
const SearchContext = require('../../src/services/search/search_context');
const dateUtils = require('../../src/services/date_utils');
const becca = require('../../src/becca/becca');
const {NoteBuilder, findNoteByTitle, note} = require('./note_cache_mocking');
const {NoteBuilder, findNoteByTitle, note} = require('./becca_mocking.js');
describe("Search", () => {
let rootNote;

@ -1,4 +1,4 @@
const {note} = require('./note_cache_mocking');
const {note} = require('./becca_mocking.js');
const ValueExtractor = require('../../src/services/search/value_extractor');
const becca = require('../../src/becca/becca');
const SearchContext = require("../../src/services/search/search_context");

@ -10,6 +10,7 @@ const FileStore = require('session-file-store')(session);
const sessionSecret = require('./services/session_secret');
const dataDir = require('./services/data_dir');
const utils = require('./services/utils');
const assetPath = require('./services/asset_path');
require('./services/handlers');
require('./becca/becca_loader');
@ -34,14 +35,19 @@ app.use(express.json({limit: '500mb'}));
app.use(express.raw({limit: '500mb'}));
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/libraries', express.static(path.join(__dirname, '..', 'libraries')));
app.use(express.static(path.join(__dirname, 'public/root')));
app.use(`/${assetPath}/app`, express.static(path.join(__dirname, 'public/app')));
app.use(`/${assetPath}/app-dist`, express.static(path.join(__dirname, 'public/app-dist')));
app.use(`/${assetPath}/fonts`, express.static(path.join(__dirname, 'public/fonts')));
app.use(`/${assetPath}/stylesheets`, express.static(path.join(__dirname, 'public/stylesheets')));
app.use(`/${assetPath}/libraries`, express.static(path.join(__dirname, '..', 'libraries')));
// excalidraw-view mode in shared notes
app.use('/node_modules/react/umd/react.production.min.js', express.static(path.join(__dirname, '..', 'node_modules/react/umd/react.production.min.js')));
app.use('/node_modules/react-dom/umd/react-dom.production.min.js', express.static(path.join(__dirname, '..', 'node_modules/react-dom/umd/react-dom.production.min.js')));
app.use(`/${assetPath}/node_modules/react/umd/react.production.min.js`, express.static(path.join(__dirname, '..', 'node_modules/react/umd/react.production.min.js')));
app.use(`/${assetPath}/node_modules/react-dom/umd/react-dom.production.min.js`, express.static(path.join(__dirname, '..', 'node_modules/react-dom/umd/react-dom.production.min.js')));
// expose whole dist folder since complete assets are needed in edit and share
app.use('/node_modules/@excalidraw/excalidraw/dist/', express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
app.use('/images', express.static(path.join(__dirname, '..', 'images')));
app.use(`/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
app.use(`/${assetPath}/node_modules/@excalidraw/excalidraw/dist/`, express.static(path.join(__dirname, '..', 'node_modules/@excalidraw/excalidraw/dist/')));
app.use(`/${assetPath}/images`, express.static(path.join(__dirname, '..', 'images')));
const sessionParser = session({
secret: sessionSecret,
resave: false, // true forces the session to be saved back to the session store, even if the session was never modified during the request.

@ -64,7 +64,7 @@ function setupGlobs() {
};
for (const appCssNoteId of glob.appCssNoteIds || []) {
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`);
libraryLoader.requireCss(`api/notes/download/${appCssNoteId}`, false);
}
utils.initHelpButtons($(window));

@ -86,6 +86,8 @@ async function requireLibrary(library) {
const loadedScriptPromises = {};
async function requireScript(url) {
url = window.glob.assetPath + "/" + url;
if (!loadedScriptPromises[url]) {
loadedScriptPromises[url] = $.ajax({
url: url,
@ -97,12 +99,16 @@ async function requireScript(url) {
await loadedScriptPromises[url];
}
async function requireCss(url) {
async function requireCss(url, prependAssetPath = true) {
const cssLinks = Array
.from(document.querySelectorAll('link'))
.map(el => el.href);
if (!cssLinks.some(l => l.endsWith(url))) {
if (prependAssetPath) {
url = window.glob.assetPath + "/" + url;
}
$('head').append($('<link rel="stylesheet" type="text/css" />').attr('href', url));
}
}

@ -16,7 +16,7 @@ const TPL = `
}
.global-menu-button {
background-image: url("images/icon-black.png");
background-image: url("${window.glob.assetPath}/images/icon-black.png");
background-repeat: no-repeat;
background-position: 50% 45%;
width: 100%;
@ -26,7 +26,7 @@ const TPL = `
}
.global-menu-button:hover {
background-image: url("images/icon-color.png");
background-image: url("${window.glob.assetPath}/images/icon-color.png");
}
.global-menu-button-update-available {

@ -237,15 +237,17 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
$promotedAttributes = (await attributeRenderer.renderNormalAttributes(this.note)).$renderedAttributes;
}
const {assetPath} = window.glob;
this.$widget.find('.note-detail-printable:visible').printThis({
header: $("<div>")
.append($("<h2>").text(this.note.title))
.append($promotedAttributes)
.prop('outerHTML'),
footer: `
<script src="libraries/katex/katex.min.js"></script>
<script src="libraries/katex/mhchem.min.js"></script>
<script src="libraries/katex/auto-render.min.js"></script>
<script src="${assetPath}/libraries/katex/katex.min.js"></script>
<script src="${assetPath}/libraries/katex/mhchem.min.js"></script>
<script src="${assetPath}/libraries/katex/auto-render.min.js"></script>
<script>
document.body.className += ' ck-content printed-content';
@ -254,13 +256,13 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
`,
importCSS: false,
loadCSS: [
"libraries/codemirror/codemirror.css",
"libraries/ckeditor/ckeditor-content.css",
"libraries/bootstrap/css/bootstrap.min.css",
"libraries/katex/katex.min.css",
"stylesheets/print.css",
"stylesheets/relation_map.css",
"stylesheets/ckeditor-theme.css"
assetPath + "/libraries/codemirror/codemirror.css",
assetPath + "/libraries/ckeditor/ckeditor-content.css",
assetPath + "/libraries/bootstrap/css/bootstrap.min.css",
assetPath + "/libraries/katex/katex.min.css",
assetPath + "/stylesheets/print.css",
assetPath + "/stylesheets/relation_map.css",
assetPath + "/stylesheets/ckeditor-theme.css"
],
debug: true
});

@ -9,6 +9,7 @@ const env = require('../services/env');
const utils = require('../services/utils');
const protectedSessionService = require("../services/protected_session");
const packageJson = require('../../package.json');
const assetPath = require("../services/asset_path");
function index(req, res) {
const options = optionService.getOptionsMap();
@ -36,7 +37,8 @@ function index(req, res) {
extraHoistedNoteId: req.query.extraHoistedNoteId,
isProtectedSessionAvailable: protectedSessionService.isProtectedSessionAvailable(),
maxContentWidth: parseInt(options.maxContentWidth),
triliumVersion: packageJson.version
triliumVersion: packageJson.version,
assetPath: assetPath
});
}
@ -46,7 +48,7 @@ function getThemeCssUrl(theme) {
}
if (theme === 'dark') {
return `stylesheets/theme-dark.css`;
return `${assetPath}/stylesheets/theme-dark.css`;
}
else {
const themeNote = attributeService.getNoteWithLabel('appTheme', theme);

@ -5,13 +5,20 @@ const optionService = require('../services/options');
const myScryptService = require('../services/my_scrypt');
const log = require('../services/log');
const passwordService = require("../services/password");
const assetPath = require("../services/asset_path");
function loginPage(req, res) {
res.render('login', { failedAuth: false });
res.render('login', {
failedAuth: false,
assetPath: assetPath
});
}
function setPasswordPage(req, res) {
res.render('set_password', { error: false });
res.render('set_password', {
error: false,
assetPath: assetPath
});
}
function setPassword(req, res) {
@ -32,7 +39,10 @@ function setPassword(req, res) {
}
if (error) {
res.render('set_password', { error });
res.render('set_password', {
error,
assetPath: assetPath
});
return;
}
@ -62,7 +72,10 @@ function login(req, res) {
// note that logged IP address is usually meaningless since the traffic should come from a reverse proxy
log.info(`WARNING: Wrong password from ${req.ip}, rejecting.`);
res.render('login', {'failedAuth': true});
res.render('login', {
failedAuth: true,
assetPath: assetPath
});
}
}

@ -3,6 +3,7 @@
const sqlInit = require('../services/sql_init');
const setupService = require('../services/setup');
const utils = require('../services/utils');
const assetPath = require("../services/asset_path");
function setupPage(req, res) {
if (sqlInit.isDbInitialized()) {
@ -28,7 +29,8 @@ function setupPage(req, res) {
}
res.render('setup', {
syncInProgress: syncInProgress
syncInProgress: syncInProgress,
assetPath: assetPath
});
}

@ -0,0 +1,3 @@
const packageJson = require('../../package.json');
module.exports = "assets/v" + packageJson.version;

@ -6,6 +6,7 @@ const shaca = require("./shaca/shaca");
const shacaLoader = require("./shaca/shaca_loader");
const shareRoot = require("./share_root");
const contentRenderer = require("./content_renderer");
const assetPath = require("../services/asset_path");
function getSharedSubTreeRoot(note) {
if (note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) {
@ -103,7 +104,8 @@ function register(router) {
header,
content,
isEmpty,
subRoot
subRoot,
assetPath
});
}

@ -34,7 +34,8 @@
isMainWindow: <%= isMainWindow %>,
extraHoistedNoteId: '<%= extraHoistedNoteId %>',
isProtectedSessionAvailable: <%= isProtectedSessionAvailable %>,
triliumVersion: "<%= triliumVersion %>"
triliumVersion: "<%= triliumVersion %>",
assetPath: "<%= assetPath %>"
};
</script>
@ -47,40 +48,40 @@
<!-- Required for correct loading of scripts in Electron -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="libraries/jquery.min.js"></script>
<script src="<%= assetPath %>/libraries/jquery.min.js"></script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="<%= assetPath %>/libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Include Fancytree library and skip -->
<link href="stylesheets/tree.css" rel="stylesheet">
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<link href="<%= assetPath %>/stylesheets/tree.css" rel="stylesheet">
<script src="<%= assetPath %>/libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<script src="libraries/jquery.hotkeys.js"></script>
<script src="<%= assetPath %>/libraries/jquery.hotkeys.js"></script>
<script src="libraries/autocomplete.jquery.min.js"></script>
<script src="<%= assetPath %>/libraries/autocomplete.jquery.min.js"></script>
<script src="libraries/dayjs.min.js"></script>
<script src="<%= assetPath %>/libraries/dayjs.min.js"></script>
<script src="libraries/split.min.js"></script>
<script src="<%= assetPath %>/libraries/split.min.js"></script>
<link href="stylesheets/ckeditor-theme.css" rel="stylesheet">
<link href="<%= assetPath %>/stylesheets/ckeditor-theme.css" rel="stylesheet">
<link href="api/fonts" rel="stylesheet">
<link href="stylesheets/theme-light.css" rel="stylesheet">
<link href="<%= assetPath %>/stylesheets/theme-light.css" rel="stylesheet">
<% if (themeCssUrl) { %>
<link href="<%= themeCssUrl %>" rel="stylesheet">
<% } %>
<link href="stylesheets/style.css" rel="stylesheet">
<link href="<%= assetPath %>/stylesheets/style.css" rel="stylesheet">
<script>
$("body").show();
</script>
<script src="app/desktop.js" crossorigin type="module"></script>
<script src="<%= assetPath %>/app/desktop.js" crossorigin type="module"></script>
<link rel="stylesheet" type="text/css" href="libraries/boxicons/css/boxicons.min.css">
<link rel="stylesheet" type="text/css" href="<%= assetPath %>/libraries/boxicons/css/boxicons.min.css">
</body>
</html>

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Login</title>
<link rel="apple-touch-icon" sizes="180x180" href="images/app-icons/ios/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="180x180" href="<%= assetPath %>/images/app-icons/ios/apple-touch-icon.png">
<link rel="shortcut icon" href="favicon.ico">
</head>
<body>
@ -68,6 +68,6 @@
}
</script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
</body>
</html>

@ -115,31 +115,32 @@
csrfToken: '<%= csrfToken %>',
isDev: <%= isDev %>,
appCssNoteIds: <%- JSON.stringify(appCssNoteIds) %>,
isProtectedSessionAvailable: <%= isProtectedSessionAvailable %>
isProtectedSessionAvailable: <%= isProtectedSessionAvailable %>,
assetPath: "<%= assetPath %>"
};
</script>
<script src="libraries/jquery.min.js"></script>
<script src="<%= assetPath %>/libraries/jquery.min.js"></script>
<script src="libraries/dayjs.min.js"></script>
<script src="<%= assetPath %>/libraries/dayjs.min.js"></script>
<link href="stylesheets/tree.css" rel="stylesheet">
<script src="libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<link href="<%= assetPath %>/stylesheets/tree.css" rel="stylesheet">
<script src="<%= assetPath %>/libraries/fancytree/jquery.fancytree-all-deps.min.js"></script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="<%= assetPath %>/libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="app/mobile.js" crossorigin type="module"></script>
<script src="<%= assetPath %>/app/mobile.js" crossorigin type="module"></script>
<link href="api/fonts" rel="stylesheet">
<link href="stylesheets/ckeditor-theme.css" rel="stylesheet">
<link href="stylesheets/theme-light.css" rel="stylesheet">
<link href="<%= assetPath %>/stylesheets/ckeditor-theme.css" rel="stylesheet">
<link href="<%= assetPath %>/stylesheets/theme-light.css" rel="stylesheet">
<% if (themeCssUrl) { %>
<link href="<%= themeCssUrl %>" rel="stylesheet">
<% } %>
<link href="stylesheets/style.css" rel="stylesheet">
<link href="<%= assetPath %>/stylesheets/style.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="libraries/boxicons/css/boxicons.min.css">
<link rel="stylesheet" type="text/css" href="<%= assetPath %>/libraries/boxicons/css/boxicons.min.css">
</body>
</html>

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Login</title>
<link rel="apple-touch-icon" sizes="180x180" href="images/app-icons/ios/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="180x180" href="<%= assetPath %>/images/app-icons/ios/apple-touch-icon.png">
<link rel="shortcut icon" href="favicon.ico">
</head>
<body>
@ -46,6 +46,6 @@
if (typeof module === 'object') {window.module = module; module = undefined;}
</script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
</body>
</html>

@ -153,15 +153,15 @@
<!-- Required for correct loading of scripts in Electron -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="libraries/jquery.min.js"></script>
<script src="libraries/jquery.hotkeys.js"></script>
<script src="<%= assetPath %>/libraries/jquery.min.js"></script>
<script src="<%= assetPath %>/libraries/jquery.hotkeys.js"></script>
<link href="libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<link href="<%= assetPath %>/libraries/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="<%= assetPath %>/libraries/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="libraries/knockout.min.js"></script>
<script src="<%= assetPath %>/libraries/knockout.min.js"></script>
<script src="app/setup.js" crossorigin type="module"></script>
<link href="stylesheets/theme-light.css" rel="stylesheet">
<script src="<%= assetPath %>/app/setup.js" crossorigin type="module"></script>
<link href="<%= assetPath %>/stylesheets/theme-light.css" rel="stylesheet">
</body>
</html>

@ -12,13 +12,13 @@
<% } else { %>
<link rel="shortcut icon" href="../favicon.ico">
<% } %>
<script src="../app/share.js"></script>
<script src="../<%= assetPath %>/app/share.js"></script>
<% if (!note.hasLabel("shareOmitDefaultCss")) { %>
<link href="../libraries/normalize.min.css" rel="stylesheet">
<link href="../stylesheets/share.css" rel="stylesheet">
<link href="../<%= assetPath %>/libraries/normalize.min.css" rel="stylesheet">
<link href="../<%= assetPath %>/stylesheets/share.css" rel="stylesheet">
<% } %>
<% if (note.type === 'text' || note.type === 'book') { %>
<link href="../libraries/ckeditor/ckeditor-content.css" rel="stylesheet">
<link href="../<%= assetPath %>/libraries/ckeditor/ckeditor-content.css" rel="stylesheet">
<% } %>
<% for (const cssRelation of note.getRelations("shareCss")) { %>
<link href="api/notes/<%= cssRelation.value %>/download" rel="stylesheet">

@ -1,4 +1,5 @@
const path = require('path');
const assetPath = require('./src/services/asset_path');
module.exports = {
mode: 'production',
@ -6,7 +7,7 @@ module.exports = {
mobile: './src/public/app/desktop.js',
},
output: {
publicPath: 'app-dist/',
publicPath: `/${assetPath}/app-dist/`,
path: path.resolve(__dirname, 'src/public/app-dist'),
filename: 'desktop.js'
},

@ -1,4 +1,5 @@
const path = require('path');
const assetPath = require('./src/services/asset_path');
module.exports = {
mode: 'production',
@ -6,7 +7,7 @@ module.exports = {
mobile: './src/public/app/mobile.js',
},
output: {
publicPath: 'app-dist/',
publicPath: `/${assetPath}/app-dist/`,
path: path.resolve(__dirname, 'src/public/app-dist'),
filename: 'mobile.js'
},

@ -1,4 +1,5 @@
const path = require('path');
const assetPath = require('./src/services/asset_path');
module.exports = {
mode: 'production',
@ -6,7 +7,7 @@ module.exports = {
mobile: './src/public/app/setup.js',
},
output: {
publicPath: 'app-dist/',
publicPath: `/${assetPath}/app-dist/`,
path: path.resolve(__dirname, 'src/public/app-dist'),
filename: 'setup.js'
},