mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 04:51:31 +08:00 
			
		
		
		
	Merge branch 'feature/typescript_backend' into feature/typescript_backend_2
This commit is contained in:
		
						commit
						db2b33704f
					
				| @ -1,7 +0,0 @@ | |||||||
| node_modules |  | ||||||
| dist |  | ||||||
| bin |  | ||||||
| docs |  | ||||||
| libraries |  | ||||||
| coverage |  | ||||||
| play |  | ||||||
							
								
								
									
										212
									
								
								.eslintrc.js
									
									
									
									
									
								
							
							
						
						
									
										212
									
								
								.eslintrc.js
									
									
									
									
									
								
							| @ -1,212 +0,0 @@ | |||||||
| module.exports = { |  | ||||||
|     env: { |  | ||||||
|         browser: true, |  | ||||||
|         commonjs: true, |  | ||||||
|         es2021: true, |  | ||||||
|         node: true, |  | ||||||
|     }, |  | ||||||
|     // plugins: ['prettier'], // to be activated
 |  | ||||||
|     extends: ['eslint:recommended', 'airbnb-base', 'plugin:jsonc/recommended-with-jsonc', 'prettier'], |  | ||||||
|     overrides: [ |  | ||||||
|         { |  | ||||||
|             files: ['*.json', '*.json5', '*.jsonc'], |  | ||||||
|             parser: 'jsonc-eslint-parser', |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             files: ['package.json'], |  | ||||||
|             parser: 'jsonc-eslint-parser', |  | ||||||
|             rules: { |  | ||||||
|                 'jsonc/sort-keys': [ |  | ||||||
|                     'off', |  | ||||||
|                     { |  | ||||||
|                         pathPattern: '^$', |  | ||||||
|                         order: [ |  | ||||||
|                             'name', |  | ||||||
|                             'version', |  | ||||||
|                             'private', |  | ||||||
|                             'packageManager', |  | ||||||
|                             'description', |  | ||||||
|                             'type', |  | ||||||
|                             'keywords', |  | ||||||
|                             'homepage', |  | ||||||
|                             'bugs', |  | ||||||
|                             'license', |  | ||||||
|                             'author', |  | ||||||
|                             'contributors', |  | ||||||
|                             'funding', |  | ||||||
|                             'files', |  | ||||||
|                             'main', |  | ||||||
|                             'module', |  | ||||||
|                             'exports', |  | ||||||
|                             'unpkg', |  | ||||||
|                             'jsdelivr', |  | ||||||
|                             'browser', |  | ||||||
|                             'bin', |  | ||||||
|                             'man', |  | ||||||
|                             'directories', |  | ||||||
|                             'repository', |  | ||||||
|                             'publishConfig', |  | ||||||
|                             'scripts', |  | ||||||
|                             'peerDependencies', |  | ||||||
|                             'peerDependenciesMeta', |  | ||||||
|                             'optionalDependencies', |  | ||||||
|                             'dependencies', |  | ||||||
|                             'devDependencies', |  | ||||||
|                             'engines', |  | ||||||
|                             'config', |  | ||||||
|                             'overrides', |  | ||||||
|                             'pnpm', |  | ||||||
|                             'husky', |  | ||||||
|                             'lint-staged', |  | ||||||
|                             'eslintConfig', |  | ||||||
|                         ], |  | ||||||
|                     }, |  | ||||||
|                     { |  | ||||||
|                         pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies$', |  | ||||||
|                         order: { type: 'asc' }, |  | ||||||
|                     }, |  | ||||||
|                 ], |  | ||||||
|             }, |  | ||||||
|         }, |  | ||||||
|     ], |  | ||||||
|     globals: { |  | ||||||
|         $: true, |  | ||||||
|         jQuery: true, |  | ||||||
|         glob: true, |  | ||||||
|         log: true, |  | ||||||
|         EditorWatchdog: true, |  | ||||||
|         React: true, |  | ||||||
|         appState: true, |  | ||||||
|         ExcalidrawLib: true, |  | ||||||
|         elements: true, |  | ||||||
|         files: true, |  | ||||||
|         ReactDOM: true, |  | ||||||
|         // src\public\app\widgets\type_widgets\relation_map.js
 |  | ||||||
|         jsPlumb: true, |  | ||||||
|         panzoom: true, |  | ||||||
|         logError: true, |  | ||||||
|         // src\public\app\widgets\type_widgets\image.js
 |  | ||||||
|         WZoom: true, |  | ||||||
|         // \src\public\app\widgets\type_widgets\read_only_text.js
 |  | ||||||
|         renderMathInElement: true, |  | ||||||
|         // \src\public\app\widgets\type_widgets\editable_text.js
 |  | ||||||
|         BalloonEditor: true, |  | ||||||
|         FancytreeNode: true, |  | ||||||
|         CKEditorInspector: true, |  | ||||||
|         // \src\public\app\widgets\type_widgets\editable_code.js
 |  | ||||||
|         CodeMirror: true, |  | ||||||
|         // \src\public\app\services\resizer.js
 |  | ||||||
|         Split: true, |  | ||||||
|         // \src\public\app\services\content_renderer.js
 |  | ||||||
|         mermaid: true, |  | ||||||
|         // src\public\app\services\frontend_script_api.js
 |  | ||||||
|         dayjs: true, |  | ||||||
|         // \src\public\app\widgets\note_map.js
 |  | ||||||
|         ForceGraph: true, |  | ||||||
|         // \src\public\app\setup.js
 |  | ||||||
|         ko: true, |  | ||||||
|         syncInProgress: true, |  | ||||||
|         // src\public\app\services\utils.js
 |  | ||||||
|         logInfo: true, |  | ||||||
|         __non_webpack_require__: true, |  | ||||||
|         describe: true, |  | ||||||
|         it: true, |  | ||||||
|         expect: true |  | ||||||
|     }, |  | ||||||
|     parserOptions: { |  | ||||||
|         ecmaVersion: 'latest', |  | ||||||
|         sourceType: 'module', |  | ||||||
|     }, |  | ||||||
|     rules: { |  | ||||||
|         // eslint:recommended
 |  | ||||||
|         'no-unused-vars': 'off', |  | ||||||
|         'linebreak-style': 'off', |  | ||||||
|         'no-useless-escape': 'off', |  | ||||||
|         'no-empty': 'off', |  | ||||||
|         'no-constant-condition': 'off', |  | ||||||
|         'getter-return': 'off', |  | ||||||
|         'no-cond-assign': 'off', |  | ||||||
|         'no-async-promise-executor': 'off', |  | ||||||
|         'no-extra-semi': 'off', |  | ||||||
|         'no-inner-declarations': 'off', |  | ||||||
| 
 |  | ||||||
|         // prettier
 |  | ||||||
|         'prettier/prettier': ['off', { endOfLine: 'auto' }], |  | ||||||
| 
 |  | ||||||
|         // airbnb-base
 |  | ||||||
|         'no-console': 'off', |  | ||||||
|         'no-plusplus': 'off', |  | ||||||
|         'no-param-reassign': 'off', |  | ||||||
|         'global-require': 'off', |  | ||||||
|         'no-use-before-define': 'off', |  | ||||||
|         'no-await-in-loop': 'off', |  | ||||||
|         radix: 'off', |  | ||||||
|         'import/order': 'off', |  | ||||||
|         'import/no-extraneous-dependencies': 'off', |  | ||||||
|         'prefer-destructuring': 'off', |  | ||||||
|         'no-shadow': 'off', |  | ||||||
|         'no-new': 'off', |  | ||||||
|         'no-restricted-syntax': 'off', |  | ||||||
|         strict: 'off', |  | ||||||
|         'class-methods-use-this': 'off', |  | ||||||
|         'no-else-return': 'off', |  | ||||||
|         'import/no-dynamic-require': 'off', |  | ||||||
|         'no-underscore-dangle': 'off', |  | ||||||
|         'prefer-template': 'off', |  | ||||||
|         'consistent-return': 'off', |  | ||||||
|         'no-continue': 'off', |  | ||||||
|         'object-shorthand': 'off', |  | ||||||
|         'one-var': 'off', |  | ||||||
|         'prefer-const': 'off', |  | ||||||
|         'spaced-comment': 'off', |  | ||||||
|         'no-loop-func': 'off', |  | ||||||
|         'arrow-body-style': 'off', |  | ||||||
| 
 |  | ||||||
|         'guard-for-in': 'off', |  | ||||||
|         'no-return-assign': 'off', |  | ||||||
|         'dot-notation': 'off', |  | ||||||
| 
 |  | ||||||
|         'func-names': 'off', |  | ||||||
|         'import/no-useless-path-segments': 'off', |  | ||||||
|         'default-param-last': 'off', |  | ||||||
|         'prefer-arrow-callback': 'off', |  | ||||||
|         'no-unneeded-ternary': 'off', |  | ||||||
|         'no-return-await': 'off', |  | ||||||
|         'import/extensions': 'off', |  | ||||||
| 
 |  | ||||||
|         'no-var': 'off', |  | ||||||
|         'import/newline-after-import': 'off', |  | ||||||
|         'no-restricted-globals': 'off', |  | ||||||
|         'operator-assignment': 'off', |  | ||||||
|         'no-eval': 'off', |  | ||||||
|         'max-classes-per-file': 'off', |  | ||||||
|         'vars-on-top': 'off', |  | ||||||
|         'no-bitwise': 'off', |  | ||||||
|         'no-lonely-if': 'off', |  | ||||||
|         'no-multi-assign': 'off', |  | ||||||
|         'no-promise-executor-return': 'off', |  | ||||||
|         'no-empty-function': 'off', |  | ||||||
|         'import/no-unresolved': 'off', |  | ||||||
|         camelcase: 'off', |  | ||||||
|         eqeqeq: 'off', |  | ||||||
|         'lines-between-class-members': 'off', |  | ||||||
|         'import/no-cycle': 'off', |  | ||||||
|         'new-cap': 'off', |  | ||||||
|         'prefer-object-spread': 'off', |  | ||||||
|         'no-new-func': 'off', |  | ||||||
|         'no-unused-expressions': 'off', |  | ||||||
|         'lines-around-directive': 'off', |  | ||||||
|         'prefer-exponentiation-operator': 'off', |  | ||||||
|         'no-restricted-properties': 'off', |  | ||||||
|         'prefer-rest-params': 'off', |  | ||||||
|         'no-unreachable-loop': 'off', |  | ||||||
|         'no-alert': 'off', |  | ||||||
|         'no-useless-return': 'off', |  | ||||||
|         'no-nested-ternary': 'off', |  | ||||||
|         'prefer-regex-literals': 'off', |  | ||||||
|         'import/no-named-as-default-member': 'off', |  | ||||||
|         yoda: 'off', |  | ||||||
|         'no-script-url': 'off', |  | ||||||
|         'no-prototype-builtins':'off' |  | ||||||
|     }, |  | ||||||
| }; |  | ||||||
							
								
								
									
										1
									
								
								.husky/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.husky/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +0,0 @@ | |||||||
