mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-29 10:09:26 +02:00
web: update importer to 2.6.0
This commit is contained in:
2132
apps/web/package-lock.json
generated
2132
apps/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
"@lingui/react": "5.1.2",
|
||||
"@mdi/js": "7.4.47",
|
||||
"@mdi/react": "1.6.1",
|
||||
"@notesnook-importer/core": "^2.4.5",
|
||||
"@notesnook-importer/core": "2.6.0",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
|
||||
121
apps/web/src/common/sqlite/importer-sqlite-adapter.ts
Normal file
121
apps/web/src/common/sqlite/importer-sqlite-adapter.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { wrap } from "comlink";
|
||||
import type { Remote } from "comlink";
|
||||
import type {
|
||||
SqlDatabase,
|
||||
SqliteAdapter,
|
||||
SqliteDatabaseFiles,
|
||||
SqlParams,
|
||||
SqlRow
|
||||
} from "@notesnook-importer/core";
|
||||
import SQLiteWorker from "./sqlite.worker?worker";
|
||||
import { IDBBatchAtomicVFS } from "./IDBBatchAtomicVFS";
|
||||
import SQLiteAsyncURI from "./wa-sqlite-async.wasm?url";
|
||||
|
||||
type ImporterWorkerAPI = {
|
||||
open(
|
||||
name: string,
|
||||
options: { async: boolean; url?: string; encrypted: boolean; skipExtensions?: boolean }
|
||||
): Promise<void>;
|
||||
run(
|
||||
mode: "query" | "exec" | "raw",
|
||||
sql: string,
|
||||
parameters?: unknown[]
|
||||
): Promise<{ rows: SqlRow[] }>;
|
||||
close(): Promise<void>;
|
||||
};
|
||||
|
||||
function toParams(params?: SqlParams): unknown[] | undefined {
|
||||
return Array.isArray(params) ? params : params ? Object.values(params) : undefined;
|
||||
}
|
||||
|
||||
class WorkerSqlDatabase implements SqlDatabase {
|
||||
constructor(
|
||||
private readonly worker: InstanceType<typeof SQLiteWorker>,
|
||||
private readonly api: Remote<ImporterWorkerAPI>,
|
||||
private readonly idbName: string
|
||||
) {}
|
||||
|
||||
async all<T = SqlRow>(sql: string, params?: SqlParams): Promise<T[]> {
|
||||
const result = await this.api.run("query", sql, toParams(params));
|
||||
return result.rows as T[];
|
||||
}
|
||||
|
||||
async get<T = SqlRow>(sql: string, params?: SqlParams): Promise<T | undefined> {
|
||||
const result = await this.api.run("query", sql, toParams(params));
|
||||
return result.rows[0] as T | undefined;
|
||||
}
|
||||
|
||||
close() {
|
||||
void this.api
|
||||
.close()
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
this.worker.terminate();
|
||||
try {
|
||||
indexedDB.deleteDatabase(this.idbName);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An SQLite adapter for Apple Notes / Apple Journal. Database files are
|
||||
* streamed into IndexedDB (via the `IDBBatchAtomicVFS` block format) on the
|
||||
* main thread — so large imports never load the files fully into memory — and
|
||||
* the existing `sqlite.worker.ts` is reused to open the database and run
|
||||
* queries. WAL data is replayed with exclusive locking, so no manual
|
||||
* checkpointing is needed.
|
||||
*/
|
||||
export class ImporterSqliteAdapter implements SqliteAdapter {
|
||||
async open(files: SqliteDatabaseFiles): Promise<SqlDatabase> {
|
||||
const name = `importer-${crypto.randomUUID()}`;
|
||||
const path = `/${name}`;
|
||||
|
||||
const vfs = new IDBBatchAtomicVFS(name, { durability: "strict" });
|
||||
try {
|
||||
await vfs.importFile(path, files.main);
|
||||
if (files.wal) await vfs.importFile(`${path}-wal`, files.wal);
|
||||
// The -shm file is intentionally skipped: it is only a cache of the WAL
|
||||
// index and its import breaks the Asyncify build. Exclusive locking makes
|
||||
// SQLite rebuild it in memory.
|
||||
} finally {
|
||||
await vfs.close();
|
||||
}
|
||||
|
||||
const worker = new SQLiteWorker();
|
||||
const api = wrap<ImporterWorkerAPI>(worker);
|
||||
await api.open(name, {
|
||||
async: true,
|
||||
encrypted: false,
|
||||
url: SQLiteAsyncURI,
|
||||
skipExtensions: true
|
||||
});
|
||||
|
||||
// WAL + exclusive locking (the same combination the Notesnook database
|
||||
// uses) replays the imported -wal file without needing a shared -shm.
|
||||
await api.run("exec", "PRAGMA locking_mode=EXCLUSIVE");
|
||||
|
||||
return new WorkerSqlDatabase(worker, api, name);
|
||||
}
|
||||
}
|
||||
@@ -18,23 +18,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
IFile,
|
||||
IFileProvider,
|
||||
ProviderSettings,
|
||||
transform
|
||||
} from "@notesnook-importer/core";
|
||||
import { formatBytes, getFormattedDate } from "@notesnook/common";
|
||||
import { ScrollContainer } from "@notesnook/ui";
|
||||
import { Button, Flex, Input, Text } from "@theme-ui/components";
|
||||
import { Button, Flex, Text } from "@theme-ui/components";
|
||||
import { xxhash64 } from "hash-wasm";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { importNote } from "../../../utils/importer";
|
||||
import { PromptDialog } from "../../../dialogs/prompt";
|
||||
import { ImporterSqliteAdapter } from "../../../common/sqlite/importer-sqlite-adapter";
|
||||
import Accordion from "../../accordion";
|
||||
import { TransformResult } from "../types";
|
||||
import { useStore as useAppStore } from "../../../stores/app-store";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { showFilePicker } from "../../../utils/file-picker";
|
||||
|
||||
type FileProviderHandlerProps = {
|
||||
provider: IFileProvider;
|
||||
@@ -63,20 +63,6 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
|
||||
const [_, setCounter] = useState<number>(0);
|
||||
const logs = useRef<LogMessage[]>([]);
|
||||
|
||||
const onDrop = useCallback((acceptedFiles: File[]) => {
|
||||
setFiles((files) => {
|
||||
const newFiles = [...acceptedFiles, ...files];
|
||||
return newFiles;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||
onDrop,
|
||||
accept: {
|
||||
file: provider?.supportedExtensions?.concat([".zip"])
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setFiles([]);
|
||||
}, [provider]);
|
||||
@@ -122,14 +108,15 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
|
||||
setTotalNoteCount(++totalNotes);
|
||||
},
|
||||
options: {
|
||||
onenote: {
|
||||
getPassword
|
||||
},
|
||||
colornote: {
|
||||
getPassword: async (filename: string) => {
|
||||
const password = await PromptDialog.show({
|
||||
title: strings.colorNotePasswordFor(filename),
|
||||
description: strings.colorNotPasswordForDesc()
|
||||
});
|
||||
return password || undefined;
|
||||
}
|
||||
getPassword
|
||||
},
|
||||
applenotes: {
|
||||
adapter: new ImporterSqliteAdapter(),
|
||||
getPassword
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -140,20 +127,24 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
|
||||
done: 0
|
||||
});
|
||||
|
||||
for (const file of files) {
|
||||
setFilesProgress((p) => ({
|
||||
...p,
|
||||
done: p.done + 1
|
||||
}));
|
||||
errors.push(
|
||||
...(await transform(
|
||||
provider,
|
||||
files.map((f) => ({
|
||||
name: f.name,
|
||||
modifiedAt: f.lastModified,
|
||||
size: f.size,
|
||||
data: f
|
||||
})),
|
||||
settings
|
||||
))
|
||||
);
|
||||
|
||||
setFilesProgress({
|
||||
total: files.length,
|
||||
done: files.length
|
||||
});
|
||||
|
||||
const providerFile: IFile = {
|
||||
name: file.name,
|
||||
modifiedAt: file.lastModified,
|
||||
size: file.size,
|
||||
data: file
|
||||
};
|
||||
errors.push(...(await transform(provider, [providerFile], settings)));
|
||||
}
|
||||
await useAppStore.getState().refresh();
|
||||
onTransformFinished({
|
||||
totalNotes,
|
||||
@@ -226,42 +217,53 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
|
||||
how to import from {provider?.name}.
|
||||
</a>
|
||||
</Text>
|
||||
<Flex
|
||||
{...getRootProps()}
|
||||
sx={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 100,
|
||||
border: "2px dashed var(--border)",
|
||||
borderRadius: "default",
|
||||
mt: 2,
|
||||
cursor: "pointer",
|
||||
":hover": {
|
||||
bg: "background-secondary"
|
||||
<Flex sx={{ mt: 1, gap: 1 }}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
showFilePicker({
|
||||
multiple: true,
|
||||
acceptedFileTypes: provider?.supportedExtensions
|
||||
?.concat([".zip"])
|
||||
.join(",")
|
||||
}).then((newFiles) => {
|
||||
setFiles((files) => {
|
||||
const _files = [...files, ...newFiles];
|
||||
return _files;
|
||||
});
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Input {...getInputProps()} />
|
||||
<Text variant="body" sx={{ textAlign: "center" }}>
|
||||
{isDragActive
|
||||
? "Drop the files here"
|
||||
: "Drag & drop files here, or click to select files"}
|
||||
<br />
|
||||
<Text variant="subBody">
|
||||
Only {provider?.supportedExtensions.join(", ")} files are supported.{" "}
|
||||
{provider?.supportedExtensions.includes(".zip") ? null : (
|
||||
<>
|
||||
You can also select .zip files containing{" "}
|
||||
{provider?.supportedExtensions.join(", ")} files.
|
||||
</>
|
||||
)}
|
||||
<br />
|
||||
{provider.examples ? (
|
||||
<>For example, {provider.examples.join(", ")}</>
|
||||
) : null}
|
||||
</Text>
|
||||
</Text>
|
||||
>
|
||||
{strings.selectFiles()}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
showFilePicker({
|
||||
directory: true
|
||||
}).then((newFiles) => {
|
||||
setFiles((files) => {
|
||||
const _files = [...files, ...newFiles];
|
||||
return _files;
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
{strings.selectFolder()}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Text variant="subBody" sx={{ mt: 1 }}>
|
||||
Only {provider?.supportedExtensions.join(", ")} files are supported.{" "}
|
||||
{provider?.supportedExtensions.includes(".zip") ? null : (
|
||||
<>
|
||||
You can also select .zip files containing{" "}
|
||||
{provider?.supportedExtensions.join(", ")} files.
|
||||
</>
|
||||
)}
|
||||
{provider.examples ? (
|
||||
<> For example, {provider.examples.join(", ")}</>
|
||||
) : null}
|
||||
</Text>
|
||||
|
||||
{files.length > 0 ? (
|
||||
<Accordion
|
||||
@@ -352,3 +354,11 @@ export function FileProviderHandler(props: FileProviderHandlerProps) {
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
async function getPassword(filename: string) {
|
||||
const password = await PromptDialog.show({
|
||||
title: strings.passwordFor(filename),
|
||||
type: "password"
|
||||
});
|
||||
return password || undefined;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ export type PromptDialogProps = BaseDialogProps<undefined | string> & {
|
||||
title: string;
|
||||
description?: string;
|
||||
defaultValue?: string;
|
||||
type?: "text" | "password" | "email" | "number";
|
||||
};
|
||||
|
||||
export const PromptDialog = DialogManager.register(function PromptDialog(
|
||||
@@ -51,6 +52,7 @@ export const PromptDialog = DialogManager.register(function PromptDialog(
|
||||
<Field
|
||||
inputRef={inputRef}
|
||||
defaultValue={props.defaultValue}
|
||||
type={props.type}
|
||||
autoFocus
|
||||
onKeyUp={(e) => {
|
||||
if (e.key == "Enter") props.onClose(inputRef.current?.value || "");
|
||||
|
||||
@@ -21,17 +21,26 @@ import { PAGE_VISIBILITY_CHANGE } from "./page-visibility";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { TaskManager } from "../common/task-manager";
|
||||
|
||||
type FilePickerOptions = { acceptedFileTypes: string; multiple?: boolean };
|
||||
type FilePickerOptions = {
|
||||
acceptedFileTypes?: string;
|
||||
multiple?: boolean;
|
||||
directory?: boolean;
|
||||
};
|
||||
|
||||
export async function showFilePicker({
|
||||
acceptedFileTypes,
|
||||
multiple
|
||||
multiple,
|
||||
directory
|
||||
}: FilePickerOptions): Promise<File[]> {
|
||||
PAGE_VISIBILITY_CHANGE.ignore = true;
|
||||
const input = document.createElement("input");
|
||||
input.setAttribute("type", "file");
|
||||
input.setAttribute("multiple", `${multiple || false}`);
|
||||
input.setAttribute("accept", acceptedFileTypes);
|
||||
if (acceptedFileTypes) input.setAttribute("accept", acceptedFileTypes);
|
||||
if (directory) {
|
||||
input.setAttribute("webkitdirectory", "true");
|
||||
input.setAttribute("directory", "true");
|
||||
}
|
||||
input.dispatchEvent(new MouseEvent("click"));
|
||||
const result = await TaskManager.startTask<File[]>({
|
||||
type: "modal",
|
||||
|
||||
144
packages/editor/package-lock.json
generated
144
packages/editor/package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/core": "^2.4.5",
|
||||
"@notesnook-importer/core": "^2.6.0",
|
||||
"@notesnook/common": "file:../common",
|
||||
"@notesnook/intl": "file:../intl",
|
||||
"@notesnook/theme": "file:../theme",
|
||||
@@ -105,6 +105,7 @@
|
||||
"version": "2.1.3",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook/common": "^2.1.3",
|
||||
"@notesnook/core": "file:../core",
|
||||
"@readme/data-urls": "^3.0.0",
|
||||
"dayjs": "1.11.13",
|
||||
@@ -982,15 +983,43 @@
|
||||
"integrity": "sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@notesnook-importer/core": {
|
||||
"version": "2.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.4.5.tgz",
|
||||
"integrity": "sha512-7Oqkw07CykwC/xzGrC6St4C/87QmXqK8UtmSxwE05fpz8DWoKEviJSWFa5fKY52umTphGvmtY23252dZ9J9EJg==",
|
||||
"node_modules/@notesnook-importer/applenotes": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/applenotes/-/applenotes-1.1.0.tgz",
|
||||
"integrity": "sha512-6mV6QtYqNqomyHJsWA926I1X8BsoM/6R3X8cdF7d4sg5cfkjENt2hoayBiW1ONK92MM9rU6mbJlqDSDEDinXPg==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/enex": "^2.3.5",
|
||||
"@notesnook-importer/storage": "^2.3.5",
|
||||
"@notesnook-importer/znel": "^2.3.5",
|
||||
"@notesnook-importer/types": "^1.1.0",
|
||||
"entities": "^4.4.0",
|
||||
"fflate": "^0.7.4",
|
||||
"protobufjs": "^8.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/applenotes/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/core": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.6.0.tgz",
|
||||
"integrity": "sha512-HjVvNgH6hFDMM/m3i+7GNDLMfcqAvNessDMS+JBWp70k8w8m1KltkVL2E6bng/zRRG6hisJJMSQzFOwpTBS2Ag==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/applenotes": "^1.1.0",
|
||||
"@notesnook-importer/enex": "^2.5.0",
|
||||
"@notesnook-importer/onenote": "^1.1.0",
|
||||
"@notesnook-importer/samsung-notes": "^1.1.0",
|
||||
"@notesnook-importer/storage": "^2.5.0",
|
||||
"@notesnook-importer/types": "^1.1.0",
|
||||
"@notesnook-importer/znel": "^2.5.0",
|
||||
"@stablelib/chacha20poly1305": "^1.0.1",
|
||||
"@streamparser/json": "^0.0.10",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
@@ -1004,6 +1033,7 @@
|
||||
"hast-util-is-element": "^2.1.3",
|
||||
"htmlparser2": "^8.0.1",
|
||||
"magic-bytes.js": "^1.8.0",
|
||||
"plist": "^5.0.0",
|
||||
"rehype-stringify": "^9.0.3",
|
||||
"remark": "^14.0.3",
|
||||
"remark-comments": "^1.2.9",
|
||||
@@ -1012,6 +1042,7 @@
|
||||
"remark-rehype": "^10.1.0",
|
||||
"remark-supersub": "^1.0.0",
|
||||
"spark-md5": "^3.0.2",
|
||||
"sql.js": "^1.14.2",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"varint": "^6.0.0",
|
||||
@@ -1031,9 +1062,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/enex": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/enex/-/enex-2.3.5.tgz",
|
||||
"integrity": "sha512-0+08XVhsQQFoEUrar3k07DuTluNho/FHxJ25n/DT+ug8kVraHHVqI40a2P9h8bW8iWxYs02Zq1n+N2uTv5qb+g==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/enex/-/enex-2.5.0.tgz",
|
||||
"integrity": "sha512-oqlg0SCqwTDmqGdi/p6m5FpcaKspIhDG08g/2fm2xIAYH95WJlyS4nb4pygyJGsywrq1USgIQ/Bup9hZ4jJKeA==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.5.1",
|
||||
@@ -1045,16 +1076,40 @@
|
||||
"spark-md5": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/onenote": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/onenote/-/onenote-1.1.0.tgz",
|
||||
"integrity": "sha512-V0cFx4QsC873wJsh5ONNG/pTAdTN+9LBYIAEIi+U6ZubTfm8Y2zIn/eBabVpFO62OvdD551EcFIbto5CTGJOrg==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"fflate": "^0.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/samsung-notes": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/samsung-notes/-/samsung-notes-1.1.0.tgz",
|
||||
"integrity": "sha512-2/2WbDqBBYQ46qkpPf4M5mdgHgSsjBlyTxWQsr0jv5l2j9TedxKE6NwmMxlrRJFkLxNBnNw3Yj1E437h7AJpqA==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"fflate": "^0.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/storage": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/storage/-/storage-2.3.5.tgz",
|
||||
"integrity": "sha512-orvSK0XIcqlmiWmjQ3RzS3qZp7viBdCpAloX557Ml200LMSMGDsOtofYNv5IYllBETnqApERLPQaUzBSuviuvA==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/storage/-/storage-2.5.0.tgz",
|
||||
"integrity": "sha512-7HpvJkafCs3Ba0DdzZA8QecLfdN7D7V3g4773/iwTsRxa07YTRcavmV2jBGY6DuMaTkJio/Q/M/kSI0m5yiU6A==",
|
||||
"license": "GPL-3.0-or-later"
|
||||
},
|
||||
"node_modules/@notesnook-importer/types": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/types/-/types-1.1.0.tgz",
|
||||
"integrity": "sha512-hoS4jHoaXiFnbUTElxYdIY85BOqf1wke0B+Oe5ExbHuFdUDOI0AtZWyCwArG9t0vfUlYmhJ1v27QHOfeE1kxQQ==",
|
||||
"license": "GPL-3.0-or-later"
|
||||
},
|
||||
"node_modules/@notesnook-importer/znel": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/znel/-/znel-2.3.5.tgz",
|
||||
"integrity": "sha512-s1kTA3EQ5OswBc0RvWnWgIm6/mIWvnh3iWmcOJcApIqhDwQziEkYiS+UMfuY9nOUyIWtepMe/WJ0Odk15uah9w==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/znel/-/znel-2.5.0.tgz",
|
||||
"integrity": "sha512-8Tx+fcAPJQeyjJpk9+mrak4c+v186IExgpy16I25fRJwl35k5B77NS0gWNOCFX80levInoX8FoXNp8IanVb8Rg==",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.5.1",
|
||||
@@ -2299,6 +2354,15 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.9.11",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.11.tgz",
|
||||
"integrity": "sha512-tW8bcK3hsG0/uqSnNz6TK4BkcuZSezoU7DlnYssILmZDktPnSHHuDJJFM0AJv+13gz2r0iGdrj6qqKeUnxXEDg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@zip.js/zip.js": {
|
||||
"version": "2.7.57",
|
||||
"resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.57.tgz",
|
||||
@@ -3528,6 +3592,12 @@
|
||||
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz",
|
||||
"integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg=="
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/longest-streak": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
|
||||
@@ -4764,6 +4834,19 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/plist": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/plist/-/plist-5.0.0.tgz",
|
||||
"integrity": "sha512-20N+g1DvMm/DFRbsvER7tT4wDryq0WunK7VMkDaiJcKNapAnUMkTsAnacFYf8n420F4Hf6/hefgmJRkMb1M0fg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.10",
|
||||
"xmlbuilder": "^15.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
|
||||
@@ -5047,6 +5130,18 @@
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "8.7.2",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.7.2.tgz",
|
||||
"integrity": "sha512-oTVHV+oelUBtiu5iTuTNNZ0eLYsXSMxry4cgr30mayNkgIZL6qZ0IOQVPuSWGcyAaXKl/XgqwWHIC3a0khYVBA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"long": "^5.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pstree.remy": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||
@@ -5500,6 +5595,12 @@
|
||||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/sql.js": {
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.14.2.tgz",
|
||||
"integrity": "sha512-3ZGPovObMFrdw79zrUHbfdE/DLIsy8jdNdssmMSQuRAymedU6q84asPt0kgiqrdMYlPegDItiIMfmIXzZnYFcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stackback": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
|
||||
@@ -6208,6 +6309,15 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "15.1.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
||||
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/core": "^2.4.5",
|
||||
"@notesnook-importer/core": "^2.6.0",
|
||||
"@notesnook/common": "file:../common",
|
||||
"@notesnook/intl": "file:../intl",
|
||||
"@notesnook/theme": "file:../theme",
|
||||
|
||||
@@ -812,7 +812,7 @@ msgstr "Align left"
|
||||
msgid "Align right"
|
||||
msgstr "Align right"
|
||||
|
||||
#: src/strings.ts:2813
|
||||
#: src/strings.ts:2809
|
||||
msgid "Alignment"
|
||||
msgstr "Alignment"
|
||||
|
||||
@@ -1358,6 +1358,10 @@ msgstr "Boost your productivity with Notebooks and organize your notes."
|
||||
msgid "Browse"
|
||||
msgstr "Browse"
|
||||
|
||||
#: src/strings.ts:2811
|
||||
msgid "Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space."
|
||||
msgstr "Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space."
|
||||
|
||||
#: src/strings.ts:2286
|
||||
msgid "Bullet list"
|
||||
msgstr "Bullet list"
|
||||
@@ -1662,7 +1666,7 @@ msgstr "Clear data & reset account"
|
||||
msgid "Clear default notebook"
|
||||
msgstr "Clear default notebook"
|
||||
|
||||
#: src/strings.ts:2803
|
||||
#: src/strings.ts:2799
|
||||
msgid "Clear history"
|
||||
msgstr "Clear history"
|
||||
|
||||
@@ -1821,10 +1825,6 @@ msgstr "Color scheme"
|
||||
msgid "Color title"
|
||||
msgstr "Color title"
|
||||
|
||||
#: src/strings.ts:2796
|
||||
msgid "Colornote password for {filename}"
|
||||
msgstr "Colornote password for {filename}"
|
||||
|
||||
#: src/strings.ts:309
|
||||
msgid "colors"
|
||||
msgstr "colors"
|
||||
@@ -2314,7 +2314,7 @@ msgstr "Delete account"
|
||||
msgid "Delete all"
|
||||
msgstr "Delete all"
|
||||
|
||||
#: src/strings.ts:2805
|
||||
#: src/strings.ts:2801
|
||||
msgid "Delete all version history for this note?"
|
||||
msgstr "Delete all version history for this note?"
|
||||
|
||||
@@ -2338,7 +2338,7 @@ msgstr "Delete data"
|
||||
msgid "Delete group"
|
||||
msgstr "Delete group"
|
||||
|
||||
#: src/strings.ts:2799
|
||||
#: src/strings.ts:2795
|
||||
msgid "Delete item"
|
||||
msgstr "Delete item"
|
||||
|
||||
@@ -2809,6 +2809,10 @@ msgstr "Enter notebook title"
|
||||
msgid "Enter password"
|
||||
msgstr "Enter password"
|
||||
|
||||
#: src/strings.ts:2812
|
||||
msgid "Enter password for {filename}"
|
||||
msgstr "Enter password for {filename}"
|
||||
|
||||
#: src/strings.ts:2100
|
||||
msgid "Enter pin or password to enable app lock."
|
||||
msgstr "Enter pin or password to enable app lock."
|
||||
@@ -3844,7 +3848,7 @@ msgstr "Keep"
|
||||
msgid "Keep open"
|
||||
msgstr "Keep open"
|
||||
|
||||
#: src/strings.ts:2800
|
||||
#: src/strings.ts:2796
|
||||
msgid "Keep screen on"
|
||||
msgstr "Keep screen on"
|
||||
|
||||
@@ -4737,7 +4741,7 @@ msgstr "Off"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: src/strings.ts:2810
|
||||
#: src/strings.ts:2806
|
||||
msgid "Offline mode"
|
||||
msgstr "Offline mode"
|
||||
|
||||
@@ -5223,7 +5227,7 @@ msgstr "Pressing \"X\" will hide the app in your system tray."
|
||||
msgid "Prevent note title from appearing in tab/window title."
|
||||
msgstr "Prevent note title from appearing in tab/window title."
|
||||
|
||||
#: src/strings.ts:2802
|
||||
#: src/strings.ts:2798
|
||||
msgid "Prevent the screen from turning off while the editor is focused."
|
||||
msgstr "Prevent the screen from turning off while the editor is focused."
|
||||
|
||||
@@ -6152,8 +6156,12 @@ msgid "Select day of the week to repeat the reminder."
|
||||
msgstr "Select day of the week to repeat the reminder."
|
||||
|
||||
#: src/strings.ts:1765
|
||||
msgid "Select files to import"
|
||||
msgstr "Select files to import"
|
||||
msgid "Select files"
|
||||
msgstr "Select files"
|
||||
|
||||
#: src/strings.ts:2813
|
||||
msgid "Select folder"
|
||||
msgstr "Select folder"
|
||||
|
||||
#: src/strings.ts:1608
|
||||
msgid "Select folder where Notesnook backup files are stored to view and restore them from the app"
|
||||
@@ -6924,10 +6932,6 @@ msgstr "The information above will be publically available at"
|
||||
msgid "The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits."
|
||||
msgstr "The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits."
|
||||
|
||||
#: src/strings.ts:2798
|
||||
msgid "The password for decrypting the Colornote backup file."
|
||||
msgstr "The password for decrypting the Colornote backup file."
|
||||
|
||||
#: src/strings.ts:2094
|
||||
msgid "The password/pin for unlocking the app."
|
||||
msgstr "The password/pin for unlocking the app."
|
||||
@@ -7493,7 +7497,7 @@ msgstr "User verification failed"
|
||||
msgid "Using {instance} (v{version})"
|
||||
msgstr "Using {instance} (v{version})"
|
||||
|
||||
#: src/strings.ts:2812
|
||||
#: src/strings.ts:2808
|
||||
msgid "Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly."
|
||||
msgstr "Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly."
|
||||
|
||||
@@ -7565,7 +7569,7 @@ msgstr "Verifying your email"
|
||||
msgid "Version"
|
||||
msgstr "Version"
|
||||
|
||||
#: src/strings.ts:2804
|
||||
#: src/strings.ts:2800
|
||||
msgid "Version history cleared"
|
||||
msgstr "Version history cleared"
|
||||
|
||||
|
||||
@@ -812,7 +812,7 @@ msgstr ""
|
||||
msgid "Align right"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2813
|
||||
#: src/strings.ts:2809
|
||||
msgid "Alignment"
|
||||
msgstr ""
|
||||
|
||||
@@ -1358,6 +1358,10 @@ msgstr ""
|
||||
msgid "Browse"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2811
|
||||
msgid "Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2286
|
||||
msgid "Bullet list"
|
||||
msgstr ""
|
||||
@@ -1662,7 +1666,7 @@ msgstr ""
|
||||
msgid "Clear default notebook"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2803
|
||||
#: src/strings.ts:2799
|
||||
msgid "Clear history"
|
||||
msgstr ""
|
||||
|
||||
@@ -1810,10 +1814,6 @@ msgstr ""
|
||||
msgid "Color title"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2796
|
||||
msgid "Colornote password for {filename}"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:309
|
||||
msgid "colors"
|
||||
msgstr ""
|
||||
@@ -2303,7 +2303,7 @@ msgstr ""
|
||||
msgid "Delete all"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2805
|
||||
#: src/strings.ts:2801
|
||||
msgid "Delete all version history for this note?"
|
||||
msgstr ""
|
||||
|
||||
@@ -2327,7 +2327,7 @@ msgstr ""
|
||||
msgid "Delete group"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2799
|
||||
#: src/strings.ts:2795
|
||||
msgid "Delete item"
|
||||
msgstr ""
|
||||
|
||||
@@ -2798,6 +2798,10 @@ msgstr ""
|
||||
msgid "Enter password"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2812
|
||||
msgid "Enter password for {filename}"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2100
|
||||
msgid "Enter pin or password to enable app lock."
|
||||
msgstr ""
|
||||
@@ -3824,7 +3828,7 @@ msgstr ""
|
||||
msgid "Keep open"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2800
|
||||
#: src/strings.ts:2796
|
||||
msgid "Keep screen on"
|
||||
msgstr ""
|
||||
|
||||
@@ -4711,7 +4715,7 @@ msgstr ""
|
||||
msgid "Offline"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2810
|
||||
#: src/strings.ts:2806
|
||||
msgid "Offline mode"
|
||||
msgstr ""
|
||||
|
||||
@@ -5197,7 +5201,7 @@ msgstr ""
|
||||
msgid "Prevent note title from appearing in tab/window title."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2802
|
||||
#: src/strings.ts:2798
|
||||
msgid "Prevent the screen from turning off while the editor is focused."
|
||||
msgstr ""
|
||||
|
||||
@@ -6126,7 +6130,11 @@ msgid "Select day of the week to repeat the reminder."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:1765
|
||||
msgid "Select files to import"
|
||||
msgid "Select files"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2813
|
||||
msgid "Select folder"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:1608
|
||||
@@ -6883,10 +6891,6 @@ msgstr ""
|
||||
msgid "The Notesnook Circle is exclusive to subscribers. Please consider subscribing to gain access to Notesnook Circle and enjoy additional benefits."
|
||||
msgstr "<<<<<<< HEAD"
|
||||
|
||||
#: src/strings.ts:2798
|
||||
msgid "The password for decrypting the Colornote backup file."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2094
|
||||
msgid "The password/pin for unlocking the app."
|
||||
msgstr ""
|
||||
@@ -7443,7 +7447,7 @@ msgstr ""
|
||||
msgid "Using {instance} (v{version})"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2812
|
||||
#: src/strings.ts:2808
|
||||
msgid "Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly."
|
||||
msgstr ""
|
||||
|
||||
@@ -7515,7 +7519,7 @@ msgstr ""
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:2804
|
||||
#: src/strings.ts:2800
|
||||
msgid "Version history cleared"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1762,7 +1762,7 @@ For example:
|
||||
one: "# file ready for import",
|
||||
other: "# files ready for import"
|
||||
}),
|
||||
selectFilesToImport: () => t`Select files to import`,
|
||||
selectFiles: () => t`Select files`,
|
||||
importerHelpText: () => [
|
||||
t`Please refer to the`,
|
||||
t`import guide`,
|
||||
@@ -2792,10 +2792,6 @@ Continue without attachments?`,
|
||||
enterPgpPublicKey: () => t`Enter your PGP public key`,
|
||||
enterPgpPrivateKey: () => t`Enter your PGP private key`,
|
||||
expiryDateRemoved: () => t`Expiry date removed`,
|
||||
colorNotePasswordFor: (filename: string) =>
|
||||
t`Colornote password for ${filename}`,
|
||||
colorNotPasswordForDesc: () =>
|
||||
t`The password for decrypting the Colornote backup file.`,
|
||||
deleteItem: () => t`Delete item`,
|
||||
keepScreenOn: () => t`Keep screen on`,
|
||||
keepScreenOnDesc: () =>
|
||||
@@ -2810,5 +2806,9 @@ Continue without attachments?`,
|
||||
offlineMode: () => t`Offline mode`,
|
||||
offlineModeDesc: () =>
|
||||
t`Using Notesnook without an account will **NOT** sync your notes across devices and could result in data loss if you lose access to your device or uninstall the app. Make sure to backup your notes regularly.`,
|
||||
alignment: () => t`Alignment`
|
||||
alignment: () => t`Alignment`,
|
||||
browserStorageQuotaReached: () =>
|
||||
t`Browser storage quota reached. Please delete some attachments from the attachment manager or clear some local data to free up space.`,
|
||||
passwordFor: (filename: string) => t`Enter password for ${filename}`,
|
||||
selectFolder: () => t`Select folder`
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user