mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
parent
e60595f0de
commit
43e40bcf5a
@ -79,6 +79,8 @@ packages/app-cli/app/LinkSelector.js
|
|||||||
packages/app-cli/app/base-command.js
|
packages/app-cli/app/base-command.js
|
||||||
packages/app-cli/app/command-done.test.js
|
packages/app-cli/app/command-done.test.js
|
||||||
packages/app-cli/app/command-e2ee.js
|
packages/app-cli/app/command-e2ee.js
|
||||||
|
packages/app-cli/app/command-mkbook.js
|
||||||
|
packages/app-cli/app/command-mkbook.test.js
|
||||||
packages/app-cli/app/command-settingschema.js
|
packages/app-cli/app/command-settingschema.js
|
||||||
packages/app-cli/app/command-sync.js
|
packages/app-cli/app/command-sync.js
|
||||||
packages/app-cli/app/command-testing.js
|
packages/app-cli/app/command-testing.js
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -67,6 +67,8 @@ packages/app-cli/app/LinkSelector.js
|
|||||||
packages/app-cli/app/base-command.js
|
packages/app-cli/app/base-command.js
|
||||||
packages/app-cli/app/command-done.test.js
|
packages/app-cli/app/command-done.test.js
|
||||||
packages/app-cli/app/command-e2ee.js
|
packages/app-cli/app/command-e2ee.js
|
||||||
|
packages/app-cli/app/command-mkbook.js
|
||||||
|
packages/app-cli/app/command-mkbook.test.js
|
||||||
packages/app-cli/app/command-settingschema.js
|
packages/app-cli/app/command-settingschema.js
|
||||||
packages/app-cli/app/command-sync.js
|
packages/app-cli/app/command-sync.js
|
||||||
packages/app-cli/app/command-testing.js
|
packages/app-cli/app/command-testing.js
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const locale_1 = require("@joplin/lib/locale");
|
|
||||||
const registry_js_1 = require("@joplin/lib/registry.js");
|
|
||||||
class BaseCommand {
|
|
||||||
constructor() {
|
|
||||||
this.stdout_ = null;
|
|
||||||
this.prompt_ = null;
|
|
||||||
}
|
|
||||||
usage() {
|
|
||||||
throw new Error('Usage not defined');
|
|
||||||
}
|
|
||||||
encryptionCheck(item) {
|
|
||||||
if (item && item.encryption_applied)
|
|
||||||
throw new Error((0, locale_1._)('Cannot change encrypted item'));
|
|
||||||
}
|
|
||||||
description() {
|
|
||||||
throw new Error('Description not defined');
|
|
||||||
}
|
|
||||||
action(_args) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
throw new Error('Action not defined');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
compatibleUis() {
|
|
||||||
return ['cli', 'gui'];
|
|
||||||
}
|
|
||||||
supportsUi(ui) {
|
|
||||||
return this.compatibleUis().indexOf(ui) >= 0;
|
|
||||||
}
|
|
||||||
options() {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
hidden() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
enabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
cancellable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cancel() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () { });
|
|
||||||
}
|
|
||||||
name() {
|
|
||||||
const r = this.usage().split(' ');
|
|
||||||
return r[0];
|
|
||||||
}
|
|
||||||
setDispatcher(fn) {
|
|
||||||
this.dispatcher_ = fn;
|
|
||||||
}
|
|
||||||
dispatch(action) {
|
|
||||||
if (!this.dispatcher_)
|
|
||||||
throw new Error('Dispatcher not defined');
|
|
||||||
return this.dispatcher_(action);
|
|
||||||
}
|
|
||||||
setStdout(fn) {
|
|
||||||
this.stdout_ = fn;
|
|
||||||
}
|
|
||||||
stdout(text) {
|
|
||||||
if (this.stdout_)
|
|
||||||
this.stdout_(text);
|
|
||||||
}
|
|
||||||
setPrompt(fn) {
|
|
||||||
this.prompt_ = fn;
|
|
||||||
}
|
|
||||||
prompt(message, options = null) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!this.prompt_)
|
|
||||||
throw new Error('Prompt is undefined');
|
|
||||||
return yield this.prompt_(message, options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
metadata() {
|
|
||||||
return {
|
|
||||||
name: this.name(),
|
|
||||||
usage: this.usage(),
|
|
||||||
options: this.options(),
|
|
||||||
hidden: this.hidden(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
logger() {
|
|
||||||
return registry_js_1.reg.logger();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = BaseCommand;
|
|
||||||
//# sourceMappingURL=base-command.js.map
|
|
@ -1,21 +0,0 @@
|
|||||||
const BaseCommand = require('./base-command').default;
|
|
||||||
const { app } = require('./app.js');
|
|
||||||
const { _ } = require('@joplin/lib/locale');
|
|
||||||
const Folder = require('@joplin/lib/models/Folder').default;
|
|
||||||
|
|
||||||
class Command extends BaseCommand {
|
|
||||||
usage() {
|
|
||||||
return 'mkbook <new-notebook>';
|
|
||||||
}
|
|
||||||
|
|
||||||
description() {
|
|
||||||
return _('Creates a new notebook.');
|
|
||||||
}
|
|
||||||
|
|
||||||
async action(args) {
|
|
||||||
const folder = await Folder.save({ title: args['new-notebook'] }, { userSideValidation: true });
|
|
||||||
app().switchCurrentFolder(folder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Command;
|
|
50
packages/app-cli/app/command-mkbook.test.ts
Normal file
50
packages/app-cli/app/command-mkbook.test.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||||
|
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
|
||||||
|
import Folder from '@joplin/lib/models/Folder';
|
||||||
|
const Command = require('./command-mkbook');
|
||||||
|
|
||||||
|
|
||||||
|
describe('command-mkbook', () => {
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await setupDatabaseAndSynchronizer(1);
|
||||||
|
await switchClient(1);
|
||||||
|
await setupApplication();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should create a subfolder in first folder', async () => {
|
||||||
|
const command = setupCommandForTesting(Command);
|
||||||
|
await command.action({ 'new-notebook': 'folder1', options: {} });
|
||||||
|
await command.action({ 'new-notebook': 'folder1_1', options: { parent: 'folder1' } });
|
||||||
|
|
||||||
|
const folder1 = await Folder.loadByTitle('folder1');
|
||||||
|
const folder1_1 = await Folder.loadByTitle('folder1_1');
|
||||||
|
|
||||||
|
expect(folder1.title).toBe('folder1');
|
||||||
|
expect(folder1_1.parent_id).toBe(folder1.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be possible to create a subfolder without an argument.', async () => {
|
||||||
|
const command = setupCommandForTesting(Command);
|
||||||
|
await command.action({ 'new-notebook': 'folder2', options: {} });
|
||||||
|
await expect(command.action({ 'new-notebook': 'folder2_1', options: { parent: true } })).rejects.toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be possible to create subfolder in ambiguous destination folder', async () => {
|
||||||
|
const command = setupCommandForTesting(Command);
|
||||||
|
await command.action({ 'new-notebook': 'folder3', options: {} });
|
||||||
|
await command.action({ 'new-notebook': 'folder3', options: {} }); // ambiguous folder
|
||||||
|
await expect(command.action({ 'new-notebook': 'folder3_1', options: { parent: 'folder3' } })).rejects.toThrowError();
|
||||||
|
|
||||||
|
// check if duplicate entries have been created.
|
||||||
|
const folderAll = await Folder.all();
|
||||||
|
const folders3 = folderAll.filter(x => x.title === 'folder3');
|
||||||
|
expect(folders3.length).toBe(2);
|
||||||
|
|
||||||
|
// check if something has been created in one of the duplicate entries.
|
||||||
|
expect(await Folder.childrenIds(folders3[0].id)).toEqual([]);
|
||||||
|
expect(await Folder.childrenIds(folders3[1].id)).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
65
packages/app-cli/app/command-mkbook.ts
Normal file
65
packages/app-cli/app/command-mkbook.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
const BaseCommand = require('./base-command').default;
|
||||||
|
const { app } = require('./app.js');
|
||||||
|
import { _ } from '@joplin/lib/locale';
|
||||||
|
import BaseModel from '@joplin/lib/BaseModel';
|
||||||
|
import Folder from '@joplin/lib/models/Folder';
|
||||||
|
import { FolderEntity } from '@joplin/lib/services/database/types';
|
||||||
|
|
||||||
|
class Command extends BaseCommand {
|
||||||
|
usage() {
|
||||||
|
return 'mkbook <new-notebook>';
|
||||||
|
}
|
||||||
|
|
||||||
|
description() {
|
||||||
|
return _('Creates a new notebook.');
|
||||||
|
}
|
||||||
|
|
||||||
|
options() {
|
||||||
|
return [
|
||||||
|
['-p, --parent <parent-notebook>', _('Create a new notebook under a parent notebook.')],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// validDestinationFolder check for presents and ambiguous folders
|
||||||
|
async validDestinationFolder(targetFolder: string) {
|
||||||
|
|
||||||
|
const destinationFolder = await app().loadItem(BaseModel.TYPE_FOLDER, targetFolder);
|
||||||
|
if (!destinationFolder) {
|
||||||
|
throw new Error(_('Cannot find: "%s"', targetFolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
const destinationDups = await Folder.search({ titlePattern: targetFolder, limit: 2 });
|
||||||
|
if (destinationDups.length > 1) {
|
||||||
|
throw new Error(_('Ambiguous notebook "%s". Please use short notebook id instead - press "ti" to see the short notebook id', targetFolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
return destinationFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveAndSwitchFolder(newFolder: FolderEntity) {
|
||||||
|
|
||||||
|
const folder = await Folder.save(newFolder, { userSideValidation: true });
|
||||||
|
app().switchCurrentFolder(folder);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async action(args: any) {
|
||||||
|
const targetFolder = args.options.parent;
|
||||||
|
|
||||||
|
const newFolder: FolderEntity = {
|
||||||
|
title: args['new-notebook'],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (targetFolder) {
|
||||||
|
|
||||||
|
const destinationFolder = await this.validDestinationFolder(targetFolder);
|
||||||
|
newFolder.parent_id = destinationFolder.id;
|
||||||
|
await this.saveAndSwitchFolder(newFolder);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
await this.saveAndSwitchFolder(newFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Command;
|
Loading…
Reference in New Issue
Block a user