npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

notion-json-lens

v1.0.6

Published

Bi-directional converter between Notion database properties format and a plain JSON object

Downloads

11

Readme

notion-json-lens

A bi-directional converter between Notion's DB properties and a simple plain JSON object.

Motivation

Notion's type objects definition for a DB items' properties can be tricky to work with. To get the value of any column, you need to know it's type and the object format of that type according to the Type Objects Reference.

For example. A column of type Text in a notion DB is represented as:

{
    ...
    "properties": {
        "column_name": {
            "id": "HbZT",
            "type": "rich_text",
            "rich_text": [
                {
                "type": "text",
                "text": {
                    "content": "There is some text here",
                    "link": null
                },
                "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                },
                "plain_text": "There is some text here",
                "href": null
                },
            ]
        }
    }
}

To get the column's value you need to use item.properties.column_name.rich_text[0].plain_text 😰 (not to mention specific cases like if there are multiple blocks of rich_text in there).

Most times you just need a simple path to access an item's properties such as item.properties.column_name with no need to worry about the type of that columnm.

This is where this library comes in.

How it works

The lens provides transformation in two directions, each implemented with a different function:

  • notionToJson
  • jsonToNotion

The lens will only be applied to the properties node of the item. Other data points outside the properties object are not contemplated in the transformation.

The name of the columns and json fields is preserved during a transformation. The lens is agnostic on the naming convention of the DB and object model, not performing any alterations on the columns and fields names, just its contents.

Notion to JSON

Transforms a Notion DB item properties object into a flat JSON.

Transformed types:

  • Title
  • Text
  • Number
  • Select
  • Multi Select
  • Status
  • Date
  • Checkbox
  • URL
  • Unique Id

Columns with types not in the list above are returned as-is to preserve information. Support to more types coming in the future...

import { notionToJson } from "notion-json-lens";

const sampleNotionDbProperties = {
    Title: {
        id: "title",
        type: "title",
        title: [
            {
                type: "text",
                text: {
                    content: "page 1",
                    link: null,
                },
                annotations: {
                    bold: false,
                    italic: false,
                    strikethrough: false,
                    underline: false,
                    code: false,
                    color: "default",
                },
                plain_text: "page 1",
                href: null,
            },
        ],
    },
    Description: {
        id: "HbZT",
        type: "rich_text",
        rich_text: [
            {
                type: "text",
                text: {
                    content: "There is some ",
                    link: null,
                },
                annotations: {
                    bold: false,
                    italic: false,
                    strikethrough: false,
                    underline: false,
                    code: false,
                    color: "default",
                },
                plain_text: "There is some ",
                href: null,
            },
            {
                type: "text",
                text: {
                    content: "text",
                    link: null,
                },
                annotations: {
                    bold: true,
                    italic: false,
                    strikethrough: false,
                    underline: false,
                    code: false,
                    color: "default",
                },
                plain_text: "text",
                href: null,
            },
            {
                type: "text",
                text: {
                    content: " in this property!",
                    link: null,
                },
                annotations: {
                    bold: false,
                    italic: false,
                    strikethrough: false,
                    underline: false,
                    code: false,
                    color: "default",
                },
                plain_text: " in this property!",
                href: null,
            },
        ],
    },
    Number: {
        id: "DT%3Eg",
        type: "number",
        number: 2,
    },
    Select: {
        id: "FSau",
        type: "select",
        select: {
            id: "b5b79bb7-e513-4513-9c0f-8cf81392b189",
            name: "option 1",
            color: "red",
        },
    },
    "Multi Select": {
        id: "%3EP%60%7D",
        type: "multi_select",
        multi_select: [
            {
                id: "82303241-ae20-4690-bd0b-349a1528954c",
                name: "option 2",
                color: "red",
            },
            {
                id: "d521ee51-b4ad-468d-979a-d230875c1cf8",
                name: "option 1",
                color: "green",
            },
        ],
    },
    Status: {
        id: "ynbl",
        type: "status",
        status: {
            id: "13edf371-8bb1-4d19-921d-a095831dfab0",
            name: "Done",
            color: "green",
        },
    },
    Date: {
        id: "MJSZ",
        type: "date",
        date: {
            start: "2024-03-16T00:00:00.000-05:00",
            end: "2024-03-17T00:00:00.000-05:00",
            time_zone: null,
        },
    },
    Checkbox: {
        id: "jWlx",
        type: "checkbox",
        checkbox: true,
    },
    URL: {
        id: "jWlx",
        type: "url",
        url: "https://www.notion.so",
    },
};

