mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 14:39:34 +01:00
feat: implement fluent api
This commit is contained in:
@@ -12,7 +12,7 @@ beforeEach(async () => {
|
|||||||
test("add a notebook", () =>
|
test("add a notebook", () =>
|
||||||
notebookTest().then(({ db, id }) => {
|
notebookTest().then(({ db, id }) => {
|
||||||
expect(id).toBeDefined();
|
expect(id).toBeDefined();
|
||||||
let notebook = db.notebooks.get(id);
|
let notebook = db.notebooks.notebook(id);
|
||||||
expect(notebook).toBeDefined();
|
expect(notebook).toBeDefined();
|
||||||
expect(notebook.title).toBe(TEST_NOTEBOOK.title);
|
expect(notebook.title).toBe(TEST_NOTEBOOK.title);
|
||||||
}));
|
}));
|
||||||
@@ -34,42 +34,46 @@ test("search all notebooks", () =>
|
|||||||
|
|
||||||
test("pin a notebook", () =>
|
test("pin a notebook", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
await db.notebooks.pin(id);
|
let notebook = db.notebooks.notebook(id);
|
||||||
let notebook = db.notebooks.get(id);
|
await notebook.pin();
|
||||||
expect(notebook.pinned).toBe(true);
|
expect(notebook.data.pinned).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("unpin a notebook", () =>
|
test("unpin a notebook", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
await db.notebooks.unpin(id);
|
let notebook = db.notebooks.notebook(id);
|
||||||
let notebook = db.notebooks.get(id);
|
await notebook.pin();
|
||||||
expect(notebook.pinned).toBe(false);
|
expect(notebook.data.pinned).toBe(true);
|
||||||
|
await notebook.pin();
|
||||||
|
expect(notebook.data.pinned).toBe(false);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("favorite a notebook", () =>
|
test("favorite a notebook", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
await db.notebooks.favorite(id);
|
let notebook = db.notebooks.notebook(id);
|
||||||
let notebook = db.notebooks.get(id);
|
await notebook.favorite();
|
||||||
expect(notebook.favorite).toBe(true);
|
expect(notebook.data.favorite).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("unfavorite a notebook", () =>
|
test("unfavorite a notebook", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
await db.notebooks.unfavorite(id);
|
let notebook = db.notebooks.notebook(id);
|
||||||
let notebook = db.notebooks.get(id);
|
await notebook.favorite();
|
||||||
expect(notebook.favorite).toBe(false);
|
expect(notebook.data.favorite).toBe(true);
|
||||||
|
await notebook.favorite();
|
||||||
|
expect(notebook.data.favorite).toBe(false);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("delete a notebook", () =>
|
test("delete a notebook", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
let noteId = await db.notes.add(TEST_NOTE);
|
let noteId = await db.notes.add(TEST_NOTE);
|
||||||
await db.notebooks
|
await db.notebooks
|
||||||
.topics(id)
|
.notebook(id)
|
||||||
.topic("General")
|
.topics.topic("General")
|
||||||
.add(noteId);
|
.add(noteId);
|
||||||
let note = await db.notes.get(noteId);
|
let note = db.notes.note(noteId);
|
||||||
expect(note.notebook.id).toBe(id);
|
expect(note.notebook.id).toBe(id);
|
||||||
await db.notebooks.delete(id);
|
await db.notebooks.delete(id);
|
||||||
note = await db.notes.get(noteId);
|
note = db.notes.note(noteId);
|
||||||
expect(note.notebook.id).toBeUndefined();
|
expect(note.notebook.id).toBeUndefined();
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ test("add invalid note", () =>
|
|||||||
|
|
||||||
test("add note", () =>
|
test("add note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note).toBeDefined();
|
expect(note.data).toBeDefined();
|
||||||
expect(note.content.text).toStrictEqual(TEST_NOTE.content.text);
|
expect(note.text).toStrictEqual(TEST_NOTE.content.text);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("get delta of note", () =>
|
test("get delta of note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let delta = await db.notes.delta(id);
|
let delta = await db.notes.note(id).delta();
|
||||||
expect(delta).toStrictEqual(TEST_NOTE.content.delta);
|
expect(delta).toStrictEqual(TEST_NOTE.content.delta);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -39,14 +39,12 @@ test("delete note", () =>
|
|||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let notebookId = await db.notebooks.add(TEST_NOTEBOOK);
|
let notebookId = await db.notebooks.add(TEST_NOTEBOOK);
|
||||||
let topic = await db.notebooks
|
let topic = await db.notebooks
|
||||||
.topics(notebookId)
|
.notebook(notebookId)
|
||||||
.topic("General")
|
.topics.topic("General")
|
||||||
.add(id);
|
.add(id);
|
||||||
expect(topic.all.findIndex(v => v.id === id)).toBeGreaterThan(-1);
|
expect(topic.all.findIndex(v => v.id === id)).toBeGreaterThan(-1);
|
||||||
await db.notes.delete(id);
|
await db.notes.delete(id);
|
||||||
let note = db.notes.get(id);
|
expect(db.notes.note(id)).toBeUndefined();
|
||||||
expect(await db.notes.delta(id)).toBeUndefined();
|
|
||||||
expect(note).toBeUndefined();
|
|
||||||
expect(topic.all.findIndex(v => v.id === id)).toBe(-1);
|
expect(topic.all.findIndex(v => v.id === id)).toBe(-1);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -65,7 +63,7 @@ test("search all notes", () =>
|
|||||||
|
|
||||||
test("note without a title should get title from content", () =>
|
test("note without a title should get title from content", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note.title).toBe("I am a");
|
expect(note.title).toBe("I am a");
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -83,11 +81,11 @@ test("update note", () =>
|
|||||||
// colors: ["red", "blue"]
|
// colors: ["red", "blue"]
|
||||||
};
|
};
|
||||||
id = await db.notes.add(noteData);
|
id = await db.notes.add(noteData);
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note.title).toBe(noteData.title);
|
expect(note.title).toBe(noteData.title);
|
||||||
expect(note.content.text).toStrictEqual(noteData.content.text);
|
expect(note.text).toStrictEqual(noteData.content.text);
|
||||||
expect(note.pinned).toBe(true);
|
expect(note.data.pinned).toBe(true);
|
||||||
expect(note.favorite).toBe(true);
|
expect(note.data.favorite).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("updating empty note should delete it", () =>
|
test("updating empty note should delete it", () =>
|
||||||
@@ -101,24 +99,26 @@ test("updating empty note should delete it", () =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
expect(id).toBeUndefined();
|
expect(id).toBeUndefined();
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note).toBeUndefined();
|
expect(note).toBeUndefined();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("add tag to note", () =>
|
test("add tag to note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
await db.notes.tag(id, "hello");
|
let note = db.notes.note(id);
|
||||||
expect(db.notes.get(id).tags[0]).toBe("hello");
|
await note.tag("hello");
|
||||||
|
expect(note.tags[0]).toBe("hello");
|
||||||
expect(db.notes.tags[0].title).toBe("hello");
|
expect(db.notes.tags[0].title).toBe("hello");
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("remove tag from note", () =>
|
test("remove tag from note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
await db.notes.tag(id, "hello");
|
let note = db.notes.note(id);
|
||||||
expect(db.notes.get(id).tags[0]).toBe("hello");
|
await note.tag("hello");
|
||||||
|
expect(note.tags[0]).toBe("hello");
|
||||||
expect(db.notes.tags[0].title).toBe("hello");
|
expect(db.notes.tags[0].title).toBe("hello");
|
||||||
await db.notes.untag(id, "hello");
|
await note.untag("hello");
|
||||||
expect(db.notes.get(id).tags.length).toBe(0);
|
expect(note.tags.length).toBe(0);
|
||||||
expect(db.notes.tags.length).toBe(0);
|
expect(db.notes.tags.length).toBe(0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ test("note with text longer than 150 characters should have ... in the headline"
|
|||||||
delta: []
|
delta: []
|
||||||
}
|
}
|
||||||
}).then(({ db, id }) => {
|
}).then(({ db, id }) => {
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note.headline.includes("...")).toBe(true);
|
expect(note.headline.includes("...")).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -192,45 +192,48 @@ test("get grouped notes default (special)", () => groupedTest("", true));
|
|||||||
|
|
||||||
test("pin note", () =>
|
test("pin note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
await db.notes.pin(id);
|
let note = db.notes.note(id);
|
||||||
expect(db.notes.get(id).pinned).toBe(true);
|
await note.pin();
|
||||||
|
expect(note.data.pinned).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("favorite note", () =>
|
test("favorite note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
await db.notes.favorite(id);
|
let note = db.notes.note(id);
|
||||||
expect(db.notes.get(id).favorite).toBe(true);
|
await note.favorite();
|
||||||
|
expect(note.data.favorite).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("lock and unlock note", () =>
|
test("lock and unlock note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
expect(await db.notes.lock(id, "password123")).toBe(true);
|
let note = db.notes.note(id);
|
||||||
let note = db.notes.get(id);
|
await note.lock("password123");
|
||||||
expect(note.locked).toBe(true);
|
expect(note.data.locked).toBe(true);
|
||||||
expect(note.content.iv).toBeDefined();
|
expect(note.data.content.iv).toBeDefined();
|
||||||
note = await db.notes.unlock(id, "password123");
|
note = await note.unlock("password123");
|
||||||
expect(note.id).toBe(id);
|
expect(note.id).toBe(id);
|
||||||
expect(note.content.text).toBe(TEST_NOTE.content.text);
|
expect(note.content.text).toBe(TEST_NOTE.content.text);
|
||||||
await db.notes.unlock(id, "password123", true);
|
note = db.notes.note(id);
|
||||||
note = db.notes.get(id);
|
await note.unlock("password123", true);
|
||||||
expect(note.locked).toBe(false);
|
note = db.notes.note(id);
|
||||||
|
expect(note.data.locked).toBe(false);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("add note to topic", () =>
|
test("add note to topic", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||||
let topics = db.notebooks.topics(notebookId);
|
let topics = db.notebooks.notebook(notebookId).topics;
|
||||||
let topic = await topics.add("Home");
|
let topic = await topics.add("Home");
|
||||||
await topic.add(id);
|
await topic.add(id);
|
||||||
expect(topic.all.length).toBe(1);
|
expect(topic.all.length).toBe(1);
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note.notebook.id).toBe(notebookId);
|
expect(note.notebook.id).toBe(notebookId);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
test("duplicate note to topic should not be added", () =>
|
test("duplicate note to topic should not be added", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||||
let topics = db.notebooks.topics(notebookId);
|
let topics = db.notebooks.notebook(notebookId).topics;
|
||||||
let topic = await topics.add("Home");
|
let topic = await topics.add("Home");
|
||||||
await topic.add(id);
|
await topic.add(id);
|
||||||
expect(topic.all.length).toBe(1);
|
expect(topic.all.length).toBe(1);
|
||||||
@@ -239,14 +242,14 @@ test("duplicate note to topic should not be added", () =>
|
|||||||
test("move note", () =>
|
test("move note", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||||
let topics = db.notebooks.topics(notebookId);
|
let topics = db.notebooks.notebook(notebookId).topics;
|
||||||
let topic = await topics.add("Home");
|
let topic = await topics.add("Home");
|
||||||
await topic.add(id);
|
await topic.add(id);
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
let notebookId2 = await db.notebooks.add({ title: "Hello2" });
|
let notebookId2 = await db.notebooks.add({ title: "Hello2" });
|
||||||
await db.notebooks.topics(notebookId2).add("Home2");
|
await db.notebooks.notebook(notebookId2).topics.add("Home2");
|
||||||
await db.notes.move({ id: notebookId2, topic: "Home2" }, id);
|
await db.notes.move({ id: notebookId2, topic: "Home2" }, id);
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note.notebook.id).toBe(notebookId2);
|
expect(note.notebook.id).toBe(notebookId2);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}));
|
}));
|
||||||
@@ -254,10 +257,10 @@ test("move note", () =>
|
|||||||
test("moving note to same notebook and topic should do nothing", () =>
|
test("moving note to same notebook and topic should do nothing", () =>
|
||||||
noteTest().then(async ({ db, id }) => {
|
noteTest().then(async ({ db, id }) => {
|
||||||
let notebookId = await db.notebooks.add({ title: "Hello" });
|
let notebookId = await db.notebooks.add({ title: "Hello" });
|
||||||
let topics = db.notebooks.topics(notebookId);
|
let topics = db.notebooks.notebook(notebookId).topics;
|
||||||
let topic = await topics.add("Home");
|
let topic = await topics.add("Home");
|
||||||
await topic.add(id);
|
await topic.add(id);
|
||||||
await db.notes.move({ id: notebookId, topic: "Home" }, id);
|
await db.notes.move({ id: notebookId, topic: "Home" }, id);
|
||||||
let note = db.notes.get(id);
|
let note = db.notes.note(id);
|
||||||
expect(note.notebook.id).toBe(notebookId);
|
expect(note.notebook.id).toBe(notebookId);
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ beforeEach(() => StorageInterface.clear());
|
|||||||
|
|
||||||
test("get empty topic", () =>
|
test("get empty topic", () =>
|
||||||
notebookTest().then(({ db, id }) => {
|
notebookTest().then(({ db, id }) => {
|
||||||
let topic = db.notebooks.topics(id).topic("General");
|
let topic = db.notebooks.notebook(id).topics.topic("General");
|
||||||
expect(topic.all.length).toBe(0);
|
expect(topic.all.length).toBe(0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ test("getting invalid topic should throw", () =>
|
|||||||
|
|
||||||
test("add topic to notebook", () =>
|
test("add topic to notebook", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
let topics = db.notebooks.topics(id);
|
let topics = db.notebooks.notebook(id).topics;
|
||||||
await topics.add("Home");
|
await topics.add("Home");
|
||||||
expect(topics.all.length).toBeGreaterThan(1);
|
expect(topics.all.length).toBeGreaterThan(1);
|
||||||
expect(topics.all.findIndex(v => v.title === "Home")).toBeGreaterThan(-1);
|
expect(topics.all.findIndex(v => v.title === "Home")).toBeGreaterThan(-1);
|
||||||
@@ -23,7 +23,7 @@ test("add topic to notebook", () =>
|
|||||||
|
|
||||||
test("duplicate topic to notebook should not be added", () =>
|
test("duplicate topic to notebook should not be added", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
let topics = db.notebooks.topics(id);
|
let topics = db.notebooks.notebook(id).topics;
|
||||||
await topics.add("Home");
|
await topics.add("Home");
|
||||||
let len = topics.all.length;
|
let len = topics.all.length;
|
||||||
await topics.add("Home");
|
await topics.add("Home");
|
||||||
@@ -32,7 +32,7 @@ test("duplicate topic to notebook should not be added", () =>
|
|||||||
|
|
||||||
test("get topic", () =>
|
test("get topic", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
let topics = db.notebooks.topics(id);
|
let topics = db.notebooks.notebook(id).topics;
|
||||||
let topic = await topics.add("Home");
|
let topic = await topics.add("Home");
|
||||||
let noteId = await db.notes.add({ content: { text: "Hello", delta: [] } });
|
let noteId = await db.notes.add({ content: { text: "Hello", delta: [] } });
|
||||||
await topic.add(noteId);
|
await topic.add(noteId);
|
||||||
@@ -41,7 +41,7 @@ test("get topic", () =>
|
|||||||
|
|
||||||
test("delete a topic", () =>
|
test("delete a topic", () =>
|
||||||
notebookTest().then(async ({ db, id }) => {
|
notebookTest().then(async ({ db, id }) => {
|
||||||
let topics = db.notebooks.topics(id);
|
let topics = db.notebooks.notebook(id).topics;
|
||||||
await topics.add("Home");
|
await topics.add("Home");
|
||||||
await topics.delete("Home");
|
await topics.delete("Home");
|
||||||
expect(topics.all.findIndex(v => v.title === "Home")).toBe(-1);
|
expect(topics.all.findIndex(v => v.title === "Home")).toBe(-1);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import CachedCollection from "../database/cached-collection";
|
import CachedCollection from "../database/cached-collection";
|
||||||
import fuzzysearch from "fuzzysearch";
|
import fuzzysearch from "fuzzysearch";
|
||||||
import Topics from "./topics";
|
import Notebook from "../models/notebook";
|
||||||
var tfun = require("transfun/transfun.js").tfun;
|
var tfun = require("transfun/transfun.js").tfun;
|
||||||
if (!tfun) {
|
if (!tfun) {
|
||||||
tfun = global.tfun;
|
tfun = global.tfun;
|
||||||
@@ -82,16 +82,18 @@ export default class Notebooks {
|
|||||||
return this.collection.getAllItems();
|
return this.collection.getAllItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
get(id) {
|
notebook(id) {
|
||||||
return this.collection.getItem(id);
|
let notebook = this.collection.getItem(id);
|
||||||
|
if (!notebook) return;
|
||||||
|
return new Notebook(this, notebook);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(...ids) {
|
async delete(...ids) {
|
||||||
for (let id of ids) {
|
for (let id of ids) {
|
||||||
let notebook = this.get(id);
|
let notebook = this.notebook(id);
|
||||||
if (!notebook) continue;
|
if (!notebook) continue;
|
||||||
await this.collection.transaction(() =>
|
await this.collection.transaction(() =>
|
||||||
this.topics(id).delete(...notebook.topics)
|
notebook.topics.delete(...notebook.topics.all)
|
||||||
);
|
);
|
||||||
await this.collection.removeItem(id);
|
await this.collection.removeItem(id);
|
||||||
}
|
}
|
||||||
@@ -103,23 +105,6 @@ export default class Notebooks {
|
|||||||
this.all
|
this.all
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
topics(id) {
|
|
||||||
return new Topics(this, this.notes, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pin(id) {
|
|
||||||
return this.add({ id, pinned: true });
|
|
||||||
}
|
|
||||||
unpin(id) {
|
|
||||||
return this.add({ id, pinned: false });
|
|
||||||
}
|
|
||||||
favorite(id) {
|
|
||||||
return this.add({ id, favorite: true });
|
|
||||||
}
|
|
||||||
unfavorite(id) {
|
|
||||||
return this.add({ id, favorite: false });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTopic(topic, notebookId) {
|
function makeTopic(topic, notebookId) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
} from "../utils/date";
|
} from "../utils/date";
|
||||||
import Storage from "../database/storage";
|
import Storage from "../database/storage";
|
||||||
import Notebooks from "./notebooks";
|
import Notebooks from "./notebooks";
|
||||||
|
import Note from "../models/note";
|
||||||
var tfun = require("transfun/transfun.js").tfun;
|
var tfun = require("transfun/transfun.js").tfun;
|
||||||
if (!tfun) {
|
if (!tfun) {
|
||||||
tfun = global.tfun;
|
tfun = global.tfun;
|
||||||
@@ -36,7 +37,7 @@ export default class Notes {
|
|||||||
if (!noteArg) return;
|
if (!noteArg) return;
|
||||||
|
|
||||||
let id = noteArg.id || Date.now().toString() + "_note";
|
let id = noteArg.id || Date.now().toString() + "_note";
|
||||||
let oldNote = this.get(id);
|
let oldNote = this.collection.getItem(id);
|
||||||
let note = {
|
let note = {
|
||||||
...oldNote,
|
...oldNote,
|
||||||
...noteArg
|
...noteArg
|
||||||
@@ -77,12 +78,10 @@ export default class Notes {
|
|||||||
return note.id;
|
return note.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delta(id) {
|
note(id) {
|
||||||
return await this.deltaStorage.read(id + "_delta");
|
let note = this.collection.getItem(id);
|
||||||
}
|
if (!note) return undefined;
|
||||||
|
return new Note(this, note);
|
||||||
get(id) {
|
|
||||||
return this.collection.getItem(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get all() {
|
get all() {
|
||||||
@@ -162,13 +161,13 @@ export default class Notes {
|
|||||||
|
|
||||||
async delete(...ids) {
|
async delete(...ids) {
|
||||||
for (let id of ids) {
|
for (let id of ids) {
|
||||||
let item = this.get(id);
|
let item = this.note(id);
|
||||||
if (!id) continue;
|
if (!item) continue;
|
||||||
if (item.notebook && item.notebook.id && item.notebook.topic) {
|
if (item.notebook && item.notebook.id && item.notebook.topic) {
|
||||||
await this.collection.transaction(() =>
|
await this.collection.transaction(() =>
|
||||||
this.notebooks
|
this.notebooks
|
||||||
.topics(item.notebook.id)
|
.notebook(item.notebook.id)
|
||||||
.topic(item.notebook.topic)
|
.topics.topic(item.notebook.topic)
|
||||||
.delete(id)
|
.delete(id)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -184,83 +183,18 @@ export default class Notes {
|
|||||||
return this.tagsCollection.all();
|
return this.tagsCollection.all();
|
||||||
}
|
}
|
||||||
|
|
||||||
async tag(id, tag) {
|
|
||||||
let note = await this.get(id);
|
|
||||||
if (!note)
|
|
||||||
throw new Error(`Couldn't add tag. No note found with id: ${id}.`);
|
|
||||||
note.tags.push(tag);
|
|
||||||
await this.tagsCollection.add(tag);
|
|
||||||
await this.collection.addItem(note);
|
|
||||||
}
|
|
||||||
|
|
||||||
async untag(id, tag) {
|
|
||||||
let note = await this.get(id);
|
|
||||||
if (!note)
|
|
||||||
throw new Error(`Couldn't add tag. No note found with id: ${id}.`);
|
|
||||||
if (note.tags.indexOf(tag) <= -1)
|
|
||||||
throw new Error("This note is not tagged by the specified tag.");
|
|
||||||
note.tags.splice(note.tags.indexOf(tag), 1);
|
|
||||||
await this.tagsCollection.remove(tag);
|
|
||||||
await this.collection.addItem(note);
|
|
||||||
}
|
|
||||||
|
|
||||||
async move(to, ...noteIds) {
|
async move(to, ...noteIds) {
|
||||||
if (!to) throw new Error("The destination notebook cannot be undefined.");
|
if (!to) throw new Error("The destination notebook cannot be undefined.");
|
||||||
if (!to.id || !to.topic)
|
if (!to.id || !to.topic)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"The destination notebook must contain notebookId and topic."
|
"The destination notebook must contain notebookId and topic."
|
||||||
);
|
);
|
||||||
let topic = this.notebooks.topics(to.id).topic(to.topic);
|
let topic = this.notebooks.notebook(to.id).topics.topic(to.topic);
|
||||||
if (!topic) throw new Error("No such topic exists.");
|
if (!topic) throw new Error("No such topic exists.");
|
||||||
await topic.transaction(async () => {
|
await topic.transaction(async () => {
|
||||||
await topic.add(...noteIds);
|
await topic.add(...noteIds);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async favorite(id) {
|
|
||||||
await this.add({ id, favorite: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
async unfavorite(id) {
|
|
||||||
await this.add({ id, favorite: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
async pin(id) {
|
|
||||||
await this.add({ id, pinned: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
async unpin(id) {
|
|
||||||
await this.add({ id, pinned: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
async lock(id, password) {
|
|
||||||
let note = await this.get(id);
|
|
||||||
if (!note)
|
|
||||||
throw new Error(`Couldn't lock note. No note found with id: ${id}.`);
|
|
||||||
note.content = await this.collection.indexer.encrypt(
|
|
||||||
password,
|
|
||||||
JSON.stringify(note.content)
|
|
||||||
);
|
|
||||||
note.locked = true;
|
|
||||||
await this.collection.addItem(note);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
async unlock(id, password, perm = false) {
|
|
||||||
let note = await this.get(id);
|
|
||||||
if (!note)
|
|
||||||
throw new Error(`Couldn't unlock note. No note found with id: ${id}.`);
|
|
||||||
let decrypted = await this.collection.indexer.decrypt(
|
|
||||||
password,
|
|
||||||
note.content
|
|
||||||
);
|
|
||||||
if (perm) {
|
|
||||||
note.locked = false;
|
|
||||||
note.content = JSON.parse(decrypted);
|
|
||||||
await this.collection.addItem(note);
|
|
||||||
}
|
|
||||||
return { ...note, content: JSON.parse(decrypted) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNoteEmpty(note) {
|
function isNoteEmpty(note) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import Notebooks from "./notebooks";
|
import Notebooks from "./notebooks";
|
||||||
import Notes from "./notes";
|
import Notes from "./notes";
|
||||||
|
import Topic from "../models/topic";
|
||||||
|
|
||||||
export default class Topics {
|
export default class Topics {
|
||||||
/**
|
/**
|
||||||
@@ -23,7 +24,7 @@ export default class Topics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get all() {
|
get all() {
|
||||||
return this.notebooks.get(this.notebookId).topics;
|
return this.notebooks.notebook(this.notebookId).data.topics;
|
||||||
}
|
}
|
||||||
|
|
||||||
topic(topic) {
|
topic(topic) {
|
||||||
@@ -35,7 +36,9 @@ export default class Topics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async delete(...topics) {
|
async delete(...topics) {
|
||||||
let notebook = this.notebooks.get(this.notebookId);
|
let notebook = this.notebooks.notebook(this.notebookId);
|
||||||
|
if (!notebook) return;
|
||||||
|
notebook = notebook.data;
|
||||||
for (let topic of topics) {
|
for (let topic of topics) {
|
||||||
if (!topic) continue;
|
if (!topic) continue;
|
||||||
let index = notebook.topics.findIndex(
|
let index = notebook.topics.findIndex(
|
||||||
@@ -53,77 +56,3 @@ export default class Topics {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Topic {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {Topics} topics
|
|
||||||
* @param {Object} topic
|
|
||||||
*/
|
|
||||||
constructor(topics, topic) {
|
|
||||||
this.topic = topic;
|
|
||||||
this.topics = topics;
|
|
||||||
this.transactionOpen = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction(ops, saveAfter = true) {
|
|
||||||
this.transactionOpen = true;
|
|
||||||
ops().then(() => {
|
|
||||||
this.transactionOpen = false;
|
|
||||||
});
|
|
||||||
if (!saveAfter) return this;
|
|
||||||
return this.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
has(noteId) {
|
|
||||||
return this.topic.notes.findIndex(n => n === noteId) > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
async add(...noteIds) {
|
|
||||||
for (let noteId of noteIds) {
|
|
||||||
let note = this.topics.notes.get(noteId);
|
|
||||||
if (this.has(noteId) || !note) return this;
|
|
||||||
|
|
||||||
this.topic.notes.push(noteId);
|
|
||||||
|
|
||||||
if (note.notebook && note.notebook.id && note.notebook.topic) {
|
|
||||||
if (
|
|
||||||
note.notebook.id === this.topics.notebookId &&
|
|
||||||
note.notebook.topic === this.topic.title
|
|
||||||
)
|
|
||||||
return this;
|
|
||||||
await this.topics.notebooks
|
|
||||||
.topics(note.notebook.id)
|
|
||||||
.topic(note.notebook.topic)
|
|
||||||
.delete(note.id);
|
|
||||||
}
|
|
||||||
await this.topics.notes.add({
|
|
||||||
id: noteId,
|
|
||||||
notebook: { id: this.topics.notebookId, topic: this.topic.title }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return await this.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
async delete(...noteIds) {
|
|
||||||
for (let noteId of noteIds) {
|
|
||||||
if (!this.has(noteId)) return this;
|
|
||||||
let index = this.topic.notes.findIndex(n => n === noteId);
|
|
||||||
this.topic.notes.splice(index, 1);
|
|
||||||
await this.topics.notes.add({
|
|
||||||
id: noteId,
|
|
||||||
notebook: {}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return await this.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
save() {
|
|
||||||
if (this.transactionOpen) return this;
|
|
||||||
return this.topics.add(this.topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
get all() {
|
|
||||||
return this.topic.notes.map(note => this.topics.notes.get(note));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
101
packages/core/models/note.js
Normal file
101
packages/core/models/note.js
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import Notes from "../collections/notes";
|
||||||
|
|
||||||
|
export default class Note {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Notes} notes
|
||||||
|
* @param {Object} note
|
||||||
|
*/
|
||||||
|
constructor(notes, note) {
|
||||||
|
this.note = note;
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
get data() {
|
||||||
|
return this.note;
|
||||||
|
}
|
||||||
|
|
||||||
|
get headline() {
|
||||||
|
return this.note.headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return this.note.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
get tags() {
|
||||||
|
return this.note.tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
get id() {
|
||||||
|
return this.note.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get notebook() {
|
||||||
|
return this.note.notebook;
|
||||||
|
}
|
||||||
|
|
||||||
|
get text() {
|
||||||
|
return this.note.content.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
delta() {
|
||||||
|
return this.notes.deltaStorage.read(this.note.id + "_delta");
|
||||||
|
}
|
||||||
|
|
||||||
|
async tag(tag) {
|
||||||
|
if (this.note.tags.indexOf(tag) > -1)
|
||||||
|
throw new Error("Cannot add a duplicate tag.");
|
||||||
|
this.note.tags.push(tag);
|
||||||
|
await this.notes.tagsCollection.add(tag);
|
||||||
|
await this.notes.collection.addItem(this.note);
|
||||||
|
}
|
||||||
|
|
||||||
|
async untag(tag) {
|
||||||
|
if (this.note.tags.indexOf(tag) <= -1)
|
||||||
|
throw new Error("This note is not tagged by the specified tag.");
|
||||||
|
this.note.tags.splice(this.note.tags.indexOf(tag), 1);
|
||||||
|
await this.notes.tagsCollection.remove(tag);
|
||||||
|
await this.notes.collection.addItem(this.note);
|
||||||
|
}
|
||||||
|
|
||||||
|
async save() {
|
||||||
|
await this.notes.add(this.note);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(prop) {
|
||||||
|
this.note[prop] = !this.note[prop];
|
||||||
|
return this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
favorite() {
|
||||||
|
return this.toggle("favorite");
|
||||||
|
}
|
||||||
|
|
||||||
|
pin() {
|
||||||
|
return this.toggle("pinned");
|
||||||
|
}
|
||||||
|
|
||||||
|
async lock(password) {
|
||||||
|
this.note.content = await this.notes.collection.indexer.encrypt(
|
||||||
|
password,
|
||||||
|
JSON.stringify(this.note.content)
|
||||||
|
);
|
||||||
|
this.note.locked = true;
|
||||||
|
return await this.notes.collection.addItem(this.note);
|
||||||
|
}
|
||||||
|
|
||||||
|
async unlock(password, perm = false) {
|
||||||
|
let decrypted = await this.notes.collection.indexer.decrypt(
|
||||||
|
password,
|
||||||
|
this.note.content
|
||||||
|
);
|
||||||
|
if (perm) {
|
||||||
|
this.note.locked = false;
|
||||||
|
this.note.content = JSON.parse(decrypted);
|
||||||
|
await this.notes.collection.addItem(this.note);
|
||||||
|
}
|
||||||
|
return { ...this.note, content: JSON.parse(decrypted) };
|
||||||
|
}
|
||||||
|
}
|
||||||
39
packages/core/models/notebook.js
Normal file
39
packages/core/models/notebook.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import Notebooks from "../collections/notebooks";
|
||||||
|
import Topics from "../collections/topics";
|
||||||
|
|
||||||
|
export default class Notebook {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Notebooks} notebooks
|
||||||
|
* @param {Object} notebook
|
||||||
|
*/
|
||||||
|
constructor(notebooks, notebook) {
|
||||||
|
this.notebook = notebook;
|
||||||
|
this.notebooks = notebooks;
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return this.notebook.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
get data() {
|
||||||
|
return this.notebook;
|
||||||
|
}
|
||||||
|
|
||||||
|
get topics() {
|
||||||
|
return new Topics(this.notebooks, this.notebooks.notes, this.notebook.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(prop) {
|
||||||
|
this.notebook[prop] = !this.notebook[prop];
|
||||||
|
return this.notebooks.add(this.notebook);
|
||||||
|
}
|
||||||
|
|
||||||
|
pin() {
|
||||||
|
return this.toggle("pinned");
|
||||||
|
}
|
||||||
|
|
||||||
|
favorite() {
|
||||||
|
return this.toggle("favorite");
|
||||||
|
}
|
||||||
|
}
|
||||||
75
packages/core/models/topic.js
Normal file
75
packages/core/models/topic.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import Topics from "../collections/topics";
|
||||||
|
|
||||||
|
export default class Topic {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Topics} topics
|
||||||
|
* @param {Object} topic
|
||||||
|
*/
|
||||||
|
constructor(topics, topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
this.topics = topics;
|
||||||
|
this.transactionOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction(ops, saveAfter = true) {
|
||||||
|
this.transactionOpen = true;
|
||||||
|
ops().then(() => {
|
||||||
|
this.transactionOpen = false;
|
||||||
|
});
|
||||||
|
if (!saveAfter) return this;
|
||||||
|
return this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
has(noteId) {
|
||||||
|
return this.topic.notes.findIndex(n => n === noteId) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(...noteIds) {
|
||||||
|
for (let noteId of noteIds) {
|
||||||
|
let note = this.topics.notes.note(noteId);
|
||||||
|
if (this.has(noteId) || !note) return this;
|
||||||
|
|
||||||
|
this.topic.notes.push(noteId);
|
||||||
|
|
||||||
|
if (note.notebook && note.notebook.id && note.notebook.topic) {
|
||||||
|
if (
|
||||||
|
note.notebook.id === this.topics.notebookId &&
|
||||||
|
note.notebook.topic === this.topic.title
|
||||||
|
)
|
||||||
|
return this;
|
||||||
|
await this.topics.notebooks
|
||||||
|
.topics(note.notebook.id)
|
||||||
|
.topic(note.notebook.topic)
|
||||||
|
.delete(note.id);
|
||||||
|
}
|
||||||
|
await this.topics.notes.add({
|
||||||
|
id: noteId,
|
||||||
|
notebook: { id: this.topics.notebookId, topic: this.topic.title }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return await this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(...noteIds) {
|
||||||
|
for (let noteId of noteIds) {
|
||||||
|
if (!this.has(noteId)) return this;
|
||||||
|
let index = this.topic.notes.findIndex(n => n === noteId);
|
||||||
|
this.topic.notes.splice(index, 1);
|
||||||
|
await this.topics.notes.add({
|
||||||
|
id: noteId,
|
||||||
|
notebook: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return await this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
if (this.transactionOpen) return this;
|
||||||
|
return this.topics.add(this.topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
get all() {
|
||||||
|
return this.topic.notes.map(note => this.topics.notes.note(note).note);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user