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/command-done.test.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-sync.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/command-done.test.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-sync.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