Skip to content

Commit

Permalink
Add notion cli (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroki0525 authored Nov 30, 2023
1 parent 00ffa59 commit 7f13f60
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-months-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@dandori/cli": patch
---

add notion cli
57 changes: 51 additions & 6 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,14 @@ pnpm --package=@dandori/cli dlx dandori-miro your_tasks.txt -b your_miro_board_i

* Please see [@dandori/core](../core/README.md) and [@dandori/ui](../ui/README.md) before using `@dandori/cli`.

## Supported External APIs

* [Miro](https://miro.com/)
* [Notion](https://www.notion.so/)

## Commands

### core
### dandori-core

This command is to execute `generateDandoriTasks` of `@dandori/core`.

Expand All @@ -50,23 +55,63 @@ Options:
-h, --help display help for command
```

### miro
#### Example of the command

```bash
pnpm --package=@dandori/cli dlx dandori-core your_tasks.txt > result.json
```

### dandori-miro

This command is to execute `generateDandoriMiroCards` of `@dandori/ui`.

```bash
% pnpm --package=@dandori/cli dlx dandori-miro -h

Usage: @dandori/cli <input-file> [options]

Options:
-V, --version output the version number
-e, --env-file <env-file> env file path
-m, --model <model> Chat GPT model which supports function_calling
-o, --optional-task-props <optional-task-props> optional output task props which delimiter is a comma
-a, --app-card
-b, --board-id <board-id>
-a, --app-card use app card
-b, --board-id <board-id> miro board id
-h, --help display help for command
```

## Supported External APIs
#### Example of the command

```bash
pnpm --package=@dandori/cli dlx dandori-miro your_tasks.txt -b your_miro_board_id
```

### dandori-notion

* [Miro](https://miro.com/)
This command is to execute `generateDandoriNotionPages` of `@dandori/ui`.

```bash
% pnpm --package=@dandori/cli dlx dandori-notion -h

Usage: @dandori/cli <input-file> [options]

Options:
-V, --version output the version number
-e, --env-file <env-file> env file path
-m, --model <model> Chat GPT model which supports function_calling
-o, --optional-task-props <optional-task-props> optional output task props which delimiter is a comma
-d, --database-id <database-id> notion database id
--name <name> notion page name property
--deadline <deadline> notion page deadline property
--status <status> notion page status property
--status-todo <status-todo> notion page status todo property
--status-doing <status-doing> notion page status doing property
--status-done <status-done> notion page status done property
-h, --help display help for command
```

#### Example of the command

```bash
pnpm --package=@dandori/cli dlx dandori-miro your_tasks.txt -d your_database_id -o status --status 'Status' --status-todo 'ToDo' --status-doing 'Doing' --status-done 'Done 🙌'
```
6 changes: 4 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
"build": "tsup --config ../../tsup.config.ts",
"test": "vitest run",
"dev:core": "tsx src/core/cli.ts",
"dev:miro": "tsx src/miro/cli.ts tmp/tmp.txt -b uXjVMnCQ-0g="
"dev:miro": "tsx src/miro/cli.ts",
"dev:notion": "tsx src/notion/cli.ts"
},
"bin": {
"dandori-core": "./dist/core/cli.js",
"dandori-miro": "./dist/miro/cli.js"
"dandori-miro": "./dist/miro/cli.js",
"dandori-notion": "./dist/notion/cli.js"
},
"keywords": [],
"author": "Hiroki Miyaji",
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/miro/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default class DandoriMiroCli extends DandoriCoreCli {
protected override buildCommand() {
return super
.buildCommand()
.option("-a, --app-card")
.option("-b, --board-id <board-id>");
.option("-a, --app-card", "use app card")
.option("-b, --board-id <board-id>", "miro board id");
}
}
174 changes: 174 additions & 0 deletions packages/cli/src/notion/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import {
describe,
beforeEach,
afterEach,
vi,
expect,
it,
beforeAll,
afterAll,
Mock,
} from "vitest";
import { DandoriTask } from "@dandori/core";
import { generateDandoriNotionPages } from "@dandori/ui";
import DandoriMiroCli from "../index";
import { rm, writeFile } from "fs/promises";

const tasks: DandoriTask[] = [
{
id: "1",
name: "task1",
deadline: "2021-01-01",
description: "task1-description",
fromTaskIdList: [],
status: "todo",
},
];

vi.mock("@dandori/core", () => ({
default: vi.fn(() => tasks),
}));

vi.mock("@dandori/ui", () => ({
generateDandoriNotionPages: vi.fn(),
}));

const mockGenerateDandoriNotionPages = generateDandoriNotionPages as Mock;

describe("DandoriNotionCli", () => {
const inputFileName = "DandoriNotionCli.txt";
const inputFileText = "DandoriNotionCli";
const loadProcessArgv = (options: string[]) => {
process.argv = ["node", "cli.js", inputFileName, ...options];
};

beforeAll(async () => {
await writeFile(inputFileName, inputFileText);
});

afterAll(async () => {
await rm(inputFileName);
});

afterEach(() => {
process.argv = [];
vi.clearAllMocks();
});

describe("with -d option", () => {
const databaseId = "databaseId";

beforeEach(async () => {
loadProcessArgv(["-d", databaseId]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with database id", () => {
expect(mockGenerateDandoriNotionPages.mock.lastCall[1]).toContain({
databaseId,
});
});
});

describe("with --name option", () => {
const name = "Name";

beforeEach(async () => {
loadProcessArgv(["--name", name]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with databasePropertiesMap.name", () => {
expect(
mockGenerateDandoriNotionPages.mock.lastCall[1].databasePropertiesMap,
).toContain({
name,
});
});
});

describe("with --deadline option", () => {
const deadline = "Deadline";

beforeEach(async () => {
loadProcessArgv(["--deadline", deadline]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with databasePropertiesMap.deadline", () => {
expect(
mockGenerateDandoriNotionPages.mock.lastCall[1].databasePropertiesMap,
).toContain({
deadline,
});
});
});

describe("with --status option", () => {
const status = "Status";

beforeEach(async () => {
loadProcessArgv(["--status", status]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with databasePropertiesMap.status", () => {
expect(
mockGenerateDandoriNotionPages.mock.lastCall[1].databasePropertiesMap,
).toContain({
status,
});
});
});

describe("with --status-todo option", () => {
const statusTodo = "ToDo";

beforeEach(async () => {
loadProcessArgv(["--status-todo", statusTodo]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with databasePropertiesMap.status.todo", () => {
expect(
mockGenerateDandoriNotionPages.mock.lastCall[1].databasePropertiesMap,
).toContain({
"status.todo": statusTodo,
});
});
});

describe("with --status-doing option", () => {
const statusDoing = "Doing";

beforeEach(async () => {
loadProcessArgv(["--status-doing", statusDoing]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with databasePropertiesMap.status.doing", () => {
expect(
mockGenerateDandoriNotionPages.mock.lastCall[1].databasePropertiesMap,
).toContain({
"status.doing": statusDoing,
});
});
});

describe("with --status-done option", () => {
const statusDone = "Done";

beforeEach(async () => {
loadProcessArgv(["--status-done", statusDone]);
await new DandoriMiroCli().run();
});

it("call generateDandoriNotionPages with databasePropertiesMap.status.done", () => {
expect(
mockGenerateDandoriNotionPages.mock.lastCall[1].databasePropertiesMap,
).toContain({
"status.done": statusDone,
});
});
});
});
6 changes: 6 additions & 0 deletions packages/cli/src/notion/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env node

import DandoriNotionCli from "./index";

const cli = new DandoriNotionCli();
await cli.run();
39 changes: 39 additions & 0 deletions packages/cli/src/notion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { generateDandoriNotionPages } from "@dandori/ui";
import DandoriCoreCli from "../core";

export default class DandoriNotionCli extends DandoriCoreCli {
override async run(): Promise<void> {
const tasks = await this.generateDandoriTasks();
const opts = this.program.opts();
await generateDandoriNotionPages(tasks, {
databaseId: opts.databaseId,
databasePropertiesMap: {
name: opts.name,
deadline: opts.deadline,
description: opts.description,
status: opts.status,
"status.todo": opts.statusTodo,
"status.doing": opts.statusDoing,
"status.done": opts.statusDone,
},
});
}

protected override buildCommand() {
return super
.buildCommand()
.option("-d, --database-id <database-id>", "notion database id")
.option("--name <name>", "notion page name property")
.option("--deadline <deadline>", "notion page deadline property")
.option("--status <status>", "notion page status property")
.option("--status-todo <status-todo>", "notion page status todo property")
.option(
"--status-doing <status-doing>",
"notion page status doing property",
)
.option(
"--status-done <status-done>",
"notion page status done property",
);
}
}

0 comments on commit 7f13f60

Please sign in to comment.