Skip to content
This repository has been archived by the owner on Jul 16, 2022. It is now read-only.

Commit

Permalink
feat: Notion 検索まで実装
Browse files Browse the repository at this point in the history
  • Loading branch information
technote-space committed Nov 25, 2021
1 parent b2957b0 commit 827ec69
Show file tree
Hide file tree
Showing 29 changed files with 1,335 additions and 333 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NOTION_SECRET=
NOTION_PARENT_ID=
NOTION_BASE_URL=https://api.notion.com/v1
NOTION_BASE_URL=https://api.notion.com
NOTION_VERSION=2021-08-16

# public
Expand Down
14 changes: 4 additions & 10 deletions aspida.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
require('dotenv').config();

module.exports = [
{
input: 'src/pages/api',
baseURL: `${process.env.NEXT_PUBLIC_API_ENDOPOINT ?? 'http://localhost:3000'}`,
},
{
input: 'src/infra/server/shared/database/notion/api',
baseURL: `${process.env.NOTION_BASE_URL ?? 'https://api.notion.com/v1'}`,
}
];
module.exports = {
input: 'src/pages/api',
baseURL: `${process.env.NEXT_PUBLIC_API_ENDOPOINT ?? 'http://localhost:3000'}`,
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@aspida/axios": "^1.7.1",
"@aspida/swr": "^1.7.1",
"@next/bundle-analyzer": "^12.0.4",
"@notionhq/client": "^0.4.9",
"axios": "^0.24.0",
"clsx": "^1.1.1",
"dayjs": "^1.10.7",
Expand Down
28 changes: 11 additions & 17 deletions schema/tag.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
{
"title": [
"table": "tags",
"name": "タグ",
"columns": [
{
"type": "text",
"text": {
"content": "タグ",
"link": null
}
}
],
"properties": {
"タグ名": {
"title": {}
"name": "タグ名",
"type": "title"
},
"ユーザー": {
"relation": {
"database_id": "${TAG_DB_ID}"
}
{
"name": "ユーザー",
"type": "relation",
"relation": "users"
}
}
}
]
}
64 changes: 31 additions & 33 deletions schema/task.json
Original file line number Diff line number Diff line change
@@ -1,43 +1,41 @@
{
"title": [
"table": "tasks",
"name": "タスク",
"columns": [
{
"type": "text",
"text": {
"content": "タスク",
"link": null
}
}
],
"properties": {
"タスク名": {
"title": {}
"name": "タスク名",
"type": "title"
},
"メモ": {
"rich_text": {}
{
"name": "メモ",
"type": "text"
},
"ステータス": {
"rich_text": {}
{
"name": "ステータス",
"type": "text"
},
"期日": {
"date": {}
{
"name": "期日",
"type": "datetime"
},
"作業見積": {
"number": {
"format": "number"
}
{
"name": "作業見積",
"type": "int"
},
"作業見積単位": {
"rich_text": {}
{
"name": "作業見積単位",
"type": "text"
},
"ユーザー": {
"relation": {
"database_id": "${USER_DB_ID}"
}
{
"name": "ユーザー",
"type": "relation",
"relation": "users"
},
"タグ": {
"relation": {
"database_id": "${TAG_DB_ID}"
}
{
"name": "タグ",
"type": "relation",
"relation": "tags",
"multiple": true
}
}
}
]
}
20 changes: 7 additions & 13 deletions schema/user.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
{
"title": [
"table": "users",
"name": "ユーザー",
"columns": [
{
"type": "text",
"text": {
"content": "ユーザー",
"link": null
}
"name": "ユーザー識別子",
"type": "title"
}
],
"properties": {
"ユーザー識別子": {
"title": {}
}
}
}
]
}
6 changes: 4 additions & 2 deletions src/__mocks__/env.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import type IEnv from '$/server/shared/env';
import { mockNotionBaseUrl } from '^/__mocks__/server';

export default class TestEnv implements IEnv {
public constructor(private env: Record<string, string>) {
this.env.NOTION_BASE_URL = mockNotionBaseUrl;
}

public getValue(key: string): string | never {
if (!(key in this.env)) {
throw Error();
throw Error('環境変数が設定されていません: ' + key);
}

const env = this.env[key];
if (env === undefined) {
throw Error();
throw Error('環境変数が設定されていません: ' + key);
}

return env;
Expand Down
8 changes: 2 additions & 6 deletions src/__mocks__/server.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import type { RestHandler } from 'msw';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import aspida from '@aspida/axios';
import notionApi from '@/server/shared/database/notion/api/$api';
import type { ApiInstance } from '@/server/shared/database/notion/api/$api';

const mockNotionBaseUrl = 'https://example.com';
export const mockNotionBaseUrl = 'https://example.com';
type Method = keyof typeof rest;
export const createHandler = (method: Method, path: string, status: number, jsonBody: any): RestHandler => rest[method](path, (req, res, ctx) => res(
ctx.status(status),
ctx.json(jsonBody),
));
export const createNotionHandler = (method: Method, path: string, status: number, jsonBody: any): RestHandler => createHandler(method, `${mockNotionBaseUrl}${path}`, status, jsonBody);
export const createNotionHandler = (method: Method, path: string, status: number, jsonBody: any): RestHandler => createHandler(method, `${mockNotionBaseUrl}/v1${path}`, status, jsonBody);
export const useMockServer = (handlers: RestHandler[]) => {
const server = setupServer(...handlers);
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
};
export const getNotionApi = () => notionApi(aspida(undefined, { baseURL: mockNotionBaseUrl })) as ApiInstance;
13 changes: 3 additions & 10 deletions src/config/registry.server.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import type { MigrationSchemas } from '^/usecase/migrationUseCase';
import { container } from 'tsyringe';
import Env from '@/server/shared/env';
import { IndexPageProps } from '@/web/pages/index/server';
import api from '@/server/shared/database/notion/api/$api';
import aspida from '@aspida/axios';
import userSchema from '../../schema/user.json';
import tagSchema from '../../schema/tag.json';
import taskSchema from '../../schema/task.json';
import Env from '@/server/shared/env';
import userSchema from '../../schema/user.json';

container.registerInstance('NotionClient', api(aspida()));
container.registerInstance('IEnv', Env);

// pages
container.registerSingleton('IIndexPageProps', IndexPageProps);

// schema
container.registerInstance('MigrationSchemas', {
'USER_DB_ID': userSchema,
'TAG_DB_ID': tagSchema,
'TASK_DB_ID': taskSchema,
} as MigrationSchemas);
container.registerInstance('MigrationSchemas', [userSchema, tagSchema, taskSchema] as MigrationSchemas);
82 changes: 77 additions & 5 deletions src/domain/server/shared/database.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,100 @@
export type CreateTableColumn = {
name: string;
} & ({
type: 'title' | 'number' | 'rich_text' | 'date';
type: 'title' | 'text' | 'datetime' | 'int';
} | {
type: 'relation';
database_id: string;
relation: string;
multiple?: boolean;
});
export type TableColumn = {
id: string;
name: string;
} & ({
type: 'pk' | 'title' | 'text' | 'datetime' | 'int';
} | {
type: 'relation';
relation_id: string;
multiple: boolean;
});
export type TableColumn = { id: string } & CreateTableColumn;
export type Table = {
id: string;
table: string;
name: string;
columns: TableColumn[];
};
export type CreateTableParam = {
table: string;
name: string;
columns: CreateTableColumn[];
};
type TextSearch = {
text: {
equals?: string;
does_not_equal?: string;
contains?: string;
does_not_contain?: string;
starts_with?: string;
ends_with?: string;
is_empty?: boolean;
is_not_empty?: boolean;
}
};
type IntSearch = {
int: {
equals?: number;
does_not_equal?: number;
greater_than?: number;
less_than?: number;
greater_than_or_equal_to?: number;
less_than_or_equal_to?: number;
is_empty?: boolean;
is_not_empty?: boolean;
}
};
type DatetimeSearch = {
datetime: {
equals?: string;
before?: string;
after?: string;
on_or_before?: string;
on_or_after?: string;
is_empty?: boolean;
is_not_empty?: boolean;
past_week?: boolean;
past_month?: boolean;
past_year?: boolean;
next_week?: boolean;
next_month?: boolean;
next_year?: boolean;
}
};
type RelationSearch = {
relation: {
contains?: string;
does_not_contain?: string;
is_empty?: boolean;
is_not_empty?: boolean;
};
};
export type SearchParams = {
filter?: Record<string, TextSearch | IntSearch | DatetimeSearch | RelationSearch>;
sort?: {
column: string;
direction: 'ascending' | 'descending';
};
pageSize?: number;
cursor?: string;
};
export type Primitive = number | string | boolean;
export type DatabaseRecord = Record<string, Primitive | Primitive[] | null>;

export default interface IDatabase<T> {
export default interface IDatabase<T extends DatabaseRecord> {
listTables(): Promise<Table[]>;

createTable(table: CreateTableParam): Promise<Table>;

pagination(table: string, key: string, value: string, pageSize: number, cursor?: string): Promise<T[]>;
search(table: string, params: SearchParams): Promise<{ results: T[]; hasMore: boolean; cursor: string | null }>;

find(table: string, pk: string, id: string): Promise<T | null>;

Expand Down
2 changes: 1 addition & 1 deletion src/domain/server/shared/env.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default interface IEnv {
getValue(key: string): string | never;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@
"type": "page_id",
"page_id": "12345678-e9f3-4cff-87c1-fc43c6e48eb7"
},
"url": "https://www.notion.so/55c8c723805e4279802d749613f9f84e"
"url": "https://www.notion.so/12345678805e4279802d749613f9f84e"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"object": "list",
"results": [],
"has_more": false,
"next_cursor": null
}

0 comments on commit 827ec69

Please sign in to comment.