From 6256e14b5fa6602f0fd2696c0f50501ccf940050 Mon Sep 17 00:00:00 2001 From: Simon Leigh Date: Mon, 9 Dec 2019 17:41:31 +0900 Subject: [PATCH] import from CSON file api --- package-lock.json | 12 +++++++ package.json | 1 + src/lib/legacy-import.ts | 72 ++++++++++++++++++++++++++++++++++++++++ src/lib/utils/files.ts | 11 ++++++ 4 files changed, 96 insertions(+) create mode 100644 src/lib/legacy-import.ts create mode 100644 src/lib/utils/files.ts diff --git a/package-lock.json b/package-lock.json index a51eb476d..4dddaa59c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3846,6 +3846,11 @@ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.49.0.tgz", "integrity": "sha512-Hyzr0HToBdZpLBN9dYFO/KlJAsKH37/cXVHPAqa+imml0R92tb9AkmsvjnXL+SluEvjjdfkDgRjc65NG5jnMYA==" }, + "coffeescript": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.4.1.tgz", + "integrity": "sha512-34GV1aHrsMpTaO3KfMJL40ZNuvKDR/g98THHnE9bQj8HjMaZvSrLik99WWqyMhRtbe8V5hpx5iLgdcSvM/S2wg==" + }, "collapse-white-space": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz", @@ -4338,6 +4343,13 @@ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" }, + "cson-parser": { + "version": "git+https://github.com/ButteryCrumpet/cson-parser.git#8d9e9d15ceabe2059459e699bb6c07c654c7bea0", + "from": "git+https://github.com/ButteryCrumpet/cson-parser.git", + "requires": { + "coffeescript": "^2.4.1" + } + }, "css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", diff --git a/package.json b/package.json index 177b29ba2..c6b95d5a4 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "classcat": "^4.0.2", "codemirror": "^5.49.0", "copy-webpack-plugin": "^5.0.4", + "cson-parser": "git+https://github.com/ButteryCrumpet/cson-parser.git", "dotenv": "^8.2.0", "filenamify": "^2.1.0", "hast-util-sanitize": "^2.0.1", diff --git a/src/lib/legacy-import.ts b/src/lib/legacy-import.ts new file mode 100644 index 000000000..d7d1686aa --- /dev/null +++ b/src/lib/legacy-import.ts @@ -0,0 +1,72 @@ +import { readAsText } from './utils/files' +import { parse } from 'cson-parser' +import ow from 'ow' + +type ParseErrors = 'read_error' | 'parse_error' | 'not_markdown' +type ParsedNote = { + content: string + tags: string[] + title: string +} +type ConvertResult = + | { err: true; data: ParseErrors } + | { err: false; data: ParsedNote } + +export const convertCSONFileToNote = async ( + file: File +): Promise => { + const text = await readFile(file) + + if (text === 'read_error') { + return { err: true, data: text } + } + + const parsed = await parseCSON(text) + + if (parsed === 'parse_error') { + return { err: true, data: parsed } + } + + const validated = validateNoteSchema(parsed) + + if (validated === 'parse_error') { + return { err: true, data: validated } + } + + const { type, content, title, tags } = validated + + if (type !== 'MARKDOWN_NOTE') { + return { err: true, data: 'not_markdown' } + } + + return { err: false, data: { content, title, tags } } +} + +const readFile = (file: File) => readAsText(file).catch(() => 'read_error') + +const parseCSON = (text: string) => { + try { + return parse(text) + } catch { + return 'parse_error' + } +} + +const validateNoteSchema = ( + obj: any +): ParsedNote & { type: string } | 'parse_error' => { + const validator = ow.object.partialShape({ + tags: ow.optional.array.ofType(ow.string), + content: ow.string, + title: ow.string, + type: ow.string + }) + + try { + ow(obj, validator) + return obj + } catch (e) { + console.log(e) + return 'parse_error' + } +} diff --git a/src/lib/utils/files.ts b/src/lib/utils/files.ts new file mode 100644 index 000000000..514791909 --- /dev/null +++ b/src/lib/utils/files.ts @@ -0,0 +1,11 @@ +export const readAsText = (file: File): Promise => { + return new Promise((res, rej) => { + const reader = new FileReader() + reader.onload = e => res(e.target!.result as string) + reader.onerror = () => { + reader.abort() + rej() + } + reader.readAsText(file) + }) +}