| _ |  | ||||||
| @ -1,4 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
| . "$(dirname "$0")/_/husky.sh" |  | ||||||
| 
 |  | ||||||
| #npx lint-staged |  | ||||||
							
								
								
									
										6
									
								
								.idea/jsLinters/eslint.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/jsLinters/eslint.xml
									
									
									
										generated
									
									
									
								
							| @ -1,6 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project version="4"> |  | ||||||
|   <component name="EslintConfiguration"> |  | ||||||
|     <option name="fix-on-save" value="true" /> |  | ||||||
|   </component> |  | ||||||
| </project> |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| //https://prettier.io/docs/en/options.html
 |  | ||||||
| module.exports = { |  | ||||||
| 	semi: true, |  | ||||||
| 	trailingComma: 'none', |  | ||||||
| 	singleQuote: true, |  | ||||||
| 	printWidth: 100, |  | ||||||
| 	tabWidth: 4, |  | ||||||
| 	useTabs: false, |  | ||||||
| 	quoteProps: "as-needed", |  | ||||||
| 	bracketSpacing: true, |  | ||||||
| 	arrowParens: "avoid" |  | ||||||
| 	// htmlWhitespaceSensitivity: 'ignore',
 |  | ||||||
| }; |  | ||||||
							
								
								
									
										6
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							| @ -1,6 +0,0 @@ | |||||||
| { |  | ||||||
|   "recommendations": [ |  | ||||||
|     "dbaeumer.vscode-eslint", |  | ||||||
|     "esbenp.prettier-vscode", |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
							
								
								
									
										31
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -1,34 +1,5 @@ | |||||||
| { | { | ||||||
|   "[javascript]": { |  | ||||||
|     "editor.defaultFormatter": "dbaeumer.vscode-eslint" |  | ||||||
|   }, |  | ||||||
|   "[json]": { |  | ||||||
|     "editor.defaultFormatter": "dbaeumer.vscode-eslint" |  | ||||||
|   }, |  | ||||||
|   "editor.formatOnSave": true, |   "editor.formatOnSave": true, | ||||||
|   "eslint.format.enable": true, |  | ||||||
|   "eslint.probe": [ |  | ||||||
|     "javascript", |  | ||||||
|     "javascriptreact", |  | ||||||
|     "typescript", |  | ||||||
|     "typescriptreact", |  | ||||||
|     "html", |  | ||||||
|     "vue", |  | ||||||
|     "markdown", |  | ||||||
|     "json", |  | ||||||
|     "jsonc" |  | ||||||
|   ], |  | ||||||
|   "eslint.validate": [ |  | ||||||
|     "javascript", |  | ||||||
|     "javascriptreact", |  | ||||||
|     "typescript", |  | ||||||
|     "typescriptreact", |  | ||||||
|     "html", |  | ||||||
|     "vue", |  | ||||||
|     "markdown", |  | ||||||
|     "json", |  | ||||||
|     "jsonc" |  | ||||||
|   ], |  | ||||||
|   "files.eol": "\n", |   "files.eol": "\n", | ||||||
|   "typescript.tsdk": "node_modules/typescript/lib", |   "typescript.tsdk": "node_modules/typescript/lib" | ||||||
| } | } | ||||||
| @ -2,49 +2,37 @@ | |||||||
| 
 | 
 | ||||||
| SRC_DIR=./dist/trilium-linux-x64-src | SRC_DIR=./dist/trilium-linux-x64-src | ||||||
| 
 | 
 | ||||||
| if [ "$1" != "DONTCOPY" ] | [ "$1" != "DONTCOPY" ] && ./bin/copy-trilium.sh "$SRC_DIR" | ||||||
| then |  | ||||||
|     ./bin/copy-trilium.sh $SRC_DIR |  | ||||||
| fi |  | ||||||
| 
 | 
 | ||||||
| rm -r $SRC_DIR/src/public/app-dist/*.mobile.* | rm -r "$SRC_DIR"/src/public/app-dist/*.mobile.* | ||||||
| 
 | 
 | ||||||
| echo "Copying required linux-x64 binaries" | echo "Copying required linux-x64 binaries" | ||||||
| 
 | cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node "$SRC_DIR"/node_modules/better-sqlite3/build/Release/better_sqlite3.node | ||||||
| cp -r bin/better-sqlite3/linux-desktop-better_sqlite3.node $SRC_DIR/node_modules/better-sqlite3/build/Release/better_sqlite3.node |  | ||||||
| 
 | 
 | ||||||
| echo "Packaging linux x64 electron build" | echo "Packaging linux x64 electron build" | ||||||
| 
 | ./node_modules/.bin/electron-packager "$SRC_DIR" --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite | ||||||
| ./node_modules/.bin/electron-packager $SRC_DIR --asar --out=dist --executable-name=trilium --platform=linux --arch=x64 --overwrite |  | ||||||
| 
 | 
 | ||||||
| BUILD_DIR=./dist/trilium-linux-x64 | BUILD_DIR=./dist/trilium-linux-x64 | ||||||
| rm -rf $BUILD_DIR | rm -rf "$BUILD_DIR" | ||||||
| 
 | 
 | ||||||
| mv "./dist/Trilium Notes-linux-x64" $BUILD_DIR | mv "./dist/Trilium Notes-linux-x64" "$BUILD_DIR" | ||||||
| 
 | 
 | ||||||
| cp images/app-icons/png/128x128.png $BUILD_DIR/icon.png | cp images/app-icons/png/128x128.png "$BUILD_DIR"/icon.png | ||||||
|  | cp bin/tpl/anonymize-database.sql "$BUILD_DIR"/ | ||||||
| 
 | 
 | ||||||
| cp bin/tpl/anonymize-database.sql $BUILD_DIR/ | cp -r dump-db "$BUILD_DIR"/ | ||||||
|  | rm -rf "$BUILD_DIR"/dump-db/node_modules | ||||||
| 
 | 
 | ||||||
| cp -r dump-db $BUILD_DIR/ | for f in 'trilium-portable' 'trilium-safe-mode' 'trilium-no-cert-check'; do | ||||||
| rm -rf $BUILD_DIR/dump-db/node_modules |     cp bin/tpl/"$f".sh "$BUILD_DIR"/ | ||||||
| 
 |     chmod 755 "$BUILD_DIR"/"$f".sh | ||||||
| cp bin/tpl/trilium-portable.sh $BUILD_DIR/ | done | ||||||
| chmod 755 $BUILD_DIR/trilium-portable.sh |  | ||||||
| 
 |  | ||||||
| cp bin/tpl/trilium-safe-mode.sh $BUILD_DIR/ |  | ||||||
| chmod 755 $BUILD_DIR/trilium-safe-mode.sh |  | ||||||
| 
 |  | ||||||
| cp bin/tpl/trilium-no-cert-check.sh $BUILD_DIR/ |  | ||||||
| chmod 755 $BUILD_DIR/trilium-no-cert-check.sh |  | ||||||
| 
 | 
 | ||||||
| echo "Packaging linux x64 electron distribution..." | echo "Packaging linux x64 electron distribution..." | ||||||
| VERSION=`jq -r ".version" package.json` | VERSION=`jq -r ".version" package.json` | ||||||
| 
 | 
 | ||||||
| cd dist | pushd dist | ||||||
| 
 |     tar cJf "trilium-linux-x64-${VERSION}.tar.xz" trilium-linux-x64 | ||||||
| tar cJf trilium-linux-x64-${VERSION}.tar.xz trilium-linux-x64 | popd | ||||||
| 
 |  | ||||||
| cd .. |  | ||||||
| 
 | 
 | ||||||
| bin/build-debian.sh | bin/build-debian.sh | ||||||
|  | |||||||
| @ -4,47 +4,49 @@ if [[ $# -eq 0 ]] ; then | |||||||
|     echo "Missing argument of target directory" |     echo "Missing argument of target directory" | ||||||
|     exit 1 |     exit 1 | ||||||
| fi | fi | ||||||
|  | if ! [[ $(which npm) ]]; then | ||||||
|  |     echo "Missing npm" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
| 
 | 
 | ||||||
| n exec 18.18.2 npm run webpack | n exec 18.18.2 npm run webpack || npm run webpack | ||||||
| 
 | 
 | ||||||
| DIR=$1 | DIR="$1" | ||||||
| 
 | 
 | ||||||
| rm -rf $DIR | rm -rf "$DIR" | ||||||
| mkdir $DIR | mkdir -pv "$DIR" | ||||||
| 
 | 
 | ||||||
| echo "Copying Trilium to build directory $DIR" | echo "Copying Trilium to build directory $DIR" | ||||||
| 
 | 
 | ||||||
| cp -r images $DIR/ | for d in 'images' 'libraries' 'src' 'db'; do | ||||||
| cp -r libraries $DIR/ |     cp -r "$d" "$DIR"/ | ||||||
| cp -r src $DIR/ | done | ||||||
| cp -r db $DIR/ | for f in 'package.json' 'package-lock.json' 'README.md' 'LICENSE' 'config-sample.ini' 'electron.js'; do | ||||||
| cp -r package.json $DIR/ |     cp "$f" "$DIR"/ | ||||||
| cp -r package-lock.json $DIR/ | done | ||||||
| cp -r README.md $DIR/ | cp webpack-* "$DIR"/      # here warning because there is no 'webpack-*', but webpack.config.js only | ||||||
| cp -r LICENSE $DIR/ |  | ||||||
| cp -r config-sample.ini $DIR/ |  | ||||||
| cp -r electron.js $DIR/ |  | ||||||
| cp webpack-* $DIR/ |  | ||||||
| 
 | 
 | ||||||
| # run in subshell (so we return to original dir) | # run in subshell (so we return to original dir) | ||||||
| (cd $DIR && n exec 18.18.2 npm install --only=prod) | (cd $DIR && n exec 18.18.2 npm install --only=prod) | ||||||
| 
 | 
 | ||||||
|  | if [[ -d "$DIR"/node_modules ]]; then | ||||||
| # cleanup of useless files in dependencies | # cleanup of useless files in dependencies | ||||||
| rm -r $DIR/node_modules/image-q/demo |     for d in 'image-q/demo' 'better-sqlite3/Release' 'better-sqlite3/deps/sqlite3.tar.gz' '@jimp/plugin-print/fonts' 'jimp/browser' 'jimp/fonts'; do | ||||||
| rm -r $DIR/node_modules/better-sqlite3/Release |         [[ -e "$DIR"/node_modules/"$d" ]] && rm -rv "$DIR"/node_modules/"$d" | ||||||
| rm -r $DIR/node_modules/better-sqlite3/deps/sqlite3.tar.gz |     done | ||||||
| rm -r $DIR/node_modules/@jimp/plugin-print/fonts |  | ||||||
| rm -r $DIR/node_modules/jimp/browser |  | ||||||
| rm -r $DIR/node_modules/jimp/fonts |  | ||||||
| 
 | 
 | ||||||
| # delete all tests (there are often large images as test file for jimp etc.) | # delete all tests (there are often large images as test file for jimp etc.) | ||||||
| find $DIR/node_modules -name test -exec rm -rf {} \; |     for d in 'test' 'docs' 'demo'; do | ||||||
| find $DIR/node_modules -name docs -exec rm -rf {} \; |         find "$DIR"/node_modules -name "$d" -exec rm -rf {} \; | ||||||
| find $DIR/node_modules -name demo -exec rm -rf {} \; |     done | ||||||
|  | fi | ||||||
| 
 | 
 | ||||||
| find $DIR/libraries -name "*.map" -type f -delete | find $DIR/libraries -name "*.map" -type f -delete | ||||||
| 
 | 
 | ||||||
| cp $DIR/src/public/app/share.js $DIR/src/public/app-dist/ | d="$DIR"/src/public | ||||||
| cp -r $DIR/src/public/app/doc_notes $DIR/src/public/app-dist/ | [[ -d "$d"/app-dist ]] || mkdir -pv "$d"/app-dist | ||||||
|  | cp "$d"/app/share.js "$d"/app-dist/ | ||||||
|  | cp -r "$d"/app/doc_notes "$d"/app-dist/ | ||||||
| 
 | 
 | ||||||
| rm -rf $DIR/src/public/app | rm -rf "$d"/app | ||||||
|  | unset f d DIR | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| module.exports = () => { | module.exports = () => { | ||||||
|     const beccaLoader = require('../../src/becca/becca_loader'); |     const beccaLoader = require('../../src/becca/becca_loader'); | ||||||
|     const becca = require('../../src/becca/becca.js'); |     const becca = require('../../src/becca/becca'); | ||||||
|     const cls = require('../../src/services/cls'); |     const cls = require('../../src/services/cls'); | ||||||
|     const log = require('../../src/services/log'); |     const log = require('../../src/services/log'); | ||||||
|     const sql = require('../../src/services/sql'); |     const sql = require('../../src/services/sql'); | ||||||
| @ -13,7 +13,7 @@ module.exports = () => { | |||||||
| 
 | 
 | ||||||
|         for (const note of Object.values(becca.notes)) { |         for (const note of Object.values(becca.notes)) { | ||||||
|             try { |             try { | ||||||
|                 const attachment = note.convertToParentAttachment({autoConversion: true}); |                 const attachment = note.convertToParentAttachment({ autoConversion: true }); | ||||||
| 
 | 
 | ||||||
|                 if (attachment) { |                 if (attachment) { | ||||||
|                     log.info(`Auto-converted note '${note.noteId}' into attachment '${attachment.attachmentId}'.`); |                     log.info(`Auto-converted note '${note.noteId}' into attachment '${attachment.attachmentId}'.`); | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| const fs = require("fs"); | const fs = require("fs"); | ||||||
| const sanitize = require("sanitize-filename"); | const sanitize = require("sanitize-filename"); | ||||||
| const sql = require('./sql'); | const sql = require('./sql.js'); | ||||||
| const decryptService = require('./decrypt.js'); | const decryptService = require('./decrypt.js'); | ||||||
| const dataKeyService = require('./data_key.js'); | const dataKeyService = require('./data_key.js'); | ||||||
| const extensionService = require('./extension.js'); | const extensionService = require('./extension.js'); | ||||||
| @ -74,7 +74,7 @@ function dumpDocument(documentPath, targetPath, options) { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let {content} = sql.getRow("SELECT content FROM blobs WHERE blobId = ?", [noteRow.blobId]); |             let { content } = sql.getRow("SELECT content FROM blobs WHERE blobId = ?", [noteRow.blobId]); | ||||||
| 
 | 
 | ||||||
|             if (content !== null && noteRow.isProtected && dataKey) { |             if (content !== null && noteRow.isProtected && dataKey) { | ||||||
|                 content = decryptService.decrypt(dataKey, content); |                 content = decryptService.decrypt(dataKey, content); | ||||||
| @ -108,7 +108,7 @@ function dumpDocument(documentPath, targetPath, options) { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             try { |             try { | ||||||
|                 fs.mkdirSync(childTargetPath, {recursive: true}); |                 fs.mkdirSync(childTargetPath, { recursive: true }); | ||||||
|             } |             } | ||||||
|             catch (e) { |             catch (e) { | ||||||
|                 console.error(`DUMPERROR: Creating directory ${childTargetPath} failed with error '${e.message}'`); |                 console.error(`DUMPERROR: Creating directory ${childTargetPath} failed with error '${e.message}'`); | ||||||
| @ -157,7 +157,7 @@ function validatePaths(documentPath, targetPath) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!fs.existsSync(targetPath)) { |     if (!fs.existsSync(targetPath)) { | ||||||
|         const ret = fs.mkdirSync(targetPath, {recursive: true}); |         const ret = fs.mkdirSync(targetPath, { recursive: true }); | ||||||
| 
 | 
 | ||||||
|         if (!ret) { |         if (!ret) { | ||||||
|             console.error(`Target path '${targetPath}' could not be created. Run with --help to see usage.`); |             console.error(`Target path '${targetPath}' could not be created. Run with --help to see usage.`); | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								libraries/ckeditor/ckeditor.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								libraries/ckeditor/ckeditor.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										7287
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7287
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										75
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								package.json
									
									
									
									
									
								
							| @ -2,7 +2,7 @@ | |||||||
|   "name": "trilium", |   "name": "trilium", | ||||||
|   "productName": "Trilium Notes", |   "productName": "Trilium Notes", | ||||||
|   "description": "Trilium Notes", |   "description": "Trilium Notes", | ||||||
|   "version": "0.63.1-beta", |   "version": "0.63.5", | ||||||
|   "license": "AGPL-3.0-only", |   "license": "AGPL-3.0-only", | ||||||
|   "main": "electron.js", |   "main": "electron.js", | ||||||
|   "bin": { |   "bin": { | ||||||
| @ -31,21 +31,18 @@ | |||||||
|     "test-jasmine": "TRILIUM_DATA_DIR=~/trilium/data-test jasmine", |     "test-jasmine": "TRILIUM_DATA_DIR=~/trilium/data-test jasmine", | ||||||
|     "test-es6": "node -r esm spec-es6/attribute_parser.spec.js ", |     "test-es6": "node -r esm spec-es6/attribute_parser.spec.js ", | ||||||
|     "test": "npm run test-jasmine && npm run test-es6", |     "test": "npm run test-jasmine && npm run test-es6", | ||||||
|     "postinstall": "rimraf ./node_modules/canvas", |     "postinstall": "rimraf ./node_modules/canvas" | ||||||
|     "lint": "eslint .  --cache", |  | ||||||
|     "prepare": "husky install || echo 'Husky install failed, expected on flatpak build'" |  | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@braintree/sanitize-url": "6.0.4", |     "@braintree/sanitize-url": "6.0.4", | ||||||
|     "@electron/remote": "2.1.0", |     "@electron/remote": "2.1.2", | ||||||
|     "@excalidraw/excalidraw": "0.16.1", |     "@excalidraw/excalidraw": "0.17.3", | ||||||
|     "@types/cls-hooked": "^4.3.8", |     "archiver": "7.0.0", | ||||||
|     "archiver": "6.0.1", |     "async-mutex": "0.4.1", | ||||||
|     "async-mutex": "0.4.0", |     "axios": "1.6.7", | ||||||
|     "axios": "1.6.2", |  | ||||||
|     "better-sqlite3": "8.4.0", |     "better-sqlite3": "8.4.0", | ||||||
|     "boxicons": "2.1.4", |     "boxicons": "2.1.4", | ||||||
|     "chokidar": "3.5.3", |     "chokidar": "3.6.0", | ||||||
|     "cls-hooked": "4.2.2", |     "cls-hooked": "4.2.2", | ||||||
|     "compression": "1.7.4", |     "compression": "1.7.4", | ||||||
|     "cookie-parser": "1.4.6", |     "cookie-parser": "1.4.6", | ||||||
| @ -55,35 +52,35 @@ | |||||||
|     "debounce": "1.2.1", |     "debounce": "1.2.1", | ||||||
|     "ejs": "3.1.9", |     "ejs": "3.1.9", | ||||||
|     "electron-debug": "3.2.0", |     "electron-debug": "3.2.0", | ||||||
|     "electron-dl": "3.5.1", |     "electron-dl": "3.5.2", | ||||||
|     "electron-window-state": "5.0.3", |     "electron-window-state": "5.0.3", | ||||||
|     "escape-html": "1.0.3", |     "escape-html": "1.0.3", | ||||||
|     "express": "4.18.2", |     "express": "4.18.3", | ||||||
|     "express-partial-content": "1.0.2", |     "express-partial-content": "1.0.2", | ||||||
|     "express-rate-limit": "7.1.4", |     "express-rate-limit": "7.2.0", | ||||||
|     "express-session": "1.17.3", |     "express-session": "1.18.0", | ||||||
|     "force-graph": "1.43.4", |     "force-graph": "1.43.5", | ||||||
|     "fs-extra": "11.1.1", |     "fs-extra": "11.2.0", | ||||||
|     "helmet": "7.1.0", |     "helmet": "7.1.0", | ||||||
|     "html": "1.0.0", |     "html": "1.0.0", | ||||||
|     "html2plaintext": "2.1.4", |     "html2plaintext": "2.1.4", | ||||||
|     "http-proxy-agent": "7.0.0", |     "http-proxy-agent": "7.0.2", | ||||||
|     "https-proxy-agent": "7.0.2", |     "https-proxy-agent": "7.0.4", | ||||||
|     "image-type": "4.1.0", |     "image-type": "4.1.0", | ||||||
|     "ini": "3.0.1", |     "ini": "3.0.1", | ||||||
|     "is-animated": "2.0.2", |     "is-animated": "2.0.2", | ||||||
|     "is-svg": "4.3.2", |     "is-svg": "4.3.2", | ||||||
|     "jimp": "0.22.10", |     "jimp": "0.22.12", | ||||||
|     "joplin-turndown-plugin-gfm": "1.0.12", |     "joplin-turndown-plugin-gfm": "1.0.12", | ||||||
|     "jquery": "3.7.1", |     "jquery": "3.7.1", | ||||||
|     "jquery-hotkeys": "0.2.2", |     "jquery-hotkeys": "0.2.2", | ||||||
|     "jsdom": "22.1.0", |     "jsdom": "24.0.0", | ||||||
|     "katex": "0.16.9", |     "katex": "0.16.9", | ||||||
|     "marked": "9.1.6", |     "marked": "12.0.0", | ||||||
|     "mermaid": "10.6.1", |     "mermaid": "10.9.0", | ||||||
|     "mime-types": "2.1.35", |     "mime-types": "2.1.35", | ||||||
|     "multer": "1.4.5-lts.1", |     "multer": "1.4.5-lts.1", | ||||||
|     "node-abi": "3.51.0", |     "node-abi": "3.56.0", | ||||||
|     "normalize-strings": "1.1.1", |     "normalize-strings": "1.1.1", | ||||||
|     "open": "8.4.1", |     "open": "8.4.1", | ||||||
|     "panzoom": "9.4.3", |     "panzoom": "9.4.3", | ||||||
| @ -95,24 +92,25 @@ | |||||||
|     "rimraf": "5.0.5", |     "rimraf": "5.0.5", | ||||||
|     "safe-compare": "1.1.4", |     "safe-compare": "1.1.4", | ||||||
|     "sanitize-filename": "1.6.3", |     "sanitize-filename": "1.6.3", | ||||||
|     "sanitize-html": "2.11.0", |     "sanitize-html": "2.12.1", | ||||||
|     "sax": "1.3.0", |     "sax": "1.3.0", | ||||||
|     "semver": "7.5.4", |     "semver": "7.6.0", | ||||||
|     "serve-favicon": "2.5.0", |     "serve-favicon": "2.5.0", | ||||||
|     "session-file-store": "1.5.0", |     "session-file-store": "1.5.0", | ||||||
|     "split.js": "1.6.5", |     "split.js": "1.6.5", | ||||||
|     "stream-throttle": "0.1.3", |     "stream-throttle": "0.1.3", | ||||||
|     "striptags": "3.2.0", |     "striptags": "3.2.0", | ||||||
|     "tmp": "0.2.1", |     "tmp": "0.2.3", | ||||||
|     "tree-kill": "1.2.2", |     "tree-kill": "1.2.2", | ||||||
|     "turndown": "7.1.2", |     "turndown": "7.1.2", | ||||||
|     "unescape": "1.0.1", |     "unescape": "1.0.1", | ||||||
|     "ws": "8.14.2", |     "ws": "8.16.0", | ||||||
|     "xml2js": "0.6.2", |     "xml2js": "0.6.2", | ||||||
|     "yauzl": "2.10.0" |     "yauzl": "3.1.2" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@types/better-sqlite3": "^7.6.9", |     "@types/better-sqlite3": "^7.6.9", | ||||||
|  |     "@types/cls-hooked": "^4.3.8", | ||||||
|     "@types/escape-html": "^1.0.4", |     "@types/escape-html": "^1.0.4", | ||||||
|     "@types/express": "^4.17.21", |     "@types/express": "^4.17.21", | ||||||
|     "@types/ini": "^4.1.0", |     "@types/ini": "^4.1.0", | ||||||
| @ -123,35 +121,22 @@ | |||||||
|     "@types/ws": "^8.5.10", |     "@types/ws": "^8.5.10", | ||||||
|     "cross-env": "7.0.3", |     "cross-env": "7.0.3", | ||||||
|     "electron": "25.9.8", |     "electron": "25.9.8", | ||||||
|     "electron-builder": "24.6.4", |     "electron-builder": "24.13.3", | ||||||
|     "electron-packager": "17.1.2", |     "electron-packager": "17.1.2", | ||||||
|     "electron-rebuild": "3.2.9", |     "electron-rebuild": "3.2.9", | ||||||
|     "eslint": "8.54.0", |  | ||||||
|     "eslint-config-airbnb-base": "15.0.0", |  | ||||||
|     "eslint-config-prettier": "9.0.0", |  | ||||||
|     "eslint-plugin-import": "2.29.0", |  | ||||||
|     "eslint-plugin-jsonc": "2.10.0", |  | ||||||
|     "eslint-plugin-prettier": "5.0.1", |  | ||||||
|     "esm": "3.2.25", |     "esm": "3.2.25", | ||||||
|     "husky": "8.0.3", |  | ||||||
|     "jasmine": "5.1.0", |     "jasmine": "5.1.0", | ||||||
|     "jsdoc": "4.0.2", |     "jsdoc": "4.0.2", | ||||||
|     "jsonc-eslint-parser": "2.4.0", |  | ||||||
|     "lint-staged": "15.1.0", |  | ||||||
|     "lorem-ipsum": "2.0.8", |     "lorem-ipsum": "2.0.8", | ||||||
|     "nodemon": "3.0.1", |     "nodemon": "3.1.0", | ||||||
|     "prettier": "3.1.0", |  | ||||||
|     "rcedit": "4.0.1", |     "rcedit": "4.0.1", | ||||||
|     "ts-node": "^10.9.2", |     "ts-node": "^10.9.2", | ||||||
|     "tslib": "^2.6.2", |     "tslib": "^2.6.2", | ||||||
|     "typescript": "^5.3.3", |     "typescript": "^5.3.3", | ||||||
|     "webpack": "5.89.0", |     "webpack": "5.90.3", | ||||||
|     "webpack-cli": "5.1.4" |     "webpack-cli": "5.1.4" | ||||||
|   }, |   }, | ||||||
|   "optionalDependencies": { |   "optionalDependencies": { | ||||||
|     "electron-installer-debian": "3.2.0" |     "electron-installer-debian": "3.2.0" | ||||||
|   }, |  | ||||||
|   "lint-staged": { |  | ||||||
|     "*.js": "eslint --cache --fix" |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -11,6 +11,7 @@ import BAttachment = require('./entities/battachment'); | |||||||
| import { AttachmentRow, RevisionRow } from './entities/rows'; | import { AttachmentRow, RevisionRow } from './entities/rows'; | ||||||
| import BBlob = require('./entities/bblob'); | import BBlob = require('./entities/bblob'); | ||||||
| import BRecentNote = require('./entities/brecent_note'); | import BRecentNote = require('./entities/brecent_note'); | ||||||
|  | import AbstractBeccaEntity = require('./entities/abstract_becca_entity'); | ||||||
| 
 | 
 | ||||||
| interface AttachmentOpts { | interface AttachmentOpts { | ||||||
|     includeContentLength?: boolean; |     includeContentLength?: boolean; | ||||||
| @ -95,7 +96,7 @@ class Becca { | |||||||
|         return this.notes[noteId]; |         return this.notes[noteId]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getNoteOrThrow(noteId: string): BNote | null { |     getNoteOrThrow(noteId: string): BNote { | ||||||
|         const note = this.notes[noteId]; |         const note = this.notes[noteId]; | ||||||
|         if (!note) { |         if (!note) { | ||||||
|             throw new NotFoundError(`Note '${noteId}' doesn't exist.`); |             throw new NotFoundError(`Note '${noteId}' doesn't exist.`); | ||||||
| @ -190,7 +191,11 @@ class Becca { | |||||||
|             .map(row => new BAttachment(row)); |             .map(row => new BAttachment(row)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getBlob(entity: { blobId: string }): BBlob | null { |     getBlob(entity: { blobId?: string }): BBlob | null { | ||||||
|  |         if (!entity.blobId) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         const row = sql.getRow("SELECT *, LENGTH(content) AS contentLength FROM blobs WHERE blobId = ?", [entity.blobId]); |         const row = sql.getRow("SELECT *, LENGTH(content) AS contentLength FROM blobs WHERE blobId = ?", [entity.blobId]); | ||||||
| 
 | 
 | ||||||
|         const BBlob = require('./entities/bblob'); // avoiding circular dependency problems
 |         const BBlob = require('./entities/bblob'); // avoiding circular dependency problems
 | ||||||
| @ -209,8 +214,7 @@ class Becca { | |||||||
|         return this.etapiTokens[etapiTokenId]; |         return this.etapiTokens[etapiTokenId]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** @returns {AbstractBeccaEntity|null} */ |     getEntity<T extends AbstractBeccaEntity<T>>(entityName: string, entityId: string): AbstractBeccaEntity<T> | null { | ||||||
|     getEntity(entityName: string, entityId: string) { |  | ||||||
|         if (!entityName || !entityId) { |         if (!entityName || !entityId) { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ const beccaLoaded = new Promise<void>((res, rej) => { | |||||||
|         cls.init(() => { |         cls.init(() => { | ||||||
|             load(); |             load(); | ||||||
| 
 | 
 | ||||||
|             require('../services/options_init').initStartupOptions(); |             require('../services/options_init.js').initStartupOptions(); | ||||||
| 
 | 
 | ||||||
|             res(); |             res(); | ||||||
|         }); |         }); | ||||||
| @ -75,7 +75,7 @@ function reload(reason: string) { | |||||||
|     require('../services/ws').reloadFrontend(reason || "becca reloaded"); |     require('../services/ws').reloadFrontend(reason || "becca reloaded"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED],  ({entityName, entityRow}) => { | eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED], ({ entityName, entityRow }) => { | ||||||
|     if (!becca.loaded) { |     if (!becca.loaded) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @ -98,7 +98,7 @@ eventService.subscribeBeccaLoader([eventService.ENTITY_CHANGE_SYNCED],  ({entity | |||||||
|     postProcessEntityUpdate(entityName, entityRow); |     postProcessEntityUpdate(entityName, entityRow); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED,  ({entityName, entity}) => { | eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED, ({ entityName, entity }) => { | ||||||
|     if (!becca.loaded) { |     if (!becca.loaded) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @ -125,7 +125,7 @@ function postProcessEntityUpdate(entityName: string, entityRow: any) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_SYNCED],  ({entityName, entityId}) => { | eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENTITY_DELETE_SYNCED], ({ entityName, entityId }) => { | ||||||
|     if (!becca.loaded) { |     if (!becca.loaded) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -18,6 +18,10 @@ interface ContentOpts { | |||||||
|     forceFrontendReload?: boolean; |     forceFrontendReload?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * This interface contains the data that is shared across all the objects of a given derived class of {@link AbstractBeccaEntity}. | ||||||
|  |  * For example, all BAttributes will share their content, but all BBranches will have another set of this data.  | ||||||
|  |  */ | ||||||
| interface ConstructorData<T extends AbstractBeccaEntity<T>> { | interface ConstructorData<T extends AbstractBeccaEntity<T>> { | ||||||
|     primaryKeyName: string; |     primaryKeyName: string; | ||||||
|     entityName: string; |     entityName: string; | ||||||
| @ -26,18 +30,20 @@ interface ConstructorData<T extends AbstractBeccaEntity<T>> { | |||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Base class for all backend entities. |  * Base class for all backend entities. | ||||||
|  |  *  | ||||||
|  |  * @type T the same entity type needed for self-reference in {@link ConstructorData}. | ||||||
|  */ |  */ | ||||||
| abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> { | abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> { | ||||||
| 
 | 
 | ||||||
|     protected utcDateModified?: string; |     protected utcDateModified?: string; | ||||||
|     protected dateCreated?: string; |     protected dateCreated?: string; | ||||||
|     protected dateModified?: string; |     protected dateModified?: string; | ||||||
|     protected isSynced?: boolean; |  | ||||||
|      |  | ||||||
|     protected blobId?: string; |  | ||||||
|      |      | ||||||
|     utcDateCreated!: string; |     utcDateCreated!: string; | ||||||
|  | 
 | ||||||
|     isProtected?: boolean; |     isProtected?: boolean; | ||||||
|  |     isSynced?: boolean; | ||||||
|  |     blobId?: string; | ||||||
| 
 | 
 | ||||||
|     protected beforeSaving() { |     protected beforeSaving() { | ||||||
|         const constructorData = (this.constructor as unknown as ConstructorData<T>); |         const constructorData = (this.constructor as unknown as ConstructorData<T>); | ||||||
| @ -46,7 +52,7 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected getUtcDateChanged() { |     getUtcDateChanged() { | ||||||
|         return this.utcDateModified || this.utcDateCreated; |         return this.utcDateModified || this.utcDateCreated; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -70,7 +76,7 @@ abstract class AbstractBeccaEntity<T extends AbstractBeccaEntity<T>> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected generateHash(isDeleted: boolean): string { |     generateHash(isDeleted?: boolean): string { | ||||||
|         const constructorData = (this.constructor as unknown as ConstructorData<T>); |         const constructorData = (this.constructor as unknown as ConstructorData<T>); | ||||||
|         let contentToHash = ""; |         let contentToHash = ""; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,7 +11,8 @@ import BNote = require('./bnote'); | |||||||
| import BBranch = require('./bbranch'); | import BBranch = require('./bbranch'); | ||||||
| 
 | 
 | ||||||
| const attachmentRoleToNoteTypeMapping = { | const attachmentRoleToNoteTypeMapping = { | ||||||
|     'image': 'image' |     'image': 'image', | ||||||
|  |     'file': 'file' | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| interface ContentOpts { | interface ContentOpts { | ||||||
| @ -130,7 +131,7 @@ class BAttachment extends AbstractBeccaEntity<BAttachment> { | |||||||
|         return this._getContent() as Buffer; |         return this._getContent() as Buffer; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     setContent(content: any, opts: ContentOpts) { |     setContent(content: string | Buffer, opts: ContentOpts) { | ||||||
|         this._setContent(content, opts); |         this._setContent(content, opts); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -115,7 +115,7 @@ class BRevision extends AbstractBeccaEntity<BRevision> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     setContent(content: any, opts: ContentOpts = {}) { |     setContent(content: string | Buffer, opts: ContentOpts = {}) { | ||||||
|         this._setContent(content, opts); |         this._setContent(content, opts); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -158,6 +158,13 @@ class BRevision extends AbstractBeccaEntity<BRevision> { | |||||||
|         return this.getAttachments().filter(attachment => attachment.title === title)[0]; |         return this.getAttachments().filter(attachment => attachment.title === title)[0]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Revisions are not soft-deletable, they are immediately hard-deleted (erased). | ||||||
|  |      */ | ||||||
|  |     eraseRevision() { | ||||||
|  |         require("../../services/erase.js").eraseRevisions([this.revisionId]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|         super.beforeSaving(); |         super.beforeSaving(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -43,7 +43,7 @@ interface DateLimits { | |||||||
| function filterUrlValue(value: string) { | function filterUrlValue(value: string) { | ||||||
|     return value |     return value | ||||||
|         .replace(/https?:\/\//ig, "") |         .replace(/https?:\/\//ig, "") | ||||||
|         .replace(/www\./ig, "") |         .replace(/www.js\./ig, "") | ||||||
|         .replace(/(\.net|\.com|\.org|\.info|\.edu)/ig, ""); |         .replace(/(\.net|\.com|\.org|\.info|\.edu)/ig, ""); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import froca from "./froca.js"; | |||||||
| import attributeRenderer from "./attribute_renderer.js"; | import attributeRenderer from "./attribute_renderer.js"; | ||||||
| import libraryLoader from "./library_loader.js"; | import libraryLoader from "./library_loader.js"; | ||||||
| import treeService from "./tree.js"; | import treeService from "./tree.js"; | ||||||
|  | import utils from "./utils.js"; | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="note-list"> | <div class="note-list"> | ||||||
| @ -215,7 +216,11 @@ class NoteListRenderer { | |||||||
|         if (highlightedTokens.length > 0) { |         if (highlightedTokens.length > 0) { | ||||||
|             await libraryLoader.requireLibrary(libraryLoader.MARKJS); |             await libraryLoader.requireLibrary(libraryLoader.MARKJS); | ||||||
| 
 | 
 | ||||||
|             this.highlightRegex = new RegExp(highlightedTokens.join("|"), 'gi'); |             const regex = highlightedTokens | ||||||
|  |                 .map(token => utils.escapeRegExp(token)) | ||||||
|  |                 .join("|"); | ||||||
|  | 
 | ||||||
|  |             this.highlightRegex = new RegExp(regex, 'gi'); | ||||||
|         } else { |         } else { | ||||||
|             this.highlightRegex = null; |             this.highlightRegex = null; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -487,12 +487,14 @@ function areObjectsEqual () { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function copyHtmlToClipboard(content) { | function copyHtmlToClipboard(content) { | ||||||
|     const clipboardItem = new ClipboardItem({ |     function listener(e) { | ||||||
|         'text/html': new Blob([content], {type: 'text/html'}), |         e.clipboardData.setData("text/html", content); | ||||||
|         'text/plain': new Blob([content], {type: 'text/plain'}) |         e.clipboardData.setData("text/plain", content); | ||||||
|     }); |         e.preventDefault(); | ||||||
| 
 |     } | ||||||
|     navigator.clipboard.write([clipboardItem]); |     document.addEventListener("copy", listener); | ||||||
|  |     document.execCommand("copy"); | ||||||
|  |     document.removeEventListener("copy", listener); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  | |||||||
| @ -1,10 +1,8 @@ | |||||||
| import libraryLoader from "../../services/library_loader.js"; | import libraryLoader from '../../services/library_loader.js'; | ||||||
| import TypeWidget from "./type_widget.js"; | import TypeWidget from './type_widget.js'; | ||||||
| import utils from '../../services/utils.js'; | import utils from '../../services/utils.js'; | ||||||
| import linkService from '../../services/link.js'; | import linkService from '../../services/link.js'; | ||||||
| import debounce from "../../services/debounce.js"; | import debounce from '../../services/debounce.js'; | ||||||
| 
 |  | ||||||
| const {sleep} = utils; |  | ||||||
| 
 | 
 | ||||||
| const TPL = ` | const TPL = ` | ||||||
|     <div class="canvas-widget note-detail-canvas note-detail-printable note-detail"> |     <div class="canvas-widget note-detail-canvas note-detail-printable note-detail"> | ||||||
| @ -115,7 +113,6 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|         this.currentSceneVersion = this.SCENE_VERSION_INITIAL; |         this.currentSceneVersion = this.SCENE_VERSION_INITIAL; | ||||||
| 
 | 
 | ||||||
|         // will be overwritten
 |         // will be overwritten
 | ||||||
|         this.excalidrawRef; |  | ||||||
|         this.$render; |         this.$render; | ||||||
|         this.$widget; |         this.$widget; | ||||||
|         this.reactHandlers; // used to control react state
 |         this.reactHandlers; // used to control react state
 | ||||||
| @ -155,7 +152,8 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|                 const renderElement = this.$render.get(0); |                 const renderElement = this.$render.get(0); | ||||||
| 
 | 
 | ||||||
|                 ReactDOM.unmountComponentAtNode(renderElement); |                 ReactDOM.unmountComponentAtNode(renderElement); | ||||||
|                 ReactDOM.render(React.createElement(this.createExcalidrawReactApp), renderElement); |                 const root = ReactDOM.createRoot(renderElement); | ||||||
|  |                 root.render(React.createElement(this.createExcalidrawReactApp)); | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|         return this.$widget; |         return this.$widget; | ||||||
| @ -179,9 +177,9 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|         const blob = await note.getBlob(); |         const blob = await note.getBlob(); | ||||||
| 
 | 
 | ||||||
|         // before we load content into excalidraw, make sure excalidraw has loaded
 |         // before we load content into excalidraw, make sure excalidraw has loaded
 | ||||||
|         while (!this.excalidrawRef?.current) { |         while (!this.excalidrawApi) { | ||||||
|             console.log("excalidrawRef not yet loaded, sleep 200ms..."); |             console.log("excalidrawApi not yet loaded, sleep 200ms..."); | ||||||
|             await sleep(200); |             await utils.sleep(200); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /** |         /** | ||||||
| @ -199,7 +197,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|                 collaborators: [] |                 collaborators: [] | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             this.excalidrawRef.current.updateScene(sceneData); |             this.excalidrawApi.updateScene(sceneData); | ||||||
|         } |         } | ||||||
|         else if (blob.content) { |         else if (blob.content) { | ||||||
|             // load saved content into excalidraw canvas
 |             // load saved content into excalidraw canvas
 | ||||||
| @ -246,9 +244,9 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|                 fileArray.push(file); |                 fileArray.push(file); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             this.excalidrawRef.current.updateScene(sceneData); |             this.excalidrawApi.updateScene(sceneData); | ||||||
|             this.excalidrawRef.current.addFiles(fileArray); |             this.excalidrawApi.addFiles(fileArray); | ||||||
|             this.excalidrawRef.current.history.clear(); |             this.excalidrawApi.history.clear(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Promise.all( |         Promise.all( | ||||||
| @ -261,7 +259,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             const libraryItems = blobs.map(blob => blob.getJsonContentSafely()).filter(item => !!item); |             const libraryItems = blobs.map(blob => blob.getJsonContentSafely()).filter(item => !!item); | ||||||
|             this.excalidrawRef.current.updateLibrary({libraryItems, merge: false}); |             this.excalidrawApi.updateLibrary({libraryItems, merge: false}); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         // set initial scene version
 |         // set initial scene version
 | ||||||
| @ -275,17 +273,17 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|      * this is automatically called after this.saveData(); |      * this is automatically called after this.saveData(); | ||||||
|      */ |      */ | ||||||
|     async getData() { |     async getData() { | ||||||
|         const elements = this.excalidrawRef.current.getSceneElements(); |         const elements = this.excalidrawApi.getSceneElements(); | ||||||
|         const appState = this.excalidrawRef.current.getAppState(); |         const appState = this.excalidrawApi.getAppState(); | ||||||
| 
 | 
 | ||||||
|         /** |         /** | ||||||
|          * A file is not deleted, even though removed from canvas. Therefore, we only keep |          * A file is not deleted, even though removed from canvas. Therefore, we only keep | ||||||
|          * files that are referenced by an element. Maybe this will change with a new excalidraw version? |          * files that are referenced by an element. Maybe this will change with a new excalidraw version? | ||||||
|          */ |          */ | ||||||
|         const files = this.excalidrawRef.current.getFiles(); |         const files = this.excalidrawApi.getFiles(); | ||||||
| 
 | 
 | ||||||
|         // parallel svg export to combat bitrot and enable rendering image for note inclusion, preview, and share
 |         // parallel svg export to combat bitrot and enable rendering image for note inclusion, preview, and share
 | ||||||
|         const svg = await window.ExcalidrawLib.exportToSvg({ |         const svg = await ExcalidrawLib.exportToSvg({ | ||||||
|             elements, |             elements, | ||||||
|             appState, |             appState, | ||||||
|             exportPadding: 5, // 5 px padding
 |             exportPadding: 5, // 5 px padding
 | ||||||
| @ -321,7 +319,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|             // this.libraryChanged is unset in dataSaved()
 |             // this.libraryChanged is unset in dataSaved()
 | ||||||
| 
 | 
 | ||||||
|             // there's no separate method to get library items, so have to abuse this one
 |             // there's no separate method to get library items, so have to abuse this one
 | ||||||
|             const libraryItems = await this.excalidrawRef.current.updateLibrary({merge: true}); |             const libraryItems = await this.excalidrawApi.updateLibrary({merge: true}); | ||||||
| 
 | 
 | ||||||
|             let position = 10; |             let position = 10; | ||||||
| 
 | 
 | ||||||
| @ -379,9 +377,6 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|     createExcalidrawReactApp() { |     createExcalidrawReactApp() { | ||||||
|         const React = window.React; |         const React = window.React; | ||||||
|         const { Excalidraw } = window.ExcalidrawLib; |         const { Excalidraw } = window.ExcalidrawLib; | ||||||
| 
 |  | ||||||
|         const excalidrawRef = React.useRef(null); |  | ||||||
|         this.excalidrawRef = excalidrawRef; |  | ||||||
|         const excalidrawWrapperRef = React.useRef(null); |         const excalidrawWrapperRef = React.useRef(null); | ||||||
|         this.excalidrawWrapperRef = excalidrawWrapperRef; |         this.excalidrawWrapperRef = excalidrawWrapperRef; | ||||||
|         const [dimensions, setDimensions] = React.useState({ |         const [dimensions, setDimensions] = React.useState({ | ||||||
| @ -439,7 +434,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|                 React.createElement(Excalidraw, { |                 React.createElement(Excalidraw, { | ||||||
|                     // this makes sure that 1) manual theme switch button is hidden 2) theme stays as it should after opening menu
 |                     // this makes sure that 1) manual theme switch button is hidden 2) theme stays as it should after opening menu
 | ||||||
|                     theme: this.themeStyle, |                     theme: this.themeStyle, | ||||||
|                     ref: excalidrawRef, |                     excalidrawAPI: api => { this.excalidrawApi = api; }, | ||||||
|                     width: dimensions.width, |                     width: dimensions.width, | ||||||
|                     height: dimensions.height, |                     height: dimensions.height, | ||||||
|                     onPaste: (data, event) => { |                     onPaste: (data, event) => { | ||||||
| @ -483,8 +478,8 @@ export default class ExcalidrawTypeWidget extends TypeWidget { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getSceneVersion() { |     getSceneVersion() { | ||||||
|         if (this.excalidrawRef) { |         if (this.excalidrawApi) { | ||||||
|             const elements = this.excalidrawRef.current.getSceneElements(); |             const elements = this.excalidrawApi.getSceneElements(); | ||||||
|             return window.ExcalidrawLib.getSceneVersion(elements); |             return window.ExcalidrawLib.getSceneVersion(elements); | ||||||
|         } else { |         } else { | ||||||
|             return this.SCENE_VERSION_ERROR; |             return this.SCENE_VERSION_ERROR; | ||||||
|  | |||||||
| @ -88,3 +88,7 @@ body .CodeMirror { | |||||||
| .excalidraw.theme--dark { | .excalidraw.theme--dark { | ||||||
|     --theme-filter: invert(80%) hue-rotate(180deg) !important; |     --theme-filter: invert(80%) hue-rotate(180deg) !important; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | body .todo-list input[type="checkbox"]:not(:checked):before { | ||||||
|  |     border-color: var(--muted-text-color) !important; | ||||||
|  | } | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ function getBlobPojo(entityName: string, entityId: string) { | |||||||
|     if (!entity.hasStringContent()) { |     if (!entity.hasStringContent()) { | ||||||
|         pojo.content = null; |         pojo.content = null; | ||||||
|     } else { |     } else { | ||||||
|         pojo.content = processContent(pojo.content, entity.isProtected, true); |         pojo.content = processContent(pojo.content, !!entity.isProtected, true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return pojo; |     return pojo; | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| export = { buildDate:"2024-01-21T23:49:23+01:00", buildRevision: "4f8073daa7cff1b8b6737ae45792b2e87c2adf33" }; | export = { buildDate:"2024-03-28T07:11:39+01:00", buildRevision: "399458b52f250b22be22d980a78de0b3390d7521" }; | ||||||
|  | |||||||
| @ -1,15 +1,15 @@ | |||||||
| interface DefinitionObject { | interface DefinitionObject { | ||||||
|     isPromoted: boolean; |     isPromoted?: boolean; | ||||||
|     labelType: string; |     labelType?: string; | ||||||
|     multiplicity: string; |     multiplicity?: string; | ||||||
|     numberPrecision: number; |     numberPrecision?: number; | ||||||
|     promotedAlias: string; |     promotedAlias?: string; | ||||||
|     inverseRelation: string; |     inverseRelation?: string; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function parse(value: string): DefinitionObject { | function parse(value: string): DefinitionObject { | ||||||
|     const tokens = value.split(',').map(t => t.trim()); |     const tokens = value.split(',').map(t => t.trim()); | ||||||
|     const defObj: Partial<DefinitionObject> = {}; |     const defObj: DefinitionObject = {}; | ||||||
| 
 | 
 | ||||||
|     for (const token of tokens) { |     for (const token of tokens) { | ||||||
|         if (token === 'promoted') { |         if (token === 'promoted') { | ||||||
| @ -41,7 +41,7 @@ function parse(value: string): DefinitionObject { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return defObj as DefinitionObject; |     return defObj; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export = { | export = { | ||||||
|  | |||||||
| @ -111,11 +111,7 @@ class NoteContentFulltextExp extends Expression { | |||||||
| 
 | 
 | ||||||
|         if (type === 'text' && mime === 'text/html') { |         if (type === 'text' && mime === 'text/html') { | ||||||
|             if (!this.raw && content.length < 20000) { // striptags is slow for very large notes
 |             if (!this.raw && content.length < 20000) { // striptags is slow for very large notes
 | ||||||
|                 // allow link to preserve URLs: https://github.com/zadam/trilium/issues/2412
 |                 content = this.stripTags(content); | ||||||
|                 content = striptags(content, ['a'], ' '); |  | ||||||
| 
 |  | ||||||
|                 // at least the closing tag can be easily stripped
 |  | ||||||
|                 content = content.replace(/<\/a>/ig, ""); |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             content = content.replace(/ /g, ' '); |             content = content.replace(/ /g, ' '); | ||||||
| @ -123,6 +119,23 @@ class NoteContentFulltextExp extends Expression { | |||||||
| 
 | 
 | ||||||
|         return content.trim(); |         return content.trim(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     stripTags(content) { | ||||||
|  |         // we want to allow link to preserve URLs: https://github.com/zadam/trilium/issues/2412
 | ||||||
|  |         // we want to insert space in place of block tags (because they imply text separation)
 | ||||||
|  |         // but we don't want to insert text for typical formatting inline tags which can occur within one word
 | ||||||
|  |         const linkTag = 'a'; | ||||||
|  |         const inlineFormattingTags = ['b', 'strong', 'em', 'i', 'span', 'big', 'small', 'font', 'sub', 'sup']; | ||||||
|  | 
 | ||||||
|  |         // replace tags which imply text separation with a space
 | ||||||
|  |         content = striptags(content, [linkTag, ...inlineFormattingTags], ' '); | ||||||
|  | 
 | ||||||
|  |         // replace the inline formatting tags (but not links) without a space
 | ||||||
|  |         content = striptags(content, [linkTag], ''); | ||||||
|  | 
 | ||||||
|  |         // at least the closing link tag can be easily stripped
 | ||||||
|  |         return content.replace(/<\/a>/ig, ""); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = NoteContentFulltextExp; | module.exports = NoteContentFulltextExp; | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ class TaskContext { | |||||||
|                 type: 'taskProgressCount', |                 type: 'taskProgressCount', | ||||||
|                 taskId: this.taskId, |                 taskId: this.taskId, | ||||||
|                 taskType: this.taskType, |                 taskType: this.taskType, | ||||||
|                 data: this.data || undefined, |                 data: this.data, | ||||||
|                 progressCount: this.progressCount |                 progressCount: this.progressCount | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| @ -60,7 +60,7 @@ class TaskContext { | |||||||
|             type: 'taskError', |             type: 'taskError', | ||||||
|             taskId: this.taskId, |             taskId: this.taskId, | ||||||
|             taskType: this.taskType, |             taskType: this.taskType, | ||||||
|             data: this.data || undefined, |             data: this.data, | ||||||
|             message: message |             message: message | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| @ -70,7 +70,7 @@ class TaskContext { | |||||||
|             type: 'taskSucceeded', |             type: 'taskSucceeded', | ||||||
|             taskId: this.taskId, |             taskId: this.taskId, | ||||||
|             taskType: this.taskType, |             taskType: this.taskType, | ||||||
|             data: this.data || undefined, |             data: this.data, | ||||||
|             result: result |             result: result | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -29,10 +29,10 @@ let lastSyncedPush: number | null = null; | |||||||
| interface Message { | interface Message { | ||||||
|     type: string; |     type: string; | ||||||
|     data?: { |     data?: { | ||||||
|         lastSyncedPush?: number, |         lastSyncedPush?: number | null, | ||||||
|         entityChanges?: any[] |         entityChanges?: any[] | ||||||
|     }, |     } | null, | ||||||
|     lastSyncedPush?: number, |     lastSyncedPush?: number | null, | ||||||
|      |      | ||||||
|     progressCount?: number; |     progressCount?: number; | ||||||
|     taskId?: string; |     taskId?: string; | ||||||
| @ -142,7 +142,7 @@ function fillInAdditionalProperties(entityChange: EntityChange) { | |||||||
|         if (!entityChange.entity) { |         if (!entityChange.entity) { | ||||||
|             entityChange.entity = sql.getRow(`SELECT * FROM notes WHERE noteId = ?`, [entityChange.entityId]); |             entityChange.entity = sql.getRow(`SELECT * FROM notes WHERE noteId = ?`, [entityChange.entityId]); | ||||||
| 
 | 
 | ||||||
|             if (entityChange.entity && entityChange.entity.isProtected) { |             if (entityChange.entity?.isProtected) { | ||||||
|                 entityChange.entity.title = protectedSessionService.decryptString(entityChange.entity.title || ""); |                 entityChange.entity.title = protectedSessionService.decryptString(entityChange.entity.title || ""); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -157,7 +157,7 @@ function fillInAdditionalProperties(entityChange: EntityChange) { | |||||||
| 
 | 
 | ||||||
|         if (parentNote) { |         if (parentNote) { | ||||||
|             for (const childBranch of parentNote.getChildBranches()) { |             for (const childBranch of parentNote.getChildBranches()) { | ||||||
|                 if (childBranch && childBranch.branchId) { |                 if (childBranch?.branchId) { | ||||||
|                     entityChange.positions[childBranch.branchId] = childBranch.notePosition; |                     entityChange.positions[childBranch.branchId] = childBranch.notePosition; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -222,7 +222,7 @@ function sendPing(client: WebSocket, entityChangeIds = []) { | |||||||
|     sendMessage(client, { |     sendMessage(client, { | ||||||
|         type: 'frontend-update', |         type: 'frontend-update', | ||||||
|         data: { |         data: { | ||||||
|             lastSyncedPush: lastSyncedPush || undefined, |             lastSyncedPush, | ||||||
|             entityChanges |             entityChanges | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| @ -237,19 +237,19 @@ function sendTransactionEntityChangesToAllClients() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function syncPullInProgress() { | function syncPullInProgress() { | ||||||
|     sendMessageToAllClients({ type: 'sync-pull-in-progress', lastSyncedPush: lastSyncedPush || undefined }); |     sendMessageToAllClients({ type: 'sync-pull-in-progress', lastSyncedPush }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function syncPushInProgress() { | function syncPushInProgress() { | ||||||
|     sendMessageToAllClients({ type: 'sync-push-in-progress', lastSyncedPush: lastSyncedPush || undefined }); |     sendMessageToAllClients({ type: 'sync-push-in-progress', lastSyncedPush }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function syncFinished() { | function syncFinished() { | ||||||
|     sendMessageToAllClients({ type: 'sync-finished', lastSyncedPush: lastSyncedPush || undefined }); |     sendMessageToAllClients({ type: 'sync-finished', lastSyncedPush }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function syncFailed() { | function syncFailed() { | ||||||
|     sendMessageToAllClients({ type: 'sync-failed', lastSyncedPush: lastSyncedPush || undefined }); |     sendMessageToAllClients({ type: 'sync-failed', lastSyncedPush }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function reloadFrontend(reason: string) { | function reloadFrontend(reason: string) { | ||||||
|  | |||||||
| @ -105,10 +105,10 @@ function renderText(result, note) { | |||||||
| 
 | 
 | ||||||
|         if (result.content.includes(`<span class="math-tex">`)) { |         if (result.content.includes(`<span class="math-tex">`)) { | ||||||
|             result.header += ` |             result.header += ` | ||||||
| <script src="../../${assetPath}/node_modules/katex/dist/katex.min.js"></script> | <script src="../${assetPath}/node_modules/katex/dist/katex.min.js"></script> | ||||||
| <link rel="stylesheet" href="../../${assetPath}/node_modules/katex/dist/katex.min.css"> | <link rel="stylesheet" href="../${assetPath}/node_modules/katex/dist/katex.min.css"> | ||||||
| <script src="../../${assetPath}/node_modules/katex/dist/contrib/auto-render.min.js"></script> | <script src="../${assetPath}/node_modules/katex/dist/contrib/auto-render.min.js"></script> | ||||||
| <script src="../../${assetPath}/node_modules/katex/dist/contrib/mhchem.min.js"></script> | <script src="../${assetPath}/node_modules/katex/dist/contrib/mhchem.min.js"></script> | ||||||
| <script> | <script> | ||||||
| document.addEventListener("DOMContentLoaded", function() { | document.addEventListener("DOMContentLoaded", function() { | ||||||
|     renderMathInElement(document.getElementById('content')); |     renderMathInElement(document.getElementById('content')); | ||||||
|  | |||||||
| @ -3,11 +3,11 @@ | |||||||
|       "moduleResolution": "Node", |       "moduleResolution": "Node", | ||||||
| 	  "declaration": false, | 	  "declaration": false, | ||||||
| 	  "sourceMap": true, | 	  "sourceMap": true, | ||||||
| 	  "outDir": "./build", | 	  "outDir": "./dist", | ||||||
| 	  "strict": true, | 	  "strict": true, | ||||||
| 	  "noImplicitAny": true, | 	  "noImplicitAny": true, | ||||||
| 	  "resolveJsonModule": true, | 	  "resolveJsonModule": true, | ||||||
| 	  "lib": ["ES2021"], | 	  "lib": ["ES2022"], | ||||||
| 	  "downlevelIteration": true | 	  "downlevelIteration": true | ||||||
| 	}, | 	}, | ||||||
| 	"include": [ | 	"include": [ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran