@haustle/notion-orm 0.0.41 → 0.0.43

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/src/index.ts ADDED
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Responsible for consuming notion.config.js
3
+ */
4
+
5
+ import { Client } from "@notionhq/client";
6
+ import { GetDatabaseResponse } from "@notionhq/client/build/src/api-endpoints";
7
+ import { createTypescriptFileForDatabase } from "./GenerateTypes";
8
+ import * as ts from "typescript";
9
+ import fs from "fs";
10
+ import path from "path";
11
+
12
+ export const DATABASES_DIR = path.join(__dirname, "../../build", "databases");
13
+
14
+ export type NotionConfigType = {
15
+ auth: string;
16
+ databaseIds: string[];
17
+ };
18
+
19
+ export const createDatabaseTypes = async (args: NotionConfigType) => {
20
+ const { auth, databaseIds } = args;
21
+
22
+ // Making sure the user is passing valid arguments
23
+ if (!auth) {
24
+ console.error("Please pass a valid Notion Integration Key");
25
+ process.exit(1);
26
+ }
27
+
28
+ if (databaseIds.length < 0) {
29
+ console.error("Please pass some database Ids");
30
+ process.exit(1);
31
+ }
32
+
33
+ // Initialize client
34
+ const NotionClient = new Client({
35
+ auth: auth,
36
+ });
37
+
38
+ const databaseNames: string[] = [];
39
+ const databaseClassExportStatements: ts.ExportDeclaration[] = [];
40
+
41
+ // Remove the previous databases, so they can call get updated
42
+ fs.rmdir(DATABASES_DIR, () =>
43
+ console.log("Deleting current database types...")
44
+ );
45
+
46
+ for (const database_id of databaseIds) {
47
+ let dbOjbect: GetDatabaseResponse;
48
+
49
+ try {
50
+ // Get the database schema
51
+ dbOjbect = await NotionClient.databases.retrieve({
52
+ database_id,
53
+ });
54
+
55
+ // Create typescript file based on schema
56
+ const { databaseClassName, databaseId, databaseName } =
57
+ await createTypescriptFileForDatabase(dbOjbect);
58
+
59
+ databaseNames.push(databaseName);
60
+ databaseClassExportStatements.push(
61
+ databaseExportStatement({
62
+ databaseClassName,
63
+ })
64
+ );
65
+ } catch (e) {
66
+ console.error(e);
67
+ return { databaseNames: [] };
68
+ }
69
+ }
70
+
71
+ // Create a file that exports all databases
72
+ createDatabaseBarrelFile({
73
+ databaseClassExportStatements,
74
+ });
75
+ return { databaseNames };
76
+ };
77
+
78
+ // Create the export statement for database file file
79
+ // export { databaseName } from "./databaseName"
80
+ function databaseExportStatement(args: { databaseClassName: string }) {
81
+ const { databaseClassName } = args;
82
+ return ts.factory.createExportDeclaration(
83
+ undefined,
84
+ false,
85
+ ts.factory.createNamedExports([
86
+ ts.factory.createExportSpecifier(
87
+ false,
88
+ undefined,
89
+ ts.factory.createIdentifier(databaseClassName)
90
+ ),
91
+ ]),
92
+ ts.factory.createStringLiteral(`./${databaseClassName}`),
93
+ undefined
94
+ );
95
+ }
96
+
97
+ // Creates file that import all generated notion database Ids
98
+ function createDatabaseBarrelFile(args: {
99
+ databaseClassExportStatements: ts.Node[];
100
+ }) {
101
+ const { databaseClassExportStatements } = args;
102
+ const nodes = ts.factory.createNodeArray(databaseClassExportStatements);
103
+ const sourceFile = ts.createSourceFile(
104
+ "placeholder.ts",
105
+ "",
106
+ ts.ScriptTarget.ESNext,
107
+ true,
108
+ ts.ScriptKind.TS
109
+ );
110
+ const printer = ts.createPrinter();
111
+
112
+ const typescriptCodeToString = printer.printList(
113
+ ts.ListFormat.MultiLine,
114
+ nodes,
115
+ sourceFile
116
+ );
117
+
118
+ const transpileToJavaScript = ts.transpile(typescriptCodeToString, {
119
+ module: ts.ModuleKind.None,
120
+ target: ts.ScriptTarget.ES2015,
121
+ });
122
+
123
+ if (!fs.existsSync(DATABASES_DIR)) {
124
+ fs.mkdirSync(DATABASES_DIR);
125
+ }
126
+
127
+ // Create TypeScript and JavaScript file
128
+ fs.writeFileSync(
129
+ path.resolve(DATABASES_DIR, "index.ts"),
130
+ typescriptCodeToString
131
+ );
132
+ fs.writeFileSync(
133
+ path.resolve(DATABASES_DIR, "index.js"),
134
+ transpileToJavaScript
135
+ );
136
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Column types' for all query options
3
+ */
4
+ // import { PageObjectResponse }
5
+
6
+ import {
7
+ PageObjectResponse,
8
+ QueryDatabaseResponse,
9
+ } from "@notionhq/client/build/src/api-endpoints";
10
+
11
+ type columnDiscriminatedUnionTypes = PageObjectResponse["properties"];
12
+ export type NotionColumnTypes =
13
+ columnDiscriminatedUnionTypes[keyof columnDiscriminatedUnionTypes]["type"];
14
+ // type SupportedQueryableNotionColumnTypes = Exclude<NotionColumnTypes, "created_by" | >
15
+
16
+ export type SupportedNotionColumnTypes = Exclude<
17
+ NotionColumnTypes,
18
+ | "formula"
19
+ | "files"
20
+ | "people"
21
+ | "relation"
22
+ | "rollup"
23
+ | "created_by"
24
+ | "last_edited_by"
25
+ | "created_time"
26
+ | "last_edited_time"
27
+ >;
28
+
29
+ type TextPropertyFilters = {
30
+ equals: string;
31
+ does_not_equal: string;
32
+ contains: string;
33
+ does_not_contain: string;
34
+ starts_with: string;
35
+ ends_with: string;
36
+ is_empty: true;
37
+ is_not_empty: true;
38
+ };
39
+
40
+ type NumberPropertyFilters = {
41
+ equals: number;
42
+ does_not_equals: number;
43
+ greater_than: number;
44
+ less_than: number;
45
+ greater_than_or_equal_to: number;
46
+ less_than_or_equal_to: number;
47
+ is_empty: true;
48
+ is_not_empty: true;
49
+ };
50
+
51
+ type CheckBoxPropertyFilters = {
52
+ equals: boolean;
53
+ does_not_equal: boolean;
54
+ };
55
+
56
+ //
57
+ type SelectPropertyFilters<T> = {
58
+ equals: (T extends Array<any> ? T[number] : T) | (string & {});
59
+ does_not_equal: (T extends Array<any> ? T[number] : T) | (string & {});
60
+ is_empty: true;
61
+ is_not_empty: true;
62
+ };
63
+
64
+ // pay in array --> need to turn into union
65
+ type MultiSelectPropertyFilters<T> = {
66
+ contains: (T extends Array<any> ? T[number] : T) | (string & {});
67
+ does_not_contain: (T extends Array<any> ? T[number] : T) | (string & {});
68
+ is_empty: true;
69
+ is_not_empty: true;
70
+ };
71
+
72
+ type StatusPropertyFilters<T> = SelectPropertyFilters<T>;
73
+
74
+ type ISO8601Date = string;
75
+ type DatePropertyFilters = {
76
+ equals: ISO8601Date;
77
+ before: ISO8601Date;
78
+ after: ISO8601Date;
79
+ on_or_before: ISO8601Date;
80
+ is_empty: true;
81
+ is_not_empty: true;
82
+ on_or_after: string;
83
+ past_week: {};
84
+ past_month: {};
85
+ past_year: {};
86
+ this_week: {};
87
+ next_week: {};
88
+ next_month: {};
89
+ next_year: {};
90
+ };
91
+
92
+ export type FilterOptions<T = []> = {
93
+ rich_text: TextPropertyFilters;
94
+ title: TextPropertyFilters;
95
+ number: NumberPropertyFilters;
96
+ checkbox: CheckBoxPropertyFilters;
97
+ select: SelectPropertyFilters<T>;
98
+ multi_select: MultiSelectPropertyFilters<T>;
99
+ url: TextPropertyFilters;
100
+ date: DatePropertyFilters;
101
+ status: StatusPropertyFilters<T>;
102
+ email: TextPropertyFilters;
103
+ phone_number: TextPropertyFilters;
104
+ };
105
+
106
+ /**
107
+ * Types to build query object user types out
108
+ */
109
+
110
+ type ColumnNameToNotionColumnType<T> = Record<
111
+ keyof T,
112
+ SupportedNotionColumnTypes
113
+ >;
114
+ type ColumnNameToPossibleValues = Record<string, any>;
115
+ // T is a column name to column type
116
+ // Y is the collection type
117
+ export type SingleFilter<
118
+ Y extends Record<string, any>,
119
+ T extends ColumnNameToNotionColumnType<Y>
120
+ > = {
121
+ // Passing the type from collection
122
+ [Property in keyof Y]?: Partial<FilterOptions<Y[Property]>[T[Property]]>;
123
+ };
124
+
125
+ export type CompoundFilters<
126
+ Y extends Record<string, any>,
127
+ T extends Record<keyof Y, SupportedNotionColumnTypes>
128
+ > =
129
+ | { and: Array<SingleFilter<Y, T> | CompoundFilters<Y, T>> }
130
+ | { or: Array<SingleFilter<Y, T> | CompoundFilters<Y, T>> };
131
+
132
+ export type QueryFilter<
133
+ Y extends Record<string, any>,
134
+ T extends Record<keyof Y, SupportedNotionColumnTypes>
135
+ > = SingleFilter<Y, T> | CompoundFilters<Y, T>;
136
+
137
+ export type Query<
138
+ Y extends Record<string, any>,
139
+ T extends Record<keyof Y, SupportedNotionColumnTypes>
140
+ > = {
141
+ filter?: QueryFilter<Y, T>;
142
+ sort?: [];
143
+ };
144
+
145
+ export type apiFilterQuery = {
146
+ filter?: apiSingleFilter | apiAndFilter | apiOrFilter;
147
+ };
148
+
149
+ /**
150
+ * Transform the types above to build types to
151
+ * actually build schema for query request
152
+ */
153
+
154
+ type apiColumnTypeToOptions = {
155
+ [prop in keyof FilterOptions]?: Partial<FilterOptions[prop]>;
156
+ };
157
+ export interface apiSingleFilter extends apiColumnTypeToOptions {
158
+ property: string;
159
+ }
160
+
161
+ export type apiFilterType =
162
+ | apiSingleFilter
163
+ | apiAndFilter
164
+ | apiOrFilter
165
+ | undefined;
166
+ type apiAndFilter = {
167
+ and: Array<apiFilterType>;
168
+ };
169
+
170
+ type apiOrFilter = {
171
+ or: Array<apiFilterType>;
172
+ };
173
+
174
+ export type SimpleQueryResponse<DatabaseSchema> = {
175
+ results: Partial<DatabaseSchema>[];
176
+ rawResponse: QueryDatabaseResponse;
177
+ };