console.log(notionToJson(baseNotionObject.properties));

// Output:
// {
//     Title: "page 1",
//     Description: "There is some text in this property!",
//     Number: 2,
//     Select: "option 1",
//     "Multi Select": ["option 2", "option 1"],
//     Status: "Done",
//     Date: {
//         start: "2024-03-16T00:00:00.000-05:00",
//         end: "2024-03-17T00:00:00.000-05:00",
//     },
//     Checkbox: true,
//     URL: "https://www.notion.so",
// }

JSON to Notion

Transforms a JSON object that respects the format below to a properties node of a Notion DB item.

Transformed types:

  • Title
  • Text
  • Number
  • Select
  • Multi Select
  • Status
  • Date
  • Checkbox
  • URL

Unique Id is not supported in the JSON to Notion flow since the Id is not editable in Notion.

This side of the lens requires the Notion Table's schema to get the type information of each field and perform the appropriate conversion. The schema passed is the response of the Retrieve Database endpoint of Notion's API.

import { Client } from "@notionhq/client"; // standard Notion API client
import { jsonToNotion } from "notion-json-lens";

const notion = new Client({ auth: <YOUR NOTION API SECRET> });

(async () => {

    const dbSchema = await notion.databases.retrieve({
        database_id: <your database_id>,
    });

    const json = {
        Title: "page 1",
        Description: "There is some **text** in this property!",
        Number: 2,
        Select: "option 1",
        "Multi Select": ["option 2", "option 1"],
        Status: "Done",
        Date: {
            start: "2024-03-16T00:00:00.000-05:00",
            end: "2024-03-17T00:00:00.000-05:00",
        },
        Checkbox: true,
        URL: "https://www.notion.so",
    };

    console.log(jsonToNotion(json, dbSchema));

})()

// Output
// {
//   "Title": {
//       "title": [
//           {
//               "text": {
//                   "content": "page 1"
//               }
//           }
//       ]
//   },
//   "Number": {
//       "number": 2
//   },
//   "Select": {
//       "select": {
//           "name": "option 1"
//       }
//   },
//   "Multi Select": {
//       "multi_select": [
//           {
//               "name": "option 2"
//           },
//           {
//               "name": "option 1"
//           }
//       ]
//   },
//   "Status": {
//       "status": {
//           "name": "Done"
//       }
//   },
//   "Date": {
//       "date": {
//           "start": "2024-03-16T00:00:00.000-05:00",
//           "end": "2024-03-17T00:00:00.000-05:00"
//       }
//   },
//   "Checkbox": {
//       "checkbox": true
//   },
//   "URL": {
//       "url": "https://www.notion.so"
//   }
// }

Known issues

  • Currently the formatting information in rich_text columns is lost in the conversion. One idea is to use Markdown notation in the JSON side to represent markups supported by Notion, however this is not implemented yet
  • Not all Notion types are currently contemplated in the conversion. I decided to start with the ones I use the most for simplicity and add support to additional types as needed
    • If you are interested in using this lib with an unsupported type, let me know or open a pull request 😁
  • There's no validation of the JSON schema received as input in the JSON to Notion flow. Ideally, the lib would validate if the JSON fields respect the expected format before attempting to convert to avoid any exceptions. Also in the roadmap for the future

Shout-outs

The name of this project was inspired by Ink and Switch's Project Cambria even though the actual implementation is different.