@elumixor/notion-orm 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -0
- package/dist/ast/constants.d.ts +38 -0
- package/dist/cli.js +170953 -0
- package/dist/config/helpers.d.ts +10 -0
- package/dist/config/loadConfig.d.ts +5 -0
- package/dist/db-client/DatabaseClient.d.ts +47 -0
- package/dist/db-client/add.d.ts +44 -0
- package/dist/db-client/query.d.ts +17 -0
- package/dist/db-client/queryTypes.d.ts +162 -0
- package/dist/helpers.d.ts +6 -0
- package/dist/index.js +1803 -0
- package/dist/public-api.d.ts +7 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Notion ORM
|
|
2
|
+
|
|
3
|
+
⚠️ This package is Still in development 🏗️
|
|
4
|
+
|
|
5
|
+
A library to simplify adding and querying [Notion](https://notion.so/product) databases/tables. Giving typeahead/intellisense support on columns and expected column values on user specified databases. Built on top of [Notion API](https://developers.notion.com/)
|
|
6
|
+
|
|
7
|
+
Databases with the following column types are supported:
|
|
8
|
+
|
|
9
|
+
- Multi-select
|
|
10
|
+
- Select
|
|
11
|
+
- Status
|
|
12
|
+
- Date
|
|
13
|
+
- Text
|
|
14
|
+
- Url
|
|
15
|
+
- Checkbox
|
|
16
|
+
- Email
|
|
17
|
+
- Phone Number
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
The only requirement is a Notion Developer API key ([here](https://developers.notion.com/)) and database IDs you want. Be sure to connect your [integration](https://developers.notion.com/docs/working-with-databases#adding-pages-to-a-database) (🚧 *Permissions* section) with your tables
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @haustle/notion-orm --save-dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
At the root of your project run the CLI to scaffold a config file (defaults to JavaScript unless a `tsconfig.json` is present):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx notion init
|
|
31
|
+
# or
|
|
32
|
+
bun notion init
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
You can force a specific format with `--js` or `--ts`. You’ll need to pass your developer key and database IDs. How to get database IDs [here](https://developers.notion.com/docs/working-with-databases#adding-pages-to-a-database)
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// notion.config.ts (generated with `notion init --ts`)
|
|
39
|
+
|
|
40
|
+
// Be sure to create a .env.local file and add your NOTION_KEY
|
|
41
|
+
|
|
42
|
+
// If you don't have an API key, sign up for free
|
|
43
|
+
// [here](https://developers.notion.com)
|
|
44
|
+
|
|
45
|
+
const auth = process.env.NOTION_KEY || "your-notion-api-key-here";
|
|
46
|
+
const NotionConfig = {
|
|
47
|
+
auth,
|
|
48
|
+
databaseIds: [
|
|
49
|
+
// Add undashed database source IDs here (ex. "2a3c495da03c80bc99fe000bbf2be4bb")
|
|
50
|
+
// or use the following command to automatically update
|
|
51
|
+
// `notion add <database-source-id or URL>`
|
|
52
|
+
// If you decide to manually add database IDs, be sure to run
|
|
53
|
+
// `notion generate` to properly update the local database types
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default NotionConfig;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Execute the following command from the root project directory.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx notion generate
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Package Size**
|
|
67
|
+
Unpackaged size is 70.6KB and the installation size is 5.12MB (5.03MB from `@notionhq/client` dependency)
|
|
68
|
+
|
|
69
|
+
## Implementation
|
|
70
|
+
|
|
71
|
+
Databases can be imported via barrel file or from the individual database file. All database names will be camelCase 🐫.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
// Barrel Import (access to all databases)
|
|
75
|
+
import * as notion from "@haustle/notion-orm";
|
|
76
|
+
notion.databaseName.add();
|
|
77
|
+
notion.databaseName2.query();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
// Individual Database Import
|
|
82
|
+
import {
|
|
83
|
+
databaseName,
|
|
84
|
+
DatabaseSchemaType,
|
|
85
|
+
QuerySchemaType,
|
|
86
|
+
} from "@haustle/notion-orm/build/db/databaseName";
|
|
87
|
+
|
|
88
|
+
databaseName.add();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- `DatabaseSchemaType`: Object type accepted in the database’s `add()` function
|
|
92
|
+
- `QuerySchemaType`: Object type accepted in the database’s `query()` function
|
|
93
|
+
|
|
94
|
+
The following examples for querying & adding are for server-side calls. If you’re looking to use this framework to execute client-side calls (ex. button click add/query X) visit the [Client (React)](https://www.notion.so/Notion-ORM-README-fdd30271bf944a3e85cb999ec8d5447d) section after reading
|
|
95
|
+
|
|
96
|
+
**Adding**
|
|
97
|
+
|
|
98
|
+
Only required column required is the title.
|
|
99
|
+
|
|
100
|
+
```jsx
|
|
101
|
+
notion.books.add({
|
|
102
|
+
bookName: "Raphael, Painter in Rome: a Novel", // title
|
|
103
|
+
author: "Stephanie Storey", // text
|
|
104
|
+
status: "In progress", // status
|
|
105
|
+
numberOfPages: 307, // number
|
|
106
|
+
genre: ["Historical Fiction"], // multi-select
|
|
107
|
+
rating: "⭐️⭐️⭐️⭐️", // select
|
|
108
|
+
startDate: {
|
|
109
|
+
// date
|
|
110
|
+
start: "2023-01-01",
|
|
111
|
+
},
|
|
112
|
+
phone: "0000000000", // phone
|
|
113
|
+
email: "tyrus@haustle.studio", // email
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
All column types in Notion databases are mapped to a typescript type.
|
|
118
|
+
|
|
119
|
+
| Column Type | Object |
|
|
120
|
+
| ------------ | -------------- |
|
|
121
|
+
| Title | string |
|
|
122
|
+
| Text | string |
|
|
123
|
+
| Select | string |
|
|
124
|
+
| Multi-select | Array (string) |
|
|
125
|
+
| Status | string |
|
|
126
|
+
| Number | number |
|
|
127
|
+
| Date | Object |
|
|
128
|
+
| Phone number | string |
|
|
129
|
+
| Email | string |
|
|
130
|
+
|
|
131
|
+
**Querying**
|
|
132
|
+
|
|
133
|
+
For each column type you’ll be presented with the available querying filter. Find all filter conditions [here](https://developers.notion.com/reference/post-database-query-filter)
|
|
134
|
+
|
|
135
|
+
While the querying functionality works, it’s **not complete and there is room for user error**. For instance, the `filter` object should contain one child. Either the column name (signifies single filter), or `and` or `or` (signify compound filters). However there is no typecheck in place to stop adding multiple children
|
|
136
|
+
|
|
137
|
+
Unlike `add()` , there is no transformation after the inputted object. So the querying object you’re creating is exactly what you’d normally use to query the Notion API. Learn more about them [here](https://developers.notion.com/reference/post-database-query-filter)
|
|
138
|
+
|
|
139
|
+
Example of a single filter
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
notion.books.query({
|
|
143
|
+
filter: {
|
|
144
|
+
genre: {
|
|
145
|
+
contains: "Sci-Fi",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
sort: [
|
|
149
|
+
{
|
|
150
|
+
property: "name",
|
|
151
|
+
direction: "ascending",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
property: "Author name",
|
|
155
|
+
direction: "ascending",
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Example of compound filters, which is signified with `and` and `or`. You can nest these are far as you want (i.e `and` filters within `or` filter). Learn more [here](https://developers.notion.com/reference/post-database-query-filter#compound-filter-object)
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
await notion.books.query({
|
|
165
|
+
filter: {
|
|
166
|
+
or: [
|
|
167
|
+
{
|
|
168
|
+
genre: {
|
|
169
|
+
contains: "Sci-Fi",
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
genre: {
|
|
174
|
+
contains: "Biography",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Down below is what’s returned on a successful response. `results` being a simplified extracted version of the `rawResponse` (response from Notion API)
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
{
|
|
186
|
+
rawResponse: { /* Whatever Notion API returns */},
|
|
187
|
+
results: [
|
|
188
|
+
{
|
|
189
|
+
bookName: "How to Change Your Mind",
|
|
190
|
+
genre: ["Non-fiction"],
|
|
191
|
+
numberPages: 460,
|
|
192
|
+
rating: "⭐️⭐️⭐️⭐️"
|
|
193
|
+
},
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Client-side (React)
|
|
199
|
+
|
|
200
|
+
Notion API currently blocks calls from browser (per CORS)
|
|
201
|
+
|
|
202
|
+
You can get around this by creating API endpoints on stack of your choice. I’ve provided examples only for **Next.js**, but the high level implementation should work with any backend.
|
|
203
|
+
|
|
204
|
+
If you’re planning to only make server-side calls to your Notion database (from `GetStaticProps` or `GetServerSideProps`). These calls work totally fine, as these functions are executed server-side before page load. So you can ignore the proceeding steps
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
export const getStaticProps: GetStaticProps = async () => {
|
|
208
|
+
const response = await NotionClient.books.query({
|
|
209
|
+
filter: {
|
|
210
|
+
genre: {
|
|
211
|
+
is_not_empty: true,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
return {
|
|
216
|
+
props: {
|
|
217
|
+
apiResponse: response
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
To execute calls client-side (ex. on button click) an API endpoint is needed to get around CORS. In this example we’re passing the databases `DatabaseSchemaType` as the body of the API call.
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
import { DatabaseSchemaType } from "@haustle/notion-orm/build/db/books";
|
|
226
|
+
|
|
227
|
+
async function addPageToNotionDatabase() {
|
|
228
|
+
const example: DatabaseSchemaType = {
|
|
229
|
+
bookName: "How to Change Your Mind",
|
|
230
|
+
genre: ["Non-fiction"],
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// make sure this route reflects your API path
|
|
234
|
+
await fetch("/api/notion/books", {
|
|
235
|
+
method: "POST",
|
|
236
|
+
body: JSON.stringify(example),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```jsx
|
|
242
|
+
<button onClick={ async() => await addPageToNotionDatabase()}>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Example API endpoint below, where we’re taking the body of type `DatabaseSchemaType` and passing it into the respected databases `add()` function to add a new page to the database. Learn more about _Next.js_ API’s and routing [here](https://nextjs.org/docs/api-routes/introduction).
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
// pages/api/notion/yourDatabaseName.ts
|
|
249
|
+
|
|
250
|
+
import type { NextApiRequest, NextApiResponse } from "next";
|
|
251
|
+
import {
|
|
252
|
+
DatabaseSchemaType,
|
|
253
|
+
yourDatabaseName,
|
|
254
|
+
} from "@haustle/notion-orm/build/db/yourDatabaseName";
|
|
255
|
+
|
|
256
|
+
export default async function handler(
|
|
257
|
+
req: NextApiRequest,
|
|
258
|
+
res: NextApiResponse
|
|
259
|
+
) {
|
|
260
|
+
const { method, body } = req;
|
|
261
|
+
|
|
262
|
+
if (method === "POST") {
|
|
263
|
+
const bodyJSON = JSON.parse(body) as DatabaseSchemaType;
|
|
264
|
+
await yourDatabaseName.add(bodyJSON);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal constants for AST and db-client modules.
|
|
3
|
+
*/
|
|
4
|
+
/** Generated DB files directory — always relative to the consuming project */
|
|
5
|
+
export declare const DATABASES_DIR: string;
|
|
6
|
+
/** File system paths for CLI output */
|
|
7
|
+
export declare const AST_FS_PATHS: {
|
|
8
|
+
/** metadata.json inside generated/ */
|
|
9
|
+
readonly metadataFile: string;
|
|
10
|
+
/** src/index.ts — the dynamic barrel rewritten on every generate */
|
|
11
|
+
readonly sourceIndexTs: string;
|
|
12
|
+
/** generated/index.ts — barrel exporting all DB clients */
|
|
13
|
+
readonly generatedBarrelTs: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const AST_FS_FILENAMES: {
|
|
16
|
+
readonly METADATA: "metadata.json";
|
|
17
|
+
readonly INDEX_TS: "index.ts";
|
|
18
|
+
};
|
|
19
|
+
/** Import path strings used when generating TypeScript code */
|
|
20
|
+
export declare const AST_IMPORT_PATHS: {
|
|
21
|
+
readonly DATABASE_CLIENT: "../src/db-client/DatabaseClient" | "@elumixor/notion-orm";
|
|
22
|
+
readonly QUERY_TYPES: "@elumixor/notion-orm" | "../src/db-client/queryTypes";
|
|
23
|
+
readonly ZOD: "zod";
|
|
24
|
+
readonly databaseClass: (className: string) => string;
|
|
25
|
+
};
|
|
26
|
+
export declare const AST_RUNTIME_CONSTANTS: {
|
|
27
|
+
readonly NOTION_API_VERSION: "2025-09-03";
|
|
28
|
+
readonly PACKAGE_LOG_PREFIX: "[@elumixor/notion-orm]";
|
|
29
|
+
readonly CLI_GENERATE_COMMAND: "notion generate";
|
|
30
|
+
readonly SCHEMA_DRIFT_PREFIX: "Schema drift detected";
|
|
31
|
+
readonly SCHEMA_DRIFT_HELP_MESSAGE: "Run `notion generate` to refresh all database schemas.";
|
|
32
|
+
};
|
|
33
|
+
export declare const AST_TYPE_NAMES: {
|
|
34
|
+
readonly DATABASE_SCHEMA_TYPE: "DatabaseSchemaType";
|
|
35
|
+
readonly COLUMN_NAME_TO_COLUMN_TYPE: "ColumnNameToColumnType";
|
|
36
|
+
readonly QUERY_SCHEMA_TYPE: "QuerySchemaType";
|
|
37
|
+
readonly PROPERTY_VALUES_SUFFIX: "PropertyValues";
|
|
38
|
+
};
|