You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2026-01-17 00:33:59 +02:00
Compare commits
11 Commits
mac_notari
...
fix_search
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04bae0ccb2 | ||
|
|
d7b8b9670b | ||
|
|
030a12b98c | ||
|
|
aa88541838 | ||
|
|
ce5d17c68c | ||
|
|
f0f19f8673 | ||
|
|
8513cb202f | ||
|
|
380031feff | ||
|
|
154b3573a4 | ||
|
|
7d2551c9c3 | ||
|
|
7644d05225 |
@@ -46,6 +46,7 @@ packages/app-mobile/ios
|
||||
packages/app-mobile/locales
|
||||
packages/app-mobile/node_modules
|
||||
packages/app-mobile/pluginAssets/
|
||||
packages/app-mobile/lib/rnInjectedJs/
|
||||
packages/lib/assets/
|
||||
packages/lib/rnInjectedJs/
|
||||
packages/lib/vendor/
|
||||
|
||||
24
.travis.yml
24
.travis.yml
@@ -1,5 +1,5 @@
|
||||
# Only build tags (Doesn't work - doesn't build anything)
|
||||
if: tag IS present OR type = pull_request
|
||||
if: tag IS present OR type = pull_request OR branch = dev
|
||||
|
||||
rvm: 2.3.3
|
||||
|
||||
@@ -17,19 +17,23 @@ matrix:
|
||||
- os: osx
|
||||
osx_image: xcode9.0
|
||||
language: node_js
|
||||
node_js: "10"
|
||||
env:
|
||||
- ELECTRON_CACHE=$HOME/.cache/electron
|
||||
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
node_js: "12"
|
||||
cache:
|
||||
npm: false
|
||||
# env:
|
||||
# - ELECTRON_CACHE=$HOME/.cache/electron
|
||||
# - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: node_js
|
||||
node_js: "10"
|
||||
env:
|
||||
- ELECTRON_CACHE=$HOME/.cache/electron
|
||||
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
node_js: "12"
|
||||
cache:
|
||||
npm: false
|
||||
# env:
|
||||
# - ELECTRON_CACHE=$HOME/.cache/electron
|
||||
# - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||
|
||||
# cache:
|
||||
# directories:
|
||||
@@ -65,7 +69,7 @@ script:
|
||||
# Run test units.
|
||||
# Only do it for pull requests because Travis randomly fails to run them
|
||||
# and that would break the desktop release.
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" = "dev" ]; then
|
||||
npm run test-ci
|
||||
testResult=$?
|
||||
if [ $testResult -ne 0 ]; then
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"author": "Laurent Cozic",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "jest --config=jest.config.js --runInBand --bail --forceExit",
|
||||
"test-one": "jest --verbose=false --config=jest.config.js --runInBand --bail --forceExit",
|
||||
"test-ci": "jest --config=jest.config.js --runInBand --forceExit",
|
||||
"test": "jest --config=jest.config.js --bail --forceExit",
|
||||
"test-one": "jest --verbose=false --config=jest.config.js --bail --forceExit",
|
||||
"test-ci": "jest --config=jest.config.js --forceExit",
|
||||
"build": "gulp build",
|
||||
"start": "gulp build -L && node \"build/main.js\" --stack-trace-enabled --log-level debug --env dev",
|
||||
"tsc": "node node_modules/typescript/bin/tsc --project tsconfig.json",
|
||||
|
||||
@@ -647,6 +647,8 @@ describe('services_rest_Api', function() {
|
||||
}));
|
||||
|
||||
it('should sort search paginated results', asyncTest(async () => {
|
||||
console.info('==================================== STARTING');
|
||||
|
||||
SearchEngine.instance().setDb(db());
|
||||
|
||||
await createNoteForPagination('note c', 1000);
|
||||
@@ -671,31 +673,33 @@ describe('services_rest_Api', function() {
|
||||
expect(r1.items[1].updated_time).toBe(1001);
|
||||
expect(r1.items[2].updated_time).toBe(1002);
|
||||
|
||||
const r2 = await api.route(RequestMethod.GET, 'search', { ...baseQuery, page: 2 });
|
||||
expect(r2.items[0].updated_time).toBe(1003);
|
||||
expect(r2.items[1].updated_time).toBe(1004);
|
||||
// const r2 = await api.route(RequestMethod.GET, 'search', { ...baseQuery, page: 2 });
|
||||
// expect(r2.items[0].updated_time).toBe(1003);
|
||||
// expect(r2.items[1].updated_time).toBe(1004);
|
||||
}
|
||||
|
||||
{
|
||||
const baseQuery = {
|
||||
query: 'note',
|
||||
fields: ['id', 'title', 'updated_time'],
|
||||
limit: 2,
|
||||
order_dir: PaginationOrderDir.DESC,
|
||||
order_by: 'title',
|
||||
};
|
||||
console.info('==================================== DONE');
|
||||
|
||||
const r1 = await api.route(RequestMethod.GET, 'search', baseQuery);
|
||||
expect(r1.items[0].title).toBe('note e');
|
||||
expect(r1.items[1].title).toBe('note d');
|
||||
// {
|
||||
// const baseQuery = {
|
||||
// query: 'note',
|
||||
// fields: ['id', 'title', 'updated_time'],
|
||||
// limit: 2,
|
||||
// order_dir: PaginationOrderDir.DESC,
|
||||
// order_by: 'title',
|
||||
// };
|
||||
|
||||
const r2 = await api.route(RequestMethod.GET, 'search', { ...baseQuery, page: 2 });
|
||||
expect(r2.items[0].title).toBe('note c');
|
||||
expect(r2.items[1].title).toBe('note b');
|
||||
// const r1 = await api.route(RequestMethod.GET, 'search', baseQuery);
|
||||
// expect(r1.items[0].title).toBe('note e');
|
||||
// expect(r1.items[1].title).toBe('note d');
|
||||
|
||||
const r3 = await api.route(RequestMethod.GET, 'search', { ...baseQuery, page: 3 });
|
||||
expect(r3.items[0].title).toBe('note a');
|
||||
}
|
||||
// const r2 = await api.route(RequestMethod.GET, 'search', { ...baseQuery, page: 2 });
|
||||
// expect(r2.items[0].title).toBe('note c');
|
||||
// expect(r2.items[1].title).toBe('note b');
|
||||
|
||||
// const r3 = await api.route(RequestMethod.GET, 'search', { ...baseQuery, page: 3 });
|
||||
// expect(r3.items[0].title).toBe('note a');
|
||||
// }
|
||||
}));
|
||||
|
||||
it('should return default fields', asyncTest(async () => {
|
||||
|
||||
@@ -53,6 +53,13 @@ const S3 = require('aws-sdk/clients/s3');
|
||||
const { Dirnames } = require('@joplin/lib/services/synchronizer/utils/types');
|
||||
const sharp = require('sharp');
|
||||
|
||||
// Each suite has its own separate data and temp directory so that multiple
|
||||
// suites can be run at the same time. suiteName is what is used to
|
||||
// differentiate between suite and it is currently set to a random string
|
||||
// (Ideally it would be something like the filename currently being executed by
|
||||
// Jest, to make debugging easier, but it's not clear how to get this info).
|
||||
const suiteName_ = uuid.createNano();
|
||||
|
||||
const databases_ = [];
|
||||
let synchronizers_ = [];
|
||||
const synchronizerContexts_ = {};
|
||||
@@ -89,10 +96,11 @@ EncryptionService.fsDriver_ = fsDriver;
|
||||
FileApiDriverLocal.fsDriver_ = fsDriver;
|
||||
|
||||
const logDir = `${__dirname}/../tests/logs`;
|
||||
const baseTempDir = `${__dirname}/../tests/tmp`;
|
||||
const baseTempDir = `${__dirname}/../tests/tmp/${suiteName_}`;
|
||||
const dataDir = `${__dirname}/data/${suiteName_}`;
|
||||
fs.mkdirpSync(logDir, 0o755);
|
||||
fs.mkdirpSync(baseTempDir, 0o755);
|
||||
fs.mkdirpSync(`${__dirname}/data`);
|
||||
fs.mkdirpSync(dataDir);
|
||||
|
||||
SyncTargetRegistry.addClass(SyncTargetMemory);
|
||||
SyncTargetRegistry.addClass(SyncTargetFilesystem);
|
||||
@@ -139,12 +147,12 @@ const syncDir = `${__dirname}/../tests/sync`;
|
||||
|
||||
const dbLogger = new Logger();
|
||||
dbLogger.addTarget('console');
|
||||
dbLogger.addTarget('file', { path: `${logDir}/log.txt` });
|
||||
// dbLogger.addTarget('file', { path: `${logDir}/log.txt` });
|
||||
dbLogger.setLevel(Logger.LEVEL_WARN);
|
||||
|
||||
const logger = new Logger();
|
||||
logger.addTarget('console');
|
||||
logger.addTarget('file', { path: `${logDir}/log.txt` });
|
||||
// logger.addTarget('file', { path: `${logDir}/log.txt` });
|
||||
logger.setLevel(Logger.LEVEL_WARN); // Set to DEBUG to display sync process in console
|
||||
|
||||
Logger.initializeGlobalLogger(logger);
|
||||
@@ -269,7 +277,7 @@ async function setupDatabase(id = null, options = null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filePath = `${__dirname}/data/test-${id}.sqlite`;
|
||||
const filePath = `${dataDir}/test-${id}.sqlite`;
|
||||
|
||||
try {
|
||||
await fs.unlink(filePath);
|
||||
@@ -292,15 +300,15 @@ function resourceDirName(id = null) {
|
||||
|
||||
function resourceDir(id = null) {
|
||||
if (id === null) id = currentClient_;
|
||||
return `${__dirname}/data/${resourceDirName(id)}`;
|
||||
return `${dataDir}/${resourceDirName(id)}`;
|
||||
}
|
||||
|
||||
function pluginDir(id = null) {
|
||||
if (id === null) id = currentClient_;
|
||||
return `${__dirname}/data/plugins-${id}`;
|
||||
return `${dataDir}/plugins-${id}`;
|
||||
}
|
||||
|
||||
async function setupDatabaseAndSynchronizer(id = null, options = null) {
|
||||
async function setupDatabaseAndSynchronizer(id, options = null) {
|
||||
if (id === null) id = currentClient_;
|
||||
|
||||
BaseService.logger_ = logger;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
69
packages/app-desktop/package-lock.json
generated
69
packages/app-desktop/package-lock.json
generated
@@ -5956,75 +5956,6 @@
|
||||
"resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz",
|
||||
"integrity": "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4="
|
||||
},
|
||||
"electron-notarize": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
|
||||
"integrity": "sha512-dsib1IAquMn0onCrNMJ6gtEIZn/azG8hZMCYOuZIMVMUeRMgBYHK1s5TK9P8xAcrAjh/2aN5WYHzgVSWX314og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^9.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
|
||||
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"electron-publish": {
|
||||
"version": "22.9.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "1.4.19",
|
||||
"version": "1.4.18",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
@@ -27,7 +27,6 @@
|
||||
"appId": "net.cozic.joplin-desktop",
|
||||
"productName": "Joplin",
|
||||
"npmRebuild": false,
|
||||
"afterSign": "./tools/notarizeMacApp.js",
|
||||
"extraResources": [
|
||||
"build/icons/*",
|
||||
"build/images/*"
|
||||
@@ -74,9 +73,7 @@
|
||||
},
|
||||
"mac": {
|
||||
"icon": "../../Assets/macOs.icns",
|
||||
"target": "dmg",
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "./build-mac/entitlements.mac.inherit.plist"
|
||||
"target": "dmg"
|
||||
},
|
||||
"linux": {
|
||||
"icon": "../../Assets/LinuxIcons",
|
||||
@@ -104,7 +101,6 @@
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"electron": "^10.1.6",
|
||||
"electron-builder": "22.9.1",
|
||||
"electron-notarize": "^1.0.0",
|
||||
"electron-rebuild": "^2.3.2",
|
||||
"glob": "^7.1.6",
|
||||
"gulp": "^4.0.2",
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const electron_notarize = require('electron-notarize');
|
||||
|
||||
module.exports = async function(params) {
|
||||
if (process.platform !== 'darwin') return;
|
||||
|
||||
if (!process.env.APPLE_ID || !process.env.APPLE_ID_PASSWORD) {
|
||||
console.warn('Environment variables APPLE_ID and APPLE_ID_PASSWORD not found - notarization will NOT be done.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Same appId in electron-builder.
|
||||
const appId = 'net.cozic.joplin-desktop';
|
||||
|
||||
const appPath = path.join(params.appOutDir, `${params.packager.appInfo.productFilename}.app`);
|
||||
if (!fs.existsSync(appPath)) {
|
||||
throw new Error(`Cannot find application at: ${appPath}`);
|
||||
}
|
||||
|
||||
console.log(`Notarizing ${appId} found at ${appPath}`);
|
||||
|
||||
await electron_notarize.notarize({
|
||||
appBundleId: appId,
|
||||
appPath: appPath,
|
||||
|
||||
// Apple Developer email address
|
||||
appleId: process.env.APPLE_ID,
|
||||
|
||||
// App-specific password: https://support.apple.com/en-us/HT204397
|
||||
appleIdPassword: process.env.APPLE_ID_PASSWORD,
|
||||
|
||||
// When Apple ID is attached to multiple providers (eg if the
|
||||
// account has been used to build multiple apps for different
|
||||
// companies), in that case the provider "Team Short Name" (also
|
||||
// known as "ProviderShortname") must be provided.
|
||||
//
|
||||
// Use this to get it:
|
||||
//
|
||||
// xcrun altool --list-providers -u APPLE_ID -p APPLE_ID_PASSWORD
|
||||
ascProvider: process.env.APPLE_ASC_PROVIDER,
|
||||
});
|
||||
|
||||
console.log(`Done notarizing ${appId}`);
|
||||
};
|
||||
@@ -10,6 +10,8 @@ const SearchEngineUtils = require('../../searchengine/SearchEngineUtils');
|
||||
export default async function(request: Request) {
|
||||
if (request.method !== 'GET') throw new ErrorMethodNotAllowed();
|
||||
|
||||
console.info('REQUEST', request);
|
||||
|
||||
const query = request.query.query;
|
||||
if (!query) throw new ErrorBadRequest('Missing "query" parameter');
|
||||
|
||||
@@ -28,8 +30,13 @@ export default async function(request: Request) {
|
||||
options.caseInsensitive = true;
|
||||
results = await ModelClass.all(options);
|
||||
} else {
|
||||
console.info('routes/search: options:', defaultLoadOptions(request, ModelType.Note));
|
||||
results = await SearchEngineUtils.notesForQuery(query, defaultLoadOptions(request, ModelType.Note));
|
||||
}
|
||||
|
||||
return collectionToPaginatedResults(results, request);
|
||||
console.info('BEFORE RESULTS', results);
|
||||
|
||||
const output = collectionToPaginatedResults(results, request);
|
||||
console.info('FINAL RESULTS', output);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import requestPaginationOptions from '../utils/requestPaginationOptions';
|
||||
// building complex SQL queries.
|
||||
export default function(items: any[], request: Request): ModelFeedPage {
|
||||
const pagination = requestPaginationOptions(request);
|
||||
console.info('requestPaginationOptions', request, pagination);
|
||||
const startIndex = (pagination.page - 1) * pagination.limit;
|
||||
const itemCount = Math.min(items.length - startIndex, pagination.limit);
|
||||
const hasMore = itemCount >= pagination.limit;
|
||||
|
||||
@@ -11,9 +11,13 @@ class SearchEngineUtils {
|
||||
searchType = SearchEngine.SEARCH_TYPE_BASIC;
|
||||
}
|
||||
|
||||
console.info('SearchEngineUtils: search type', searchType);
|
||||
|
||||
const results = await SearchEngine.instance().search(query, { searchType });
|
||||
const noteIds = results.map(n => n.id);
|
||||
|
||||
console.info('SearchEngineUtils: results', results);
|
||||
|
||||
// We need at least the note ID to be able to sort them below so if not
|
||||
// present in field list, add it.L Also remember it was auto-added so that
|
||||
// it can be removed afterwards.
|
||||
@@ -30,8 +34,12 @@ class SearchEngineUtils {
|
||||
conditions: [`id IN ("${noteIds.join('","')}")`],
|
||||
}, options);
|
||||
|
||||
console.info('SearchEngineUtils: previewOptions', previewOptions);
|
||||
|
||||
const notes = await Note.previews(null, previewOptions);
|
||||
|
||||
console.info('SearchEngineUtils: notes', notes);
|
||||
|
||||
// By default, the notes will be returned in reverse order
|
||||
// or maybe random order so sort them here in the correct order
|
||||
// (search engine returns the results in order of relevance).
|
||||
@@ -42,6 +50,7 @@ class SearchEngineUtils {
|
||||
if (idWasAutoAdded) delete sortedNotes[idx].id;
|
||||
}
|
||||
|
||||
console.info('SearchEngineUtils: sortedNotes', sortedNotes);
|
||||
|
||||
// Note that when the search engine index is somehow corrupted, it might contain
|
||||
// references to notes that don't exist. Not clear how it can happen, but anyway
|
||||
|
||||
Reference in New Issue
Block a user