Skip to content

Commit

Permalink
Add new config options & flags (#8)
Browse files Browse the repository at this point in the history
* feat: augmented feats

Added two features which are allowed by the Notion endpoint API and can be useful to further
customize the export:
- recursive, allows to export one block and alla the block children
- no-files, to avoid downloading files like pdf or images (as it is optional from the UI)

Also, addeda function `getMdFiles` to dump the files in a folder (this is useful if we
want to use a function from langchain, for example, to load all files in a folder).

* chore: Readme updated

* chore: remove comment

* feat: added new flags

* Clean-up

* Introduce config object.

* Adapt readme.

---------

Co-authored-by: Guille <guillermo.c.martinez@dcsl.com>
  • Loading branch information
yannbolliger and Guille committed Feb 22, 2024
1 parent c7c353b commit 841f351
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 13 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ most accurate information.
#### Constructor

Provide the [required Cookies](#needed-cookies) as authentification to create a
new exporter client.
new exporter client. For configuration options,
[refer to the definition](./src/config.ts).

```ts
const exporter = new NotionExporter(tokenV2: string, fileToken: string)
const exporter = new NotionExporter(tokenV2: string, fileToken: string, config?: Config)
```

#### Methods
Expand Down Expand Up @@ -130,4 +131,5 @@ use-case? Please submit issues and PRs on Github.

### Contributors

- Yann Bolliger, [@yannbolliger](https://github.com/yannbolliger).
- Yann Bolliger, [@yannbolliger](https://github.com/yannbolliger)
- Guillermo C. Martínez, [@telekosmos](https://github.com/telekosmos)
13 changes: 8 additions & 5 deletions src/NotionExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import axios, { AxiosInstance } from "axios"
import AdmZip from "adm-zip"

import { blockIdFromUrl, validateUuid } from "./blockId"
import { Config, defaultConfig } from "./config"

interface Task {
id: string
Expand All @@ -12,6 +13,7 @@ interface Task {
/** Lightweight client to export ZIP, Markdown or CSV files from a Notion block/page. */
export class NotionExporter {
protected readonly client: AxiosInstance
private readonly config: Config

/**
* Create a new NotionExporter client. To export any blocks/pages from
Expand All @@ -21,13 +23,14 @@ export class NotionExporter {
* @param tokenV2 – the Notion `token_v2` Cookie value
* @param fileToken – the Notion `file_token` Cookie value
*/
constructor(tokenV2: string, fileToken: string) {
constructor(tokenV2: string, fileToken: string, config?: Config) {
this.client = axios.create({
baseURL: "https://www.notion.so/api/v3/",
headers: {
Cookie: `token_v2=${tokenV2};file_token=${fileToken}`,
},
})
this.config = Object.assign(defaultConfig, config)
}

/**
Expand All @@ -40,17 +43,17 @@ export class NotionExporter {
const id = validateUuid(blockIdFromUrl(idOrUrl))
if (!id) return Promise.reject(`Invalid URL or blockId: ${idOrUrl}`)

const { recursive, includeContents, ...config } = this.config
const res = await this.client.post("enqueueTask", {
task: {
eventName: "exportBlock",
request: {
block: { id },
recursive: false,
recursive,
exportOptions: {
exportType: "markdown",
timeZone: "Europe/Zurich",
locale: "en",
collectionViewExportType: "all",
includeContents: !includeContents ? "no_files" : undefined,
...config,
},
},
},
Expand Down
5 changes: 3 additions & 2 deletions src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import rl from "readline"
import { AxiosError } from "axios"

import { NotionExporter } from "./NotionExporter"
import { Config } from "./config"

export const FileType = ["md", "csv"] as const
type FileType = (typeof FileType)[number]
Expand All @@ -25,15 +26,15 @@ const askToken = (tokenName: string): Promise<string> => {
const envOrAskToken = async (tokenName: string) =>
process.env[tokenName] || (await askToken(tokenName))

const action = async (blockId: string, fileType: string) => {
const action = async (blockId: string, fileType: string, config?: Config) => {
if (!isFileType(fileType)) {
console.log(`File type (-t, --type) has to be one of: ${FileType}`)
process.exit(1)
}

const tokenV2 = await envOrAskToken("NOTION_TOKEN")
const fileToken = await envOrAskToken("NOTION_FILE_TOKEN")
const exporter = new NotionExporter(tokenV2, fileToken)
const exporter = new NotionExporter(tokenV2, fileToken, config)

const outputStr =
fileType === "csv"
Expand Down
19 changes: 19 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/** Configuration options that are passed to the Notion API. */
export interface Config {
/** Export embedded image and pdf files, not only the (text) content. Default: false */
includeContents?: boolean
/** Export children subpages recursively. Default: false */
recursive?: boolean
/** Default: UTC */
timeZone?: string
/** Default: en */
locale?: string
/** Export all blocks of the DB/page or just the ones in the current view. Default: "all" */
collectionViewExportType?: "currentView" | "all"
}

export const defaultConfig: Config = {
timeZone: "UTC",
locale: "en",
collectionViewExportType: "all",
}
17 changes: 14 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { NotionExporter } from "./NotionExporter"
import action, { FileType } from "./action"

export default NotionExporter
export { Config, defaultConfig } from "./config"

export const cli = (args: string[]) => {
const pkg = require("../package.json")
Expand All @@ -21,14 +22,24 @@ export const cli = (args: string[]) => {
© ${pkg.author}, 2022.`
)

.option("-t, --type", `File type to be exported: ${FileType}`, "md")
// .option("-o, --output", "Output path of the exported file, stdin if empty")
.option("-r, --recursive", "Export children subpages", false)
.option(
"-a, --all-files",
"Export image and pdf files, not only content",
false
)
.example(
"https://www.notion.so/Notion-Official-83715d7703ee4b8699b5e659a4712dd8"
)
.example("83715d7703ee4b8699b5e659a4712dd8 -t md")
.example("3af0a1e347dd40c5ba0a2c91e234b2a5 -t csv > list.csv")
// .example("83715d7703ee4b8699b5e659a4712dd8 -t md -o blog.md")
.action((blockId, opts) => action(blockId, opts.type))
.action((blockId, opts) =>
action(blockId, opts.type, {
includeContents: opts["all-files"],
recursive: opts.recursive,
})
)
.parse(args)
}

0 comments on commit 841f351

Please sign in to comment.