diff --git a/.changeset/purple-foxes-approve.md b/.changeset/purple-foxes-approve.md new file mode 100644 index 0000000..d0075fd --- /dev/null +++ b/.changeset/purple-foxes-approve.md @@ -0,0 +1,6 @@ +--- +"@dandori/libs": patch +"@dandori/ui": patch +--- + +add inject api key option diff --git a/package.json b/package.json index 06cdfad..5bd3df2 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "prettier": "3.1.0", "tsup": "^8.0.1", "tsx": "^4.6.2", - "turbo": "^1.11.0", + "turbo": "^1.11.1", "typescript": "5.3.3", "vitest": "^0.34.6" }, diff --git a/packages/libs/src/__tests__/checkApiKey.test.ts b/packages/libs/src/__tests__/checkApiKey.test.ts new file mode 100644 index 0000000..d640b6b --- /dev/null +++ b/packages/libs/src/__tests__/checkApiKey.test.ts @@ -0,0 +1,40 @@ +import { describe, it, expect } from "vitest"; +import { checkApiKey } from "../index"; + +describe("checkApiKey", () => { + const keyName = "keyName"; + const targetKey = "targetKey"; + const alternativeKey = "alternativeKey"; + + describe("with targetKey", () => { + describe("with alternativeKey", () => { + it("returns targetKey", () => { + expect(checkApiKey(keyName, targetKey, alternativeKey)).toBe(targetKey); + }); + }); + + describe("without alternativeKey", () => { + it("returns targetKey", () => { + expect(checkApiKey(keyName, targetKey, undefined)).toBe(targetKey); + }); + }); + }); + + describe("without targetKey", () => { + describe("with alternativeKey", () => { + it("returns alternativeKey", () => { + expect(checkApiKey(keyName, undefined, alternativeKey)).toBe( + alternativeKey, + ); + }); + }); + + describe("without alternativeKey", () => { + it("throw error", () => { + expect(() => checkApiKey(keyName, undefined, undefined)).toThrow( + `Please set ${keyName}.`, + ); + }); + }); + }); +}); diff --git a/packages/libs/src/checkApiKey.ts b/packages/libs/src/checkApiKey.ts new file mode 100644 index 0000000..331e4f4 --- /dev/null +++ b/packages/libs/src/checkApiKey.ts @@ -0,0 +1,13 @@ +export function checkApiKey( + keyName: string, + targetKey?: string, + alternativeKey?: string, +): string { + if (targetKey) { + return targetKey; + } + if (alternativeKey) { + return alternativeKey; + } + throw new Error(`Please set ${keyName}.`); +} diff --git a/packages/libs/src/index.ts b/packages/libs/src/index.ts index 7a6f6ba..36e7a1c 100644 --- a/packages/libs/src/index.ts +++ b/packages/libs/src/index.ts @@ -2,3 +2,4 @@ export * from "./loadFile"; export * from "./loadEnvFile"; export * from "./logger"; export * from "./runPromisesSequentially"; +export * from "./checkApiKey"; diff --git a/packages/ui/README.md b/packages/ui/README.md index 41427fa..fbf118e 100644 --- a/packages/ui/README.md +++ b/packages/ui/README.md @@ -67,6 +67,7 @@ The tasks which are generated by `generateDandoriTasks` of `@dandori/core`. interface GenerateDandoriMiroCardsOptions { boardId: string; isAppCard?: boolean; + apiKey?: string; } ``` @@ -84,6 +85,12 @@ For example, if the url is `https://miro.com/app/board/1234567890/`, the board i If you set `true` , the cards are created as [App cards](https://developers.miro.com/docs/app-card). +* apiKey + +The api key of miro. You can also set `MIRO_API_KEY` environment variable instead of this option. + +```ts + ### generateDandoriNotionTasks ```ts @@ -109,6 +116,7 @@ The tasks which are generated by `generateDandoriTasks` of `@dandori/core`. interface GenerateDandoriNotionPagesOptions { databaseId: string; databasePropertiesMap?: DatabasePropertiesMap; + apuKey?: string; } ``` @@ -169,4 +177,8 @@ This is an example. In this case, the output is like belows. notion output example -For more details about database properties, please see [Notion API](https://developers.notion.com/reference/page#page-property-value). \ No newline at end of file +For more details about database properties, please see [Notion API](https://developers.notion.com/reference/page#page-property-value). + +* apiKey + +The api key of miro. You can also set `NOTION_API_KEY` environment variable instead of this option. \ No newline at end of file diff --git a/packages/ui/src/__tests__/miro.test.ts b/packages/ui/src/__tests__/miro.test.ts index 858ba51..a100315 100644 --- a/packages/ui/src/__tests__/miro.test.ts +++ b/packages/ui/src/__tests__/miro.test.ts @@ -30,6 +30,7 @@ vi.mock("@dandori/libs", () => { runPromisesSequentially: vi.fn((runPromises, _runningLogPrefix) => Promise.all(runPromises.map((runPromise: () => any) => runPromise())), ), + checkApiKey: vi.fn(), }; }); diff --git a/packages/ui/src/__tests__/notion.test.ts b/packages/ui/src/__tests__/notion.test.ts index df67f9d..23d59c1 100644 --- a/packages/ui/src/__tests__/notion.test.ts +++ b/packages/ui/src/__tests__/notion.test.ts @@ -38,6 +38,7 @@ vi.mock("@dandori/libs", () => { runPromisesSequentially: vi.fn((runPromises, _runningLogPrefix) => Promise.all(runPromises.map((runPromise: () => any) => runPromise())), ), + checkApiKey: vi.fn(), }; }); diff --git a/packages/ui/src/miro.ts b/packages/ui/src/miro.ts index 2359442..d155ff0 100644 --- a/packages/ui/src/miro.ts +++ b/packages/ui/src/miro.ts @@ -2,11 +2,17 @@ import { MiroApi } from "@mirohq/miro-api"; import { DandoriTask } from "@dandori/core"; import FlatToNested from "flat-to-nested"; import TreeModel from "tree-model"; -import { getLogger, getLogLevel, runPromisesSequentially } from "@dandori/libs"; +import { + checkApiKey, + getLogger, + getLogLevel, + runPromisesSequentially, +} from "@dandori/libs"; export type GenerateDandoriMiroCardsOptions = { boardId: Parameters[0]; isAppCard?: boolean; + apiKey?: string; }; // miro settings @@ -53,14 +59,15 @@ export async function generateDandoriMiroCards( tasks: DandoriTask[], options: GenerateDandoriMiroCardsOptions, ): Promise { - const logger = getLogger(); - const miroApi = new MiroApi( + const key = checkApiKey( + "miro api key", process.env.MIRO_API_KEY, - undefined, - (...thing) => { - logger[getLogLevel()](thing); - }, + options.apiKey, ); + const logger = getLogger(); + const miroApi = new MiroApi(key, undefined, (...thing) => { + logger[getLogLevel()](thing); + }); const miroBoard = await miroApi.getBoard(options.boardId); const taskFlat: (DandoriTask & { [taskParentPropName]?: string })[] = tasks .map((task) => diff --git a/packages/ui/src/notion.ts b/packages/ui/src/notion.ts index b7d3e3b..aca45b4 100644 --- a/packages/ui/src/notion.ts +++ b/packages/ui/src/notion.ts @@ -5,7 +5,12 @@ import { DandoriTaskStatus, } from "@dandori/core"; import { Client, LogLevel } from "@notionhq/client"; -import { getLogger, getLogLevel, runPromisesSequentially } from "@dandori/libs"; +import { + checkApiKey, + getLogger, + getLogLevel, + runPromisesSequentially, +} from "@dandori/libs"; type SupportNotionTaskOptionalProperty = Exclude< DandoriTaskOptionalProperty, @@ -56,6 +61,7 @@ export type DatabasePropertiesMap = export type GenerateDandoriNotionPagesOptions = { databaseId: string; databasePropertiesMap?: DatabasePropertiesMap; + apiKey?: string; }; const hasStatusProperty = ( @@ -145,9 +151,14 @@ export async function generateDandoriNotionPages( tasks: DandoriTask[], options: GenerateDandoriNotionPagesOptions, ): Promise { + const key = checkApiKey( + "notion api key", + process.env.NOTION_API_KEY, + options.apiKey, + ); const logger = getLogger(); const client = new Client({ - auth: process.env.NOTION_API_KEY, + auth: key, logLevel: getNotionLogLevel(), logger: ( level: LogLevel, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf6ea4e..7e6728b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,8 +57,8 @@ importers: specifier: ^4.6.2 version: 4.6.2 turbo: - specifier: ^1.11.0 - version: 1.11.0 + specifier: ^1.11.1 + version: 1.11.1 typescript: specifier: 5.3.3 version: 5.3.3 @@ -4411,64 +4411,64 @@ packages: yargs: 17.7.2 dev: true - /turbo-darwin-64@1.11.0: - resolution: {integrity: sha512-yLDeJ7QgpI1Niw87ydRNvygX67Dra+6MnxR88vwXnQJKsmHTKycBhY9w3Bhe5xvnIg4JoEWoEF5EJtw6ShrlEw==} + /turbo-darwin-64@1.11.1: + resolution: {integrity: sha512-JmwL8kcfxncDf2SZFioSa6dUvpMq/HbMcurh9mGm6BxWLQoB0d3fP/q3HizgCSbOE4ihScXoQ+c/C2xhl6Ngjg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.11.0: - resolution: {integrity: sha512-lZGlfTG6+u3R7+6eVY9j/07WpVF/tx8UNkmRWfMNt4ZGSEBMg6A+Vimvp+rni92WdPhD/rhxv+qYI/kco9hNXg==} + /turbo-darwin-arm64@1.11.1: + resolution: {integrity: sha512-lIpT7nPkU0xmpkI8VOGQcgoQKmUATRMpRhTDclz6j/Px7Qtxjc+2PitKHKfR3aCnseoRMGkgMzPEJTPUwCpnlQ==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.11.0: - resolution: {integrity: sha512-I88/WieHzTZ8V2y0j79RSjVERPp0IJTynTwLi7ddYX0PahkuyaHs1p8ktFMcs6awnJMeT6spaXlyzv5ZxnAdkg==} + /turbo-linux-64@1.11.1: + resolution: {integrity: sha512-mHFSqMkgy3h/M8Ocj2oiOr6CqlCqB6coCPWVIAmraBk+SQywwsszgJ69GWBfm7lwwJvb3B1YN1wkZNe9ZZnBfg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.11.0: - resolution: {integrity: sha512-jHsKuTFa7KwrA/FIxOnyXnfSEgDEUv0UVcseqQhP0VbdL+En93ZdBZ9S9/lI6VWooXrCqPooBmC+M/6jmwY/Ig==} + /turbo-linux-arm64@1.11.1: + resolution: {integrity: sha512-6ybojTkAkymo1Ig7kU3s2YQUUSRf3l2qatPZgw3v4OmFTSU2feCU1sHjAEqhHwEjV1KciDo1wRl1gjjyby4foQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.11.0: - resolution: {integrity: sha512-7u/1GoMallGDOTg4fnKoJmvBkf2pUCOcA0Z7NbwFB6GOa7q1Su4AaPs6Iy6Tyqrmj3vDHKSXByHwfz+o0cng/g==} + /turbo-windows-64@1.11.1: + resolution: {integrity: sha512-ytWy6+yEtBfv6nbgCKW6HsolgUFAC1PZGMPzbqRGnCm2eLVWhDuwO1Yk7uq4cvdrpXcXgOMcPEoJZxUCDbeJaQ==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.11.0: - resolution: {integrity: sha512-39MNaZ7RnbINEnpeAfB++fmH6p99RhbeeC8n2IXqG61Zrck5AA59Jm8DXpfOGR6Im93iHXSDox8qF3bb8V4amQ==} + /turbo-windows-arm64@1.11.1: + resolution: {integrity: sha512-O04DdJoRavOh/v9/MM5wWCEtOekO4aiLljNZc/fOh853sOhid61ZRSEYUmS9ecjmZ/OjKqedIfbkitaQ77c4xA==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.11.0: - resolution: {integrity: sha512-zIqJs/x1zzIIdwufhk80o7cQc9fIdHdweWRNXbK+Vjf9IaM2eSslcYyo40s+Kg/oiIOpdLM8hV7IUQst8KIyDA==} + /turbo@1.11.1: + resolution: {integrity: sha512-pmIsyTcyBJ5iJIaTjJyCxAq7YquDqyRai6FW2q0mFAkwK3k0p36wJ5yH85U2Ue6esrTKzeSEKskP4/fa7dv4+A==} hasBin: true optionalDependencies: - turbo-darwin-64: 1.11.0 - turbo-darwin-arm64: 1.11.0 - turbo-linux-64: 1.11.0 - turbo-linux-arm64: 1.11.0 - turbo-windows-64: 1.11.0 - turbo-windows-arm64: 1.11.0 + turbo-darwin-64: 1.11.1 + turbo-darwin-arm64: 1.11.1 + turbo-linux-64: 1.11.1 + turbo-linux-arm64: 1.11.1 + turbo-windows-64: 1.11.1 + turbo-windows-arm64: 1.11.1 dev: true /type-check@0.4.0: