From 4eb20ef4e75e9819ddcdb72968564f4ca79d25a1 Mon Sep 17 00:00:00 2001 From: Jia Xun Date: Sun, 28 Apr 2024 16:45:20 +0900 Subject: [PATCH 1/2] Run Linter --- .gitignore | 2 +- README.md | 20 ++--- jest.config.js | 8 +- src/anyBlock/blocks.ts | 114 ++++++++++++++-------------- src/anyBlock/config.ts | 104 +++++++++++++------------- src/anyBlock/convert.ts | 160 ++++++++++++++++++++-------------------- src/anyBlock/types.ts | 158 ++++++++++++++++++++------------------- src/anyBlock/write.ts | 16 ++-- src/cli.ts | 68 ++++++++--------- src/keep/ingest.ts | 90 +++++++++++----------- src/keep/types.ts | 42 +++++------ src/main.test.ts | 10 +-- src/main.ts | 48 ++++++------ src/utils.ts | 54 +++++++------- tsconfig.json | 19 +---- 15 files changed, 453 insertions(+), 460 deletions(-) diff --git a/.gitignore b/.gitignore index e397b53..308e9a0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ .DS_Store coverage *.log -.env \ No newline at end of file +.env diff --git a/README.md b/README.md index 844f873..f818142 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Run: ## CLI Options -* `-p` or `--path` - Path to the Google Keep folder -* `-o` or `--output` - Path to the output folder (will be created if it doesn't exist and must be different from the input folder) -* `-a` or `--archive` - Whether to include archived notes. Defaults to `false`. -* `-m` or `--mode` - Mode for conversion. Can be `pages` or `mixed`. Defaults to `mixed`. `mixed` mode will convert Keep notes with titles to Anytype `page` and Keep notes without titles to Anytype `note`. `pages` mode will convert all Keep notes to Anytype `page`, and will use the created date as the title if the Keep note does not have a title. +- `-p` or `--path` - Path to the Google Keep folder +- `-o` or `--output` - Path to the output folder (will be created if it doesn't exist and must be different from the input folder) +- `-a` or `--archive` - Whether to include archived notes. Defaults to `false`. +- `-m` or `--mode` - Mode for conversion. Can be `pages` or `mixed`. Defaults to `mixed`. `mixed` mode will convert Keep notes with titles to Anytype `page` and Keep notes without titles to Anytype `note`. `pages` mode will convert all Keep notes to Anytype `page`, and will use the created date as the title if the Keep note does not have a title. ## Import @@ -28,9 +28,9 @@ In anytype, select `file -> import` then `Any-Block` and select the output folde ## Notes -* Does not import Google Keep tags -* Does not import Google Keep images -* Does not import Google Keep note colors -* Modifies the created and modified dates to match the Google Keep note -* If the Keep note does not have a title, it uses the created date as the title -* Automatically parses any hyperlinks or annotations +- Does not import Google Keep tags +- Does not import Google Keep images +- Does not import Google Keep note colors +- Modifies the created and modified dates to match the Google Keep note +- If the Keep note does not have a title, it uses the created date as the title +- Automatically parses any hyperlinks or annotations diff --git a/jest.config.js b/jest.config.js index 12057e2..51cc616 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,10 +1,10 @@ module.exports = { - roots: ['/src'], + roots: ["/src"], testMatch: [ "**/__tests__/**/*.+(ts|tsx|js)", - "**/?(*.)+(spec|test).+(ts|tsx|js)" + "**/?(*.)+(spec|test).+(ts|tsx|js)", ], transform: { - "^.+\\.(ts|tsx)$": "ts-jest" + "^.+\\.(ts|tsx)$": "ts-jest", }, -} +}; diff --git a/src/anyBlock/blocks.ts b/src/anyBlock/blocks.ts index 01fc624..dc3e80c 100644 --- a/src/anyBlock/blocks.ts +++ b/src/anyBlock/blocks.ts @@ -1,4 +1,4 @@ -import { v4 as uuidv4 } from 'uuid' +import { v4 as uuidv4 } from "uuid"; import { AnnotationConfig, Block, @@ -14,8 +14,8 @@ import { Marks, Range, Restrictions, -} from './types' -import { extractUrls } from '../utils' +} from "./types"; +import { extractUrls } from "../utils"; const createRestrictions = ( edit = false, @@ -23,114 +23,114 @@ const createRestrictions = ( drag = true, dropOn = true ): { restrictions: Restrictions } => { - const restrictions: Restrictions = {} + const restrictions: Restrictions = {}; - if (edit) restrictions.edit = edit - if (remove) restrictions.remove = remove - if (drag) restrictions.drag = drag - if (dropOn) restrictions.dropOn = dropOn + if (edit) restrictions.edit = edit; + if (remove) restrictions.remove = remove; + if (drag) restrictions.drag = drag; + if (dropOn) restrictions.dropOn = dropOn; - return { restrictions } -} + return { restrictions }; +}; const generateLinkMarksForText = ( text: string ): Marks | Record => { - const marks: Mark[] = [] - const urls = extractUrls(text) + const marks: Mark[] = []; + const urls = extractUrls(text); if (urls.length === 0) { - return {} + return {}; } for (const url of urls) { const range: Range = - url.start > 0 ? { to: url.end, from: url.start } : { to: url.end } + url.start > 0 ? { to: url.end, from: url.start } : { to: url.end }; marks.push({ range, - type: 'Link', + type: "Link", param: url.url, - }) + }); } - return { marks } -} + return { marks }; +}; const generateTextContent = (config: ContentfulConfig) => { - const marks: Marks = generateLinkMarksForText(config.content) + const marks: Marks = generateLinkMarksForText(config.content); return { text: config.content, marks, - } -} + }; +}; // Block Handlers const headerBlockHandler: BlockHandler = { prepareContent(config) { - const childrenIds = ['featuredRelations'] - if (config.objectType === 'page') { - childrenIds.push('title', 'description') + const childrenIds = ["featuredRelations"]; + if (config.objectType === "page") { + childrenIds.push("title", "description"); } return { - id: 'header', + id: "header", ...createRestrictions(true), - layout: { style: 'Header' }, + layout: { style: "Header" }, childrenIds, - } + }; }, -} +}; const featuredRelationsBlockHandler: BlockHandler = { prepareContent() { return { - id: 'featuredRelations', + id: "featuredRelations", ...createRestrictions(), featuredRelations: {}, - } + }; }, -} +}; const descriptionBlockHandler: BlockHandler = { prepareContent() { return { - id: 'description', + id: "description", ...createRestrictions(), - fields: { _detailsKey: 'description' }, - text: { style: 'Description', marks: {} }, - } + fields: { _detailsKey: "description" }, + text: { style: "Description", marks: {} }, + }; }, -} +}; const titleBlockHandler: BlockHandler = { prepareContent() { return { - id: 'title', + id: "title", ...createRestrictions(), - fields: { _detailsKey: ['name', 'done'] }, - text: { style: 'Title', marks: {} }, - } + fields: { _detailsKey: ["name", "done"] }, + text: { style: "Title", marks: {} }, + }; }, -} +}; const textBlockHandler: BlockHandler = { prepareContent(config) { return { text: generateTextContent(config), - } + }; }, -} +}; const listBlockHandler: BlockHandler = { prepareContent(config) { return { text: { ...generateTextContent(config), - style: 'Checkbox', + style: "Checkbox", checked: config.checked, }, - } + }; }, -} +}; const annotationBlockHandler: BlockHandler = { prepareContent(config) { @@ -141,15 +141,15 @@ const annotationBlockHandler: BlockHandler = { marks: [ { range: { to: config.content.length }, - type: 'Link', + type: "Link", param: config.url, }, ], }, }, - } + }; }, -} +}; const handlers: HandlersMap = { Text: textBlockHandler, @@ -159,21 +159,21 @@ const handlers: HandlersMap = { FeaturedRelations: featuredRelationsBlockHandler, Description: descriptionBlockHandler, Title: titleBlockHandler, -} +}; export const createBlock = ( type: T, config: HandlerConfig[T] ): BlockWithId => { - let id = uuidv4() - const handler = handlers[type] + let id = uuidv4(); + const handler = handlers[type]; - const fields = handler.prepareContent(config as HandlerConfig[T]) + const fields = handler.prepareContent(config as HandlerConfig[T]); if (fields.id) { - id = fields.id + id = fields.id; } - const block: Block = { id, ...fields } - return { block, id } -} + const block: Block = { id, ...fields }; + return { block, id }; +}; diff --git a/src/anyBlock/config.ts b/src/anyBlock/config.ts index a34fbe8..d43b17d 100644 --- a/src/anyBlock/config.ts +++ b/src/anyBlock/config.ts @@ -1,108 +1,108 @@ -import { RelationLink } from './types' +import { RelationLink } from "./types"; export const relationLinks: RelationLink[] = [ { - key: 'id', - format: 'object', + key: "id", + format: "object", }, { - key: 'type', - format: 'object', + key: "type", + format: "object", }, { - key: 'snippet', + key: "snippet", }, { - key: 'lastModifiedDate', - format: 'date', + key: "lastModifiedDate", + format: "date", }, { - key: 'lastModifiedBy', - format: 'object', + key: "lastModifiedBy", + format: "object", }, { - key: 'sourceFilePath', + key: "sourceFilePath", }, { - key: 'iconEmoji', - format: 'emoji', + key: "iconEmoji", + format: "emoji", }, { - key: 'layout', - format: 'number', + key: "layout", + format: "number", }, { - key: 'name', - format: 'shorttext', + key: "name", + format: "shorttext", }, { - key: 'workspaceId', - format: 'object', + key: "workspaceId", + format: "object", }, { - key: 'backlinks', - format: 'object', + key: "backlinks", + format: "object", }, { - key: 'creator', - format: 'object', + key: "creator", + format: "object", }, { - key: 'createdDate', - format: 'date', + key: "createdDate", + format: "date", }, { - key: 'description', + key: "description", }, { - key: 'iconImage', - format: 'file', + key: "iconImage", + format: "file", }, { - key: 'layoutAlign', - format: 'number', + key: "layoutAlign", + format: "number", }, { - key: 'coverId', + key: "coverId", }, { - key: 'coverScale', - format: 'number', + key: "coverScale", + format: "number", }, { - key: 'coverType', - format: 'number', + key: "coverType", + format: "number", }, { - key: 'coverX', - format: 'number', + key: "coverX", + format: "number", }, { - key: 'coverY', - format: 'number', + key: "coverY", + format: "number", }, { - key: 'lastOpenedDate', - format: 'date', + key: "lastOpenedDate", + format: "date", }, { - key: 'featuredRelations', - format: 'object', + key: "featuredRelations", + format: "object", }, { - key: 'isFavorite', - format: 'checkbox', + key: "isFavorite", + format: "checkbox", }, { - key: 'links', - format: 'object', + key: "links", + format: "object", }, { - key: 'internalFlags', - format: 'number', + key: "internalFlags", + format: "number", }, { - key: 'restrictions', - format: 'number', + key: "restrictions", + format: "number", }, -] +]; diff --git a/src/anyBlock/convert.ts b/src/anyBlock/convert.ts index 7259d26..6142874 100644 --- a/src/anyBlock/convert.ts +++ b/src/anyBlock/convert.ts @@ -1,83 +1,83 @@ -import * as dotenv from 'dotenv' -import { convertMicrosecondsToSeconds, getEnvVar } from '../utils' -import { Mode } from '../cli' +import * as dotenv from "dotenv"; +import { convertMicrosecondsToSeconds, getEnvVar } from "../utils"; +import { Mode } from "../cli"; import { Block, BlockWithId, CreateAnyBlockPageConfig, ObjectType, Page, -} from './types' -import { relationLinks } from './config' -import { createBlock } from './blocks' -import { GoogleKeepNote } from '../keep/types' -dotenv.config() +} from "./types"; +import { relationLinks } from "./config"; +import { createBlock } from "./blocks"; +import { GoogleKeepNote } from "../keep/types"; +dotenv.config(); const genTitleFromDate = (createdTimestampUsec: number) => { - return new Date(createdTimestampUsec / 1000).toLocaleString('en-US', { - month: 'long', - day: '2-digit', - year: 'numeric', - }) -} + return new Date(createdTimestampUsec / 1000).toLocaleString("en-US", { + month: "long", + day: "2-digit", + year: "numeric", + }); +}; const getObjectType = (mode: Mode, hasTitle: boolean): ObjectType => { - if (mode === 'pages') { - return 'page' + if (mode === "pages") { + return "page"; } - if (mode === 'mixed') { - return hasTitle ? 'page' : 'note' + if (mode === "mixed") { + return hasTitle ? "page" : "note"; } - throw new Error(`Invalid mode ${mode}`) -} + throw new Error(`Invalid mode ${mode}`); +}; const getObjectTypeString = (objectType: ObjectType): string => { - if (objectType === 'page') { - return 'ot-page' + if (objectType === "page") { + return "ot-page"; } - if (objectType === 'note') { - return 'ot-note' + if (objectType === "note") { + return "ot-note"; } - throw new Error(`Invalid object type ${objectType}`) -} + throw new Error(`Invalid object type ${objectType}`); +}; const getLayoutNumber = (objectType: ObjectType): number => { - if (objectType === 'page') { - return 0 + if (objectType === "page") { + return 0; } - if (objectType === 'note') { - return 9 + if (objectType === "note") { + return 9; } - throw new Error(`Invalid object type ${objectType}`) -} + throw new Error(`Invalid object type ${objectType}`); +}; const createCoreBlocks = ( note: GoogleKeepNote, objectType: ObjectType ): BlockWithId[] => { - const headerBlock = createBlock('Header', { objectType }) - const featuredRelationsBlock = createBlock('FeaturedRelations', undefined) + const headerBlock = createBlock("Header", { objectType }); + const featuredRelationsBlock = createBlock("FeaturedRelations", undefined); const textBlocks: BlockWithId[] = note.textContent ? note.textContent - .split('\n') - .map((text) => createBlock('Text', { content: text })) - : [] + .split("\n") + .map((text) => createBlock("Text", { content: text })) + : []; const listBlocks: BlockWithId[] = note.listContent ? note.listContent.map((item) => - createBlock('List', { checked: item.isChecked, content: item.text }) + createBlock("List", { checked: item.isChecked, content: item.text }) ) - : [] + : []; const annotationBlocks: BlockWithId[] = note.annotations ? note.annotations.map((annotation) => - createBlock('Annotation', { + createBlock("Annotation", { url: annotation.url, content: annotation.title, }) ) - : [] + : []; let allBlocks: BlockWithId[] = [ headerBlock, @@ -85,38 +85,38 @@ const createCoreBlocks = ( ...listBlocks, ...annotationBlocks, featuredRelationsBlock, - ] + ]; - if (objectType === 'page') { - const titleBlock = createBlock('Title', undefined) - const descriptionBlock = createBlock('Description', undefined) - allBlocks = [...allBlocks, titleBlock, descriptionBlock] + if (objectType === "page") { + const titleBlock = createBlock("Title", undefined); + const descriptionBlock = createBlock("Description", undefined); + allBlocks = [...allBlocks, titleBlock, descriptionBlock]; } - return allBlocks -} + return allBlocks; +}; const createBlocks = ( note: GoogleKeepNote, objectType: ObjectType ): Block[] => { - const allBlocks = createCoreBlocks(note, objectType) + const allBlocks = createCoreBlocks(note, objectType); - const nonChildrenIds = ['title', 'description', 'featuredRelations'] - const blocks = allBlocks.map((blockWithId) => blockWithId.block) + const nonChildrenIds = ["title", "description", "featuredRelations"]; + const blocks = allBlocks.map((blockWithId) => blockWithId.block); const childrenIds = allBlocks .filter((blockWithId) => !nonChildrenIds.includes(blockWithId.block.id)) - .map((blockWithId) => blockWithId.id) + .map((blockWithId) => blockWithId.id); const mainBlock = { - id: '', + id: "", restrictions: {}, childrenIds: [...childrenIds], smartblock: {}, - } + }; - return [mainBlock, ...blocks] -} + return [mainBlock, ...blocks]; +}; const createAnyBlockPage = (config: CreateAnyBlockPageConfig): Page => { const { @@ -126,62 +126,62 @@ const createAnyBlockPage = (config: CreateAnyBlockPageConfig): Page => { editedTimestamp, objectType, sourcePath, - } = config + } = config; - const tagId = getEnvVar('TAG_ID', '') - const tag = tagId ? [tagId] : [] + const tagId = getEnvVar("TAG_ID", ""); + const tag = tagId ? [tagId] : []; - let featuredRelations = ['type'] - if (objectType === 'page') { - featuredRelations = [...featuredRelations, 'description'] + let featuredRelations = ["type"]; + if (objectType === "page") { + featuredRelations = [...featuredRelations, "description"]; } return { - sbType: 'Page', + sbType: "Page", snapshot: { data: { blocks, details: { backlinks: [], createdDate: convertMicrosecondsToSeconds(createdTimestamp), - creator: '', - description: '', + creator: "", + description: "", featuredRelations, - iconEmoji: '', - id: '', - lastModifiedBy: '', + iconEmoji: "", + id: "", + lastModifiedBy: "", lastModifiedDate: convertMicrosecondsToSeconds(editedTimestamp), lastOpenedDate: convertMicrosecondsToSeconds(editedTimestamp), layout: getLayoutNumber(objectType), links: [], name: titleText, restrictions: [], - snippet: '', + snippet: "", sourceFilePath: sourcePath, tag, type: getObjectTypeString(objectType), - workspaceId: '', + workspaceId: "", }, objectTypes: [getObjectTypeString(objectType)], relationLinks, }, }, - } -} + }; +}; export const convertToAnyBlockPage = ( note: GoogleKeepNote, mode: Mode ): Page => { - const hasTitle = note.title !== undefined && note.title !== '' - const objectType = getObjectType(mode, hasTitle) + const hasTitle = note.title !== undefined && note.title !== ""; + const objectType = getObjectType(mode, hasTitle); - let titleText = '' - if (objectType === 'page') { - titleText = note.title || genTitleFromDate(note.createdTimestampUsec) + let titleText = ""; + if (objectType === "page") { + titleText = note.title || genTitleFromDate(note.createdTimestampUsec); } - const blocks = createBlocks(note, objectType) + const blocks = createBlocks(note, objectType); return createAnyBlockPage({ blocks, @@ -190,5 +190,5 @@ export const convertToAnyBlockPage = ( editedTimestamp: note.userEditedTimestampUsec, objectType, sourcePath: note.sourceFilePath, - }) -} + }); +}; diff --git a/src/anyBlock/types.ts b/src/anyBlock/types.ts index b209d21..542fcd5 100644 --- a/src/anyBlock/types.ts +++ b/src/anyBlock/types.ts @@ -1,140 +1,144 @@ -export type ObjectType = 'page' | 'note' +export type ObjectType = "page" | "note"; -export type BlockWithId = { block: Block; id: string } +export type BlockWithId = { block: Block; id: string }; export interface Page { - sbType: 'Page' - snapshot: Snapshot + sbType: "Page"; + snapshot: Snapshot; } interface Snapshot { - data: Data + data: Data; } interface Data { - blocks: Block[] - details: Details - objectTypes: string[] - relationLinks: RelationLink[] + blocks: Block[]; + details: Details; + objectTypes: string[]; + relationLinks: RelationLink[]; } export interface Block { - id: string - restrictions?: Restrictions - childrenIds?: string[] - layout?: Layout - text?: Text - fields?: Fields - featuredRelations?: any - smartblock?: any + id: string; + restrictions?: Restrictions; + childrenIds?: string[]; + layout?: Layout; + text?: Text; + fields?: Fields; + featuredRelations?: any; + smartblock?: any; } export interface Restrictions { - edit?: boolean - remove?: boolean - drag?: boolean - dropOn?: boolean + edit?: boolean; + remove?: boolean; + drag?: boolean; + dropOn?: boolean; } export interface Layout { - style: string + style: string; } export interface Range { - to: number - from?: number + to: number; + from?: number; } export interface Mark { - range: Range - type: string - param?: string + range: Range; + type: string; + param?: string; } export interface Marks { - marks?: Mark[] + marks?: Mark[]; } export interface Text { - text?: string - style?: string - marks?: Marks - checked?: boolean + text?: string; + style?: string; + marks?: Marks; + checked?: boolean; } export interface Fields { - _detailsKey?: string[] | string + _detailsKey?: string[] | string; } interface Details { - backlinks: any[] - createdDate: number - creator: string - description: string - featuredRelations: string[] - iconEmoji: string - id: string - lastModifiedBy: string - lastModifiedDate: number - lastOpenedDate: number - layout: number - links: any[] - name: string - restrictions: any[] - snippet: string - sourceFilePath: string - tag: string[] - type: string - workspaceId: string + backlinks: any[]; + createdDate: number; + creator: string; + description: string; + featuredRelations: string[]; + iconEmoji: string; + id: string; + lastModifiedBy: string; + lastModifiedDate: number; + lastOpenedDate: number; + layout: number; + links: any[]; + name: string; + restrictions: any[]; + snippet: string; + sourceFilePath: string; + tag: string[]; + type: string; + workspaceId: string; } export interface RelationLink { - key: string - format?: string + key: string; + format?: string; } -type SpecialBlockType = 'Header' | 'FeaturedRelations' | 'Description' | 'Title' -export type BlockType = 'Text' | 'List' | 'Annotation' | SpecialBlockType +type SpecialBlockType = + | "Header" + | "FeaturedRelations" + | "Description" + | "Title"; +export type BlockType = "Text" | "List" | "Annotation" | SpecialBlockType; export interface HeaderConfig { - objectType: ObjectType + objectType: ObjectType; } export interface ContentfulConfig { - content: string + content: string; } export interface ListConfig extends ContentfulConfig { - checked: boolean + checked: boolean; } export interface AnnotationConfig extends ContentfulConfig { - url: string + url: string; } export type HandlerConfig = { - Header: HeaderConfig - FeaturedRelations: undefined - Title: undefined - Description: undefined - Text: ContentfulConfig - List: ListConfig - Annotation: AnnotationConfig -} + Header: HeaderConfig; + FeaturedRelations: undefined; + Title: undefined; + Description: undefined; + Text: ContentfulConfig; + List: ListConfig; + Annotation: AnnotationConfig; +}; export type HandlersMap = { - [K in BlockType]: BlockHandler -} + [K in BlockType]: BlockHandler; +}; export interface BlockHandler { - prepareContent(config: T): Partial + prepareContent(config: T): Partial; } export interface CreateAnyBlockPageConfig { - blocks: Block[] - objectType: ObjectType - titleText: string - createdTimestamp: number - editedTimestamp: number - sourcePath: string + blocks: Block[]; + objectType: ObjectType; + titleText: string; + createdTimestamp: number; + editedTimestamp: number; + sourcePath: string; } diff --git a/src/anyBlock/write.ts b/src/anyBlock/write.ts index 45c0522..fe090d4 100644 --- a/src/anyBlock/write.ts +++ b/src/anyBlock/write.ts @@ -1,14 +1,14 @@ -import { Page } from './types' -import { writeFile } from 'fs/promises' -import path from 'path' +import { Page } from "./types"; +import { writeFile } from "fs/promises"; +import path from "path"; export const writeAnyBlockPageToFile = async ( anyBlockPage: Page, sourceFileName: string, outputFolder: string ) => { - const filePath = path.resolve(outputFolder, `${sourceFileName}.json`) - const serializedData = JSON.stringify(anyBlockPage, null, 2) - await writeFile(filePath, serializedData) - return filePath -} + const filePath = path.resolve(outputFolder, `${sourceFileName}.json`); + const serializedData = JSON.stringify(anyBlockPage, null, 2); + await writeFile(filePath, serializedData); + return filePath; +}; diff --git a/src/cli.ts b/src/cli.ts index 728f6f9..f0ecba5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,54 +1,54 @@ #!/usr/bin/env node -import yargs from 'yargs' -import { main } from './main' +import yargs from "yargs"; +import { main } from "./main"; -export type Mode = 'pages' | 'mixed' +export type Mode = "pages" | "mixed"; export interface Settings { - path: string - output: string - mode: Mode - includeArchive: boolean + path: string; + output: string; + mode: Mode; + includeArchive: boolean; } const isMode = (mode: any): mode is Mode => { - return mode === 'pages' || mode === 'mixed' -} + return mode === "pages" || mode === "mixed"; +}; const argv = yargs - .option('path', { - alias: 'p', - description: 'Specify the path', - type: 'string', + .option("path", { + alias: "p", + description: "Specify the path", + type: "string", }) - .option('output', { - alias: 'o', - description: 'Specify the output path', - type: 'string', + .option("output", { + alias: "o", + description: "Specify the output path", + type: "string", }) - .option('mode', { - alias: 'm', - description: 'Specify the mode', - choices: ['pages', 'mixed'], - default: 'mixed', + .option("mode", { + alias: "m", + description: "Specify the mode", + choices: ["pages", "mixed"], + default: "mixed", }) - .option('archive', { - alias: 'a', - description: 'Include archived Keep notes', - type: 'boolean', + .option("archive", { + alias: "a", + description: "Include archived Keep notes", + type: "boolean", default: false, }) - .demandOption(['path', 'output']) + .demandOption(["path", "output"]) .help() - .alias('help', 'h').argv + .alias("help", "h").argv; if (argv.path === argv.output) { - console.error(`Error: path and output cannot be the same`) - process.exit(1) + console.error(`Error: path and output cannot be the same`); + process.exit(1); } if (!isMode(argv.mode)) { - console.error('Invalid mode') - process.exit(1) + console.error("Invalid mode"); + process.exit(1); } const settings: Settings = { @@ -56,5 +56,5 @@ const settings: Settings = { output: argv.output, mode: argv.mode, includeArchive: argv.archive, -} -main(settings) +}; +main(settings); diff --git a/src/keep/ingest.ts b/src/keep/ingest.ts index 2a1c886..c30038c 100644 --- a/src/keep/ingest.ts +++ b/src/keep/ingest.ts @@ -1,115 +1,115 @@ -import { promises as fs } from 'fs' -import path from 'path' -import { GoogleKeepNote } from './types' +import { promises as fs } from "fs"; +import path from "path"; +import { GoogleKeepNote } from "./types"; const parseGoogleKeepNote = ( jsonString: string, filePath: string ): GoogleKeepNote => { - const parsedObject = JSON.parse(jsonString) + const parsedObject = JSON.parse(jsonString); if (!isGoogleKeepNote(parsedObject)) { - throw new Error('Invalid data structure for a GoogleKeepNote') + throw new Error("Invalid data structure for a GoogleKeepNote"); } return { ...parsedObject, sourceFilePath: filePath, sourceFileName: path.parse(filePath).name, - } -} + }; +}; const isGoogleKeepNote = (object: any): object is GoogleKeepNote => { const baseFields = [ - 'color', - 'isTrashed', - 'isPinned', - 'isArchived', - 'title', - 'userEditedTimestampUsec', - 'createdTimestampUsec', - ] + "color", + "isTrashed", + "isPinned", + "isArchived", + "title", + "userEditedTimestampUsec", + "createdTimestampUsec", + ]; for (const field of baseFields) { if (!(field in object)) { - throw new Error(`Missing field: ${field}`) + throw new Error(`Missing field: ${field}`); } } if (object.listContent) { if (!Array.isArray(object.listContent)) { - throw new Error('listContent is not an array') + throw new Error("listContent is not an array"); } for (const item of object.listContent) { if ( - typeof item.text !== 'string' || - typeof item.isChecked !== 'boolean' + typeof item.text !== "string" || + typeof item.isChecked !== "boolean" ) { - throw new Error('Invalid listContent item') + throw new Error("Invalid listContent item"); } } } - if (object.textContent && typeof object.textContent !== 'string') { - throw new Error('Invalid textContent') + if (object.textContent && typeof object.textContent !== "string") { + throw new Error("Invalid textContent"); } if (object.annotations) { if (!Array.isArray(object.annotations)) { - throw new Error('annotations is not an array') + throw new Error("annotations is not an array"); } for (const annotation of object.annotations) { if ( - typeof annotation.description !== 'string' || - typeof annotation.source !== 'string' || - typeof annotation.title !== 'string' || - typeof annotation.url !== 'string' + typeof annotation.description !== "string" || + typeof annotation.source !== "string" || + typeof annotation.title !== "string" || + typeof annotation.url !== "string" ) { - throw new Error('Invalid annotation item') + throw new Error("Invalid annotation item"); } } } if (object.attachments) { if (!Array.isArray(object.attachments)) { - throw new Error('attachments is not an array') + throw new Error("attachments is not an array"); } for (const attachment of object.attachments) { if ( - typeof attachment.filePath !== 'string' || - typeof attachment.mimetype !== 'string' + typeof attachment.filePath !== "string" || + typeof attachment.mimetype !== "string" ) { - throw new Error('Invalid attachment item') + throw new Error("Invalid attachment item"); } } } - return true -} + return true; +}; export const ingestKeepJsonFiles = async ( folderPath: string, includeArchive: boolean ): Promise => { - const notes: GoogleKeepNote[] = [] - const files = await fs.readdir(folderPath) + const notes: GoogleKeepNote[] = []; + const files = await fs.readdir(folderPath); for (const file of files) { - if (path.extname(file) === '.json') { - const filePath = path.join(folderPath, file) + if (path.extname(file) === ".json") { + const filePath = path.join(folderPath, file); try { - const data = await fs.readFile(filePath, 'utf8') - const note = parseGoogleKeepNote(data, filePath) + const data = await fs.readFile(filePath, "utf8"); + const note = parseGoogleKeepNote(data, filePath); if (note.isArchived && !includeArchive) { - continue + continue; } - notes.push(note) + notes.push(note); } catch (error: any) { throw new Error( `Failed to parse ${filePath} into a GoogleKeepNote: ${error.message}` - ) + ); } } } - return notes -} + return notes; +}; diff --git a/src/keep/types.ts b/src/keep/types.ts index 0c1d526..b24746d 100644 --- a/src/keep/types.ts +++ b/src/keep/types.ts @@ -1,32 +1,32 @@ export interface ListContentItem { - text: string - isChecked: boolean + text: string; + isChecked: boolean; } export interface Annotation { - description: string - source: string - title: string - url: string + description: string; + source: string; + title: string; + url: string; } interface Attachment { - filePath: string - mimetype: string + filePath: string; + mimetype: string; } export interface GoogleKeepNote { - color: string - isTrashed: boolean - isPinned: boolean - isArchived: boolean - listContent?: ListContentItem[] - textContent?: string - annotations?: Annotation[] - attachments?: Attachment[] - title: string - userEditedTimestampUsec: number - createdTimestampUsec: number - sourceFilePath: string - sourceFileName: string + color: string; + isTrashed: boolean; + isPinned: boolean; + isArchived: boolean; + listContent?: ListContentItem[]; + textContent?: string; + annotations?: Annotation[]; + attachments?: Attachment[]; + title: string; + userEditedTimestampUsec: number; + createdTimestampUsec: number; + sourceFilePath: string; + sourceFileName: string; } diff --git a/src/main.test.ts b/src/main.test.ts index a93eae2..9d97737 100644 --- a/src/main.test.ts +++ b/src/main.test.ts @@ -1,9 +1,9 @@ -import { greet } from './main' +import { greet } from "./main"; -test('the data is peanut butter', () => { - expect(1).toBe(1) +test("the data is peanut butter", () => { + expect(1).toBe(1); }); -test('greeting', () => { - expect(greet('Foo')).toBe('Hello Foo') +test("greeting", () => { + expect(greet("Foo")).toBe("Hello Foo"); }); diff --git a/src/main.ts b/src/main.ts index dabadfc..2629cc8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,9 @@ -import { convertToAnyBlockPage } from './anyBlock/convert' -import { writeAnyBlockPageToFile } from './anyBlock/write' -import { Settings } from './cli' -import { ingestKeepJsonFiles } from './keep/ingest' -import { GoogleKeepNote } from './keep/types' -import { ensureDirectoryExists } from './utils' +import { convertToAnyBlockPage } from "./anyBlock/convert"; +import { writeAnyBlockPageToFile } from "./anyBlock/write"; +import { Settings } from "./cli"; +import { ingestKeepJsonFiles } from "./keep/ingest"; +import { GoogleKeepNote } from "./keep/types"; +import { ensureDirectoryExists } from "./utils"; export const main = async (settings: Settings) => { const { @@ -11,53 +11,53 @@ export const main = async (settings: Settings) => { output: outputFolderPath, mode, includeArchive, - } = settings - let notes: GoogleKeepNote[] = [] + } = settings; + let notes: GoogleKeepNote[] = []; try { const maybeNotes = await ingestKeepJsonFiles( inputFolderPath, includeArchive - ) - notes = maybeNotes + ); + notes = maybeNotes; } catch (err) { - console.error(`Error:`, err) - process.exit(1) + console.error(`Error:`, err); + process.exit(1); } if (!notes) { - console.error(`Error: no notes found`) - process.exit(1) + console.error(`Error: no notes found`); + process.exit(1); } - await ensureDirectoryExists(outputFolderPath) - const errors: string[] = [] + await ensureDirectoryExists(outputFolderPath); + const errors: string[] = []; for (const note of notes) { try { - const anyBlockPage = convertToAnyBlockPage(note, mode) + const anyBlockPage = convertToAnyBlockPage(note, mode); const filePath = await writeAnyBlockPageToFile( anyBlockPage, note.sourceFileName, outputFolderPath - ) - console.log(`Successfully generated ${filePath}`) + ); + console.log(`Successfully generated ${filePath}`); } catch (error) { if (error instanceof Error) { errors.push( `Error writing any-block for keep file ${note.sourceFilePath}`, error.message - ) + ); } else { errors.push( `Error writing any-block for keep file ${note.sourceFilePath}`, - 'An unknown error occurred' - ) + "An unknown error occurred" + ); } } } for (const error of errors) { - console.error(error) + console.error(error); } -} +}; diff --git a/src/utils.ts b/src/utils.ts index 71d9820..e4d5491 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,37 +1,37 @@ -import { promises as fs } from 'fs' +import { promises as fs } from "fs"; export const getEnvVar = (key: string, defaultValue?: string): string => { - const value = process.env[key] - if (value !== undefined) return value - if (defaultValue !== undefined) return defaultValue - throw new Error(`Missing environment variable: ${key}`) -} + const value = process.env[key]; + if (value !== undefined) return value; + if (defaultValue !== undefined) return defaultValue; + throw new Error(`Missing environment variable: ${key}`); +}; export const ensureDirectoryExists = async (dirPath: string) => { try { - await fs.access(dirPath) + await fs.access(dirPath); } catch (error: any) { - if (error.code === 'ENOENT') { - await fs.mkdir(dirPath, { recursive: true }) - console.log(`Directory created: ${dirPath}`) + if (error.code === "ENOENT") { + await fs.mkdir(dirPath, { recursive: true }); + console.log(`Directory created: ${dirPath}`); } else { - console.error(`An error occurred: ${error.message}`) + console.error(`An error occurred: ${error.message}`); } } -} +}; export const convertMicrosecondsToSeconds = (microseconds: number) => { - return Math.floor(microseconds / 1000000) -} + return Math.floor(microseconds / 1000000); +}; interface UrlMatch { - url: string - start: number - end: number + url: string; + start: number; + end: number; } export const extractUrls = (input: string): UrlMatch[] => { - const urlRegex = /https?:\/\/[^\s]+/g - const matches = [...input.matchAll(urlRegex)] + const urlRegex = /https?:\/\/[^\s]+/g; + const matches = [...input.matchAll(urlRegex)]; const result = matches .map((match) => { if (match.index !== undefined) { @@ -39,14 +39,14 @@ export const extractUrls = (input: string): UrlMatch[] => { url: match[0], start: match.index, end: match.index + match[0].length, - } + }; } - return null + return null; }) .filter((item) => item !== null) as Array<{ - url: string - start: number - end: number - }> - return result -} + url: string; + start: number; + end: number; + }>; + return result; +}; diff --git a/tsconfig.json b/tsconfig.json index 9ebf6dc..ab515b5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,20 +19,9 @@ "experimentalDecorators": true, "sourceMap": true, "outDir": "./dist/tsc/", - "types": [ - "node", - "jest" - ], - "lib": [ - "ES6", - "DOM" - ] + "types": ["node", "jest"], + "lib": ["ES6", "DOM"] }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "node_modules", - "**/*.test.ts" - ] + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "**/*.test.ts"] } From b7cbda533c3c76a470b46f71dacbb400e4bb3a0d Mon Sep 17 00:00:00 2001 From: Jia Xun Date: Sun, 28 Apr 2024 17:43:46 +0900 Subject: [PATCH 2/2] Added labels, colours, and archived metadata --- README.md | 20 +++++++++-- img/example-import.png | Bin 0 -> 105889 bytes src/anyBlock/blocks.ts | 12 +++++++ src/anyBlock/convert.ts | 73 ++++++++++++++++++++++++++++++++++------ src/anyBlock/types.ts | 17 +++++++++- src/cli.ts | 35 +++++++++++++++++++ src/keep/ingest.ts | 17 +++++++++- src/keep/types.ts | 5 +++ src/main.ts | 15 +++++++-- 9 files changed, 177 insertions(+), 17 deletions(-) create mode 100644 img/example-import.png diff --git a/README.md b/README.md index f818142..bd28a05 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,11 @@ Run: - `-p` or `--path` - Path to the Google Keep folder - `-o` or `--output` - Path to the output folder (will be created if it doesn't exist and must be different from the input folder) - `-a` or `--archive` - Whether to include archived notes. Defaults to `false`. +- `-t` or `--trash` - Whether to include trashed notes. Defaults to `false`. - `-m` or `--mode` - Mode for conversion. Can be `pages` or `mixed`. Defaults to `mixed`. `mixed` mode will convert Keep notes with titles to Anytype `page` and Keep notes without titles to Anytype `note`. `pages` mode will convert all Keep notes to Anytype `page`, and will use the created date as the title if the Keep note does not have a title. +- `-e` or `--emoji` - The emoji to use for the Anytype object. Defaults to nothing. +- `-d` or `--metadata` - Whether to include additional metadata from Google Keep. Defaults to `false`. Refer to Notes for more information. +- `-r` or `--relation` - Include the description relation as a block in the Anytype object. Defaults to `false`. ## Import @@ -28,9 +32,21 @@ In anytype, select `file -> import` then `Any-Block` and select the output folde ## Notes -- Does not import Google Keep tags +- You should try importing into a blank space first to see if the conversion works as expected. - Does not import Google Keep images -- Does not import Google Keep note colors - Modifies the created and modified dates to match the Google Keep note - If the Keep note does not have a title, it uses the created date as the title - Automatically parses any hyperlinks or annotations +- Metadata will be included in the description if the `metadata` flag is set to `true`. This metadata includes: + - `Color` - The colour of the note if it's not DEFAULT + - `IsPinned` - Whether the note is pinned + - `IsArchived` - Whether the note is archived + - `IsTrashed` - Whether the note is in the trash + - `Labels` - The labels attached to the note + +## Example + +`yarn cli -p /Takeout/Keep -o -a -t -d -r -m pages -e 🗒️` + +In this example, the command above was run. This includes all archived notes and adds the labels and colours of the notes in the Description relation. The creation dates also match the original Google Keep notes. +![image](img/example-import.png) diff --git a/img/example-import.png b/img/example-import.png new file mode 100644 index 0000000000000000000000000000000000000000..eaa070acd4464977a34b0c34fa8b178c3936fba9 GIT binary patch literal 105889 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%0D9O(2G_O<`=FM;VCi$a2tLhCF9g;N9 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 H*CYNPpaOXM literal 0 HcmV?d00001 diff --git a/src/anyBlock/blocks.ts b/src/anyBlock/blocks.ts index dc3e80c..7dbbfc0 100644 --- a/src/anyBlock/blocks.ts +++ b/src/anyBlock/blocks.ts @@ -13,6 +13,7 @@ import { Mark, Marks, Range, + RelationConfig, Restrictions, } from "./types"; import { extractUrls } from "../utils"; @@ -112,6 +113,16 @@ const titleBlockHandler: BlockHandler = { }, }; +const relationBlockHandler: BlockHandler = { + prepareContent(config) { + return { + relation: { + key: config.relationKey, + }, + }; + }, +}; + const textBlockHandler: BlockHandler = { prepareContent(config) { return { @@ -159,6 +170,7 @@ const handlers: HandlersMap = { FeaturedRelations: featuredRelationsBlockHandler, Description: descriptionBlockHandler, Title: titleBlockHandler, + Relation: relationBlockHandler, }; export const createBlock = ( diff --git a/src/anyBlock/convert.ts b/src/anyBlock/convert.ts index 6142874..2afffd0 100644 --- a/src/anyBlock/convert.ts +++ b/src/anyBlock/convert.ts @@ -1,6 +1,9 @@ import * as dotenv from "dotenv"; -import { convertMicrosecondsToSeconds, getEnvVar } from "../utils"; import { Mode } from "../cli"; +import { GoogleKeepNote } from "../keep/types"; +import { convertMicrosecondsToSeconds, getEnvVar } from "../utils"; +import { createBlock } from "./blocks"; +import { relationLinks } from "./config"; import { Block, BlockWithId, @@ -8,9 +11,6 @@ import { ObjectType, Page, } from "./types"; -import { relationLinks } from "./config"; -import { createBlock } from "./blocks"; -import { GoogleKeepNote } from "../keep/types"; dotenv.config(); const genTitleFromDate = (createdTimestampUsec: number) => { @@ -53,11 +53,21 @@ const getLayoutNumber = (objectType: ObjectType): number => { const createCoreBlocks = ( note: GoogleKeepNote, - objectType: ObjectType + objectType: ObjectType, + includeDescriptionRelation: boolean ): BlockWithId[] => { const headerBlock = createBlock("Header", { objectType }); const featuredRelationsBlock = createBlock("FeaturedRelations", undefined); + const descriptionRelationBlock: BlockWithId[] = []; + if (includeDescriptionRelation) { + descriptionRelationBlock.push( + createBlock("Relation", { + relationKey: "description", + }) + ); + } + const textBlocks: BlockWithId[] = note.textContent ? note.textContent .split("\n") @@ -81,6 +91,7 @@ const createCoreBlocks = ( let allBlocks: BlockWithId[] = [ headerBlock, + ...descriptionRelationBlock, ...textBlocks, ...listBlocks, ...annotationBlocks, @@ -98,9 +109,14 @@ const createCoreBlocks = ( const createBlocks = ( note: GoogleKeepNote, - objectType: ObjectType + objectType: ObjectType, + includeDescriptionRelation: boolean ): Block[] => { - const allBlocks = createCoreBlocks(note, objectType); + const allBlocks = createCoreBlocks( + note, + objectType, + includeDescriptionRelation + ); const nonChildrenIds = ["title", "description", "featuredRelations"]; const blocks = allBlocks.map((blockWithId) => blockWithId.block); @@ -126,6 +142,8 @@ const createAnyBlockPage = (config: CreateAnyBlockPageConfig): Page => { editedTimestamp, objectType, sourcePath, + description, + emoji, } = config; const tagId = getEnvVar("TAG_ID", ""); @@ -145,9 +163,9 @@ const createAnyBlockPage = (config: CreateAnyBlockPageConfig): Page => { backlinks: [], createdDate: convertMicrosecondsToSeconds(createdTimestamp), creator: "", - description: "", + description: description, featuredRelations, - iconEmoji: "", + iconEmoji: emoji, id: "", lastModifiedBy: "", lastModifiedDate: convertMicrosecondsToSeconds(editedTimestamp), @@ -171,7 +189,10 @@ const createAnyBlockPage = (config: CreateAnyBlockPageConfig): Page => { export const convertToAnyBlockPage = ( note: GoogleKeepNote, - mode: Mode + mode: Mode, + emoji: string, + includeMetadata: boolean, + includeRelation: boolean ): Page => { const hasTitle = note.title !== undefined && note.title !== ""; const objectType = getObjectType(mode, hasTitle); @@ -181,7 +202,35 @@ export const convertToAnyBlockPage = ( titleText = note.title || genTitleFromDate(note.createdTimestampUsec); } - const blocks = createBlocks(note, objectType); + let description = ""; + if (includeMetadata) { + const descriptionArray: string[] = []; + if (note.color && note.color !== "DEFAULT") { + descriptionArray.push(`Color: ${note.color}`); + } + if (note.isTrashed) { + descriptionArray.push("Trashed"); + } + if (note.isPinned) { + descriptionArray.push("Pinned"); + } + if (note.isArchived) { + descriptionArray.push("Archived"); + } + if (note.labels) { + descriptionArray.push( + `Labels: ${note.labels.map((label) => label.name).join(", ")}` + ); + } + + description = descriptionArray.join(" | "); + } + + const blocks = createBlocks( + note, + objectType, + includeMetadata && includeRelation + ); return createAnyBlockPage({ blocks, @@ -190,5 +239,7 @@ export const convertToAnyBlockPage = ( editedTimestamp: note.userEditedTimestampUsec, objectType, sourcePath: note.sourceFilePath, + description, + emoji, }); }; diff --git a/src/anyBlock/types.ts b/src/anyBlock/types.ts index 542fcd5..5d97880 100644 --- a/src/anyBlock/types.ts +++ b/src/anyBlock/types.ts @@ -27,6 +27,9 @@ export interface Block { fields?: Fields; featuredRelations?: any; smartblock?: any; + relation?: { + key: string; + }; } export interface Restrictions { @@ -98,7 +101,12 @@ type SpecialBlockType = | "FeaturedRelations" | "Description" | "Title"; -export type BlockType = "Text" | "List" | "Annotation" | SpecialBlockType; +export type BlockType = + | "Text" + | "List" + | "Annotation" + | "Relation" + | SpecialBlockType; export interface HeaderConfig { objectType: ObjectType; @@ -108,6 +116,10 @@ export interface ContentfulConfig { content: string; } +export interface RelationConfig { + relationKey: string; +} + export interface ListConfig extends ContentfulConfig { checked: boolean; } @@ -124,6 +136,7 @@ export type HandlerConfig = { Text: ContentfulConfig; List: ListConfig; Annotation: AnnotationConfig; + Relation: RelationConfig; }; export type HandlersMap = { @@ -141,4 +154,6 @@ export interface CreateAnyBlockPageConfig { createdTimestamp: number; editedTimestamp: number; sourcePath: string; + description: string; + emoji: string; } diff --git a/src/cli.ts b/src/cli.ts index f0ecba5..a2571db 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -8,6 +8,10 @@ export interface Settings { output: string; mode: Mode; includeArchive: boolean; + includeTrashed: boolean; + includeMetadata: boolean; + includeRelation: boolean; + emoji: string; } const isMode = (mode: any): mode is Mode => { @@ -37,10 +41,37 @@ const argv = yargs type: "boolean", default: false, }) + .option("trashed", { + alias: "t", + description: "Include trashed Keep notes", + type: "boolean", + default: false, + }) + .option("emoji", { + alias: "e", + description: "Include emoji in the output", + type: "string", + default: "", + }) + .option("metadata", { + alias: "d", + description: "Include additional metadata in the output", + type: "boolean", + default: false, + }) + .option("relation", { + alias: "r", + description: + "Include the description relation in the body of the object. Only works if metadata is enabled.", + type: "boolean", + default: false, + }) .demandOption(["path", "output"]) .help() .alias("help", "h").argv; +console.log("Settings:", argv); + if (argv.path === argv.output) { console.error(`Error: path and output cannot be the same`); process.exit(1); @@ -56,5 +87,9 @@ const settings: Settings = { output: argv.output, mode: argv.mode, includeArchive: argv.archive, + includeTrashed: argv.trashed, + includeMetadata: argv.metadata, + includeRelation: argv.relation, + emoji: argv.emoji, }; main(settings); diff --git a/src/keep/ingest.ts b/src/keep/ingest.ts index c30038c..a73fe4c 100644 --- a/src/keep/ingest.ts +++ b/src/keep/ingest.ts @@ -82,12 +82,24 @@ const isGoogleKeepNote = (object: any): object is GoogleKeepNote => { } } + if (object.labels) { + if (!Array.isArray(object.labels)) { + throw new Error("labels is not an array"); + } + for (const label of object.labels) { + if (typeof label.name !== "string") { + throw new Error("Invalid label item"); + } + } + } + return true; }; export const ingestKeepJsonFiles = async ( folderPath: string, - includeArchive: boolean + includeArchive: boolean, + includeTrashed: boolean ): Promise => { const notes: GoogleKeepNote[] = []; const files = await fs.readdir(folderPath); @@ -102,6 +114,9 @@ export const ingestKeepJsonFiles = async ( if (note.isArchived && !includeArchive) { continue; } + if (note.isTrashed && !includeTrashed) { + continue; + } notes.push(note); } catch (error: any) { throw new Error( diff --git a/src/keep/types.ts b/src/keep/types.ts index b24746d..60b83ea 100644 --- a/src/keep/types.ts +++ b/src/keep/types.ts @@ -15,6 +15,10 @@ interface Attachment { mimetype: string; } +export interface Label { + name: string; +} + export interface GoogleKeepNote { color: string; isTrashed: boolean; @@ -29,4 +33,5 @@ export interface GoogleKeepNote { createdTimestampUsec: number; sourceFilePath: string; sourceFileName: string; + labels?: Label[]; } diff --git a/src/main.ts b/src/main.ts index 2629cc8..88a3834 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,13 +11,18 @@ export const main = async (settings: Settings) => { output: outputFolderPath, mode, includeArchive, + includeTrashed, + includeMetadata, + includeRelation, + emoji, } = settings; let notes: GoogleKeepNote[] = []; try { const maybeNotes = await ingestKeepJsonFiles( inputFolderPath, - includeArchive + includeArchive, + includeTrashed ); notes = maybeNotes; } catch (err) { @@ -35,7 +40,13 @@ export const main = async (settings: Settings) => { for (const note of notes) { try { - const anyBlockPage = convertToAnyBlockPage(note, mode); + const anyBlockPage = convertToAnyBlockPage( + note, + mode, + emoji, + includeMetadata, + includeRelation + ); const filePath = await writeAnyBlockPageToFile( anyBlockPage, note.sourceFileName,