notion-github 0.1.6 → 0.1.9

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.
Files changed (3) hide show
  1. package/README.md +62 -1
  2. package/dist/cli.js +119 -38
  3. package/package.json +5 -4
package/README.md CHANGED
@@ -1 +1,62 @@
1
- hello
1
+ # notion-github CLI
2
+
3
+ GitHub PR 생성을 자동화하는 CLI 도구입니다.
4
+
5
+ ## 설치
6
+
7
+ ```bash
8
+ npm install -g notion-github
9
+ ```
10
+
11
+ ## 사전 준비사항
12
+
13
+ 1. GitHub Personal Access Token 발급
14
+
15
+ - [GitHub Token 발급 가이드](./docs/GITHUB_TOKEN.md)를 참고하여 토큰을 발급받으세요.
16
+ - 발급받은 토큰을 환경변수로 설정:
17
+ ```bash
18
+ export GITHUB_TOKEN=your_token_here
19
+ ```
20
+
21
+ 2. Repository 접근 권한 확인
22
+ - PR을 생성하려는 repository에 대한 write 권한이 있어야 합니다.
23
+
24
+ ## 사용법
25
+
26
+ ### PR 생성
27
+
28
+ ```bash
29
+ pr-cli create --title "PR 제목" --description "PR 설명" --head feature/branch --repo owner/repo
30
+ ```
31
+
32
+ ### 필수 옵션
33
+
34
+ - `--title`: PR 제목
35
+ - `--head`: PR을 생성할 소스 브랜치
36
+ - `--repo`: 대상 레포지토리 (예: owner/repo)
37
+
38
+ ### 선택 옵션
39
+
40
+ - `--description`: PR 설명
41
+ - `--base`: PR을 병합할 대상 브랜치 (기본값: main)
42
+
43
+ ### 도움말
44
+
45
+ ```bash
46
+ pr-cli --help # 전체 도움말
47
+ pr-cli create --help # create 명령어 도움말
48
+ ```
49
+
50
+ ## 라이선스
51
+
52
+ MIT
53
+
54
+ ## 설정
55
+
56
+ 1. 홈 디렉토리에 `notion_github_config.json` 파일을 생성합니다:
57
+
58
+ ```json
59
+ {
60
+ "githubToken": "your_github_token_here"
61
+ }
62
+ ```
package/dist/cli.js CHANGED
@@ -927,9 +927,9 @@ var require_command = __commonJS({
927
927
  "use strict";
928
928
  var EventEmitter = require("events").EventEmitter;
929
929
  var childProcess = require("child_process");
930
- var path = require("path");
931
- var fs = require("fs");
932
- var process = require("process");
930
+ var path2 = require("path");
931
+ var fs2 = require("fs");
932
+ var process2 = require("process");
933
933
  var { Argument: Argument2, humanReadableArgName } = require_argument();
934
934
  var { CommanderError: CommanderError2 } = require_error();
935
935
  var { Help: Help2 } = require_help();
@@ -975,10 +975,10 @@ var require_command = __commonJS({
975
975
  this._showHelpAfterError = false;
976
976
  this._showSuggestionAfterError = true;
977
977
  this._outputConfiguration = {
978
- writeOut: (str) => process.stdout.write(str),
979
- writeErr: (str) => process.stderr.write(str),
980
- getOutHelpWidth: () => process.stdout.isTTY ? process.stdout.columns : void 0,
981
- getErrHelpWidth: () => process.stderr.isTTY ? process.stderr.columns : void 0,
978
+ writeOut: (str) => process2.stdout.write(str),
979
+ writeErr: (str) => process2.stderr.write(str),
980
+ getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
981
+ getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
982
982
  outputError: (str, write) => write(str)
983
983
  };
984
984
  this._hidden = false;
@@ -1335,7 +1335,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1335
1335
  if (this._exitCallback) {
1336
1336
  this._exitCallback(new CommanderError2(exitCode, code, message));
1337
1337
  }
1338
- process.exit(exitCode);
1338
+ process2.exit(exitCode);
1339
1339
  }
1340
1340
  /**
1341
1341
  * Register callback `fn` for the command.
@@ -1666,8 +1666,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1666
1666
  }
1667
1667
  parseOptions = parseOptions || {};
1668
1668
  if (argv === void 0) {
1669
- argv = process.argv;
1670
- if (process.versions && process.versions.electron) {
1669
+ argv = process2.argv;
1670
+ if (process2.versions && process2.versions.electron) {
1671
1671
  parseOptions.from = "electron";
1672
1672
  }
1673
1673
  }
@@ -1680,7 +1680,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1680
1680
  userArgs = argv.slice(2);
1681
1681
  break;
1682
1682
  case "electron":
1683
- if (process.defaultApp) {
1683
+ if (process2.defaultApp) {
1684
1684
  this._scriptPath = argv[1];
1685
1685
  userArgs = argv.slice(2);
1686
1686
  } else {
@@ -1751,10 +1751,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1751
1751
  let launchWithNode = false;
1752
1752
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1753
1753
  function findFile(baseDir, baseName) {
1754
- const localBin = path.resolve(baseDir, baseName);
1755
- if (fs.existsSync(localBin)) return localBin;
1756
- if (sourceExt.includes(path.extname(baseName))) return void 0;
1757
- const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
1754
+ const localBin = path2.resolve(baseDir, baseName);
1755
+ if (fs2.existsSync(localBin)) return localBin;
1756
+ if (sourceExt.includes(path2.extname(baseName))) return void 0;
1757
+ const foundExt = sourceExt.find((ext) => fs2.existsSync(`${localBin}${ext}`));
1758
1758
  if (foundExt) return `${localBin}${foundExt}`;
1759
1759
  return void 0;
1760
1760
  }
@@ -1765,41 +1765,41 @@ Expecting one of '${allowedValues.join("', '")}'`);
1765
1765
  if (this._scriptPath) {
1766
1766
  let resolvedScriptPath;
1767
1767
  try {
1768
- resolvedScriptPath = fs.realpathSync(this._scriptPath);
1768
+ resolvedScriptPath = fs2.realpathSync(this._scriptPath);
1769
1769
  } catch (err) {
1770
1770
  resolvedScriptPath = this._scriptPath;
1771
1771
  }
1772
- executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
1772
+ executableDir = path2.resolve(path2.dirname(resolvedScriptPath), executableDir);
1773
1773
  }
1774
1774
  if (executableDir) {
1775
1775
  let localFile = findFile(executableDir, executableFile);
1776
1776
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1777
- const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
1777
+ const legacyName = path2.basename(this._scriptPath, path2.extname(this._scriptPath));
1778
1778
  if (legacyName !== this._name) {
1779
1779
  localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
1780
1780
  }
1781
1781
  }
1782
1782
  executableFile = localFile || executableFile;
1783
1783
  }
1784
- launchWithNode = sourceExt.includes(path.extname(executableFile));
1784
+ launchWithNode = sourceExt.includes(path2.extname(executableFile));
1785
1785
  let proc;
1786
- if (process.platform !== "win32") {
1786
+ if (process2.platform !== "win32") {
1787
1787
  if (launchWithNode) {
1788
1788
  args.unshift(executableFile);
1789
- args = incrementNodeInspectorPort(process.execArgv).concat(args);
1790
- proc = childProcess.spawn(process.argv[0], args, { stdio: "inherit" });
1789
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1790
+ proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
1791
1791
  } else {
1792
1792
  proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1793
1793
  }
1794
1794
  } else {
1795
1795
  args.unshift(executableFile);
1796
- args = incrementNodeInspectorPort(process.execArgv).concat(args);
1797
- proc = childProcess.spawn(process.execPath, args, { stdio: "inherit" });
1796
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1797
+ proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
1798
1798
  }
1799
1799
  if (!proc.killed) {
1800
1800
  const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
1801
1801
  signals.forEach((signal) => {
1802
- process.on(signal, () => {
1802
+ process2.on(signal, () => {
1803
1803
  if (proc.killed === false && proc.exitCode === null) {
1804
1804
  proc.kill(signal);
1805
1805
  }
@@ -1808,10 +1808,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1808
1808
  }
1809
1809
  const exitCallback = this._exitCallback;
1810
1810
  if (!exitCallback) {
1811
- proc.on("close", process.exit.bind(process));
1811
+ proc.on("close", process2.exit.bind(process2));
1812
1812
  } else {
1813
1813
  proc.on("close", () => {
1814
- exitCallback(new CommanderError2(process.exitCode || 0, "commander.executeSubCommandAsync", "(close)"));
1814
+ exitCallback(new CommanderError2(process2.exitCode || 0, "commander.executeSubCommandAsync", "(close)"));
1815
1815
  });
1816
1816
  }
1817
1817
  proc.on("error", (err) => {
@@ -1826,7 +1826,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1826
1826
  throw new Error(`'${executableFile}' not executable`);
1827
1827
  }
1828
1828
  if (!exitCallback) {
1829
- process.exit(1);
1829
+ process2.exit(1);
1830
1830
  } else {
1831
1831
  const wrappedError = new CommanderError2(1, "commander.executeSubCommandAsync", "(error)");
1832
1832
  wrappedError.nestedError = err;
@@ -2292,11 +2292,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2292
2292
  */
2293
2293
  _parseOptionsEnv() {
2294
2294
  this.options.forEach((option) => {
2295
- if (option.envVar && option.envVar in process.env) {
2295
+ if (option.envVar && option.envVar in process2.env) {
2296
2296
  const optionKey = option.attributeName();
2297
2297
  if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
2298
2298
  if (option.required || option.optional) {
2299
- this.emit(`optionEnv:${option.name()}`, process.env[option.envVar]);
2299
+ this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
2300
2300
  } else {
2301
2301
  this.emit(`optionEnv:${option.name()}`);
2302
2302
  }
@@ -2564,7 +2564,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2564
2564
  * @return {Command}
2565
2565
  */
2566
2566
  nameFromFilename(filename) {
2567
- this._name = path.basename(filename, path.extname(filename));
2567
+ this._name = path2.basename(filename, path2.extname(filename));
2568
2568
  return this;
2569
2569
  }
2570
2570
  /**
@@ -2578,9 +2578,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2578
2578
  * @param {string} [path]
2579
2579
  * @return {string|null|Command}
2580
2580
  */
2581
- executableDir(path2) {
2582
- if (path2 === void 0) return this._executableDir;
2583
- this._executableDir = path2;
2581
+ executableDir(path3) {
2582
+ if (path3 === void 0) return this._executableDir;
2583
+ this._executableDir = path3;
2584
2584
  return this;
2585
2585
  }
2586
2586
  /**
@@ -2672,7 +2672,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2672
2672
  */
2673
2673
  help(contextOptions) {
2674
2674
  this.outputHelp(contextOptions);
2675
- let exitCode = process.exitCode || 0;
2675
+ let exitCode = process2.exitCode || 0;
2676
2676
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
2677
2677
  exitCode = 1;
2678
2678
  }
@@ -2789,21 +2789,102 @@ var {
2789
2789
  } = import_index.default;
2790
2790
 
2791
2791
  // package.json
2792
- var version = "0.1.6";
2792
+ var version = "0.1.9";
2793
+
2794
+ // src/commands/create/action.ts
2795
+ var import_rest = require("@octokit/rest");
2796
+
2797
+ // src/utils/config.ts
2798
+ var import_fs = __toESM(require("fs"));
2799
+ var import_path = __toESM(require("path"));
2800
+ var import_os = __toESM(require("os"));
2801
+ var CONFIG_FILE = "notion_github_config.json";
2802
+ function readConfig() {
2803
+ try {
2804
+ const currentDirPath = import_path.default.join(process.cwd(), CONFIG_FILE);
2805
+ const homeDirPath = import_path.default.join(import_os.default.homedir(), CONFIG_FILE);
2806
+ let configPath = "";
2807
+ if (import_fs.default.existsSync(currentDirPath)) {
2808
+ configPath = currentDirPath;
2809
+ } else if (import_fs.default.existsSync(homeDirPath)) {
2810
+ configPath = homeDirPath;
2811
+ } else {
2812
+ throw new Error(
2813
+ `Config file not found. Please create ${CONFIG_FILE} in your project directory or home directory.`
2814
+ );
2815
+ }
2816
+ const config = JSON.parse(import_fs.default.readFileSync(configPath, "utf8"));
2817
+ if (!config.githubToken) {
2818
+ throw new Error("GitHub token not found in config file.");
2819
+ }
2820
+ return config;
2821
+ } catch (error) {
2822
+ if (error instanceof Error) {
2823
+ throw new Error(`Failed to read config: ${error.message}`);
2824
+ }
2825
+ throw error;
2826
+ }
2827
+ }
2793
2828
 
2794
2829
  // src/commands/create/action.ts
2795
2830
  async function action(options) {
2796
- console.log("Create command called with:", options);
2831
+ try {
2832
+ const config = readConfig();
2833
+ const octokit = new import_rest.Octokit({ auth: config.githubToken });
2834
+ const [owner, repo] = options.repo.split("/");
2835
+ if (!owner || !repo) {
2836
+ throw new Error("Invalid repository format. Use 'owner/repo' format.");
2837
+ }
2838
+ console.log("Creating PR...");
2839
+ const response = await octokit.pulls.create({
2840
+ owner,
2841
+ repo,
2842
+ title: options.title,
2843
+ head: options.head,
2844
+ base: options.base || "main",
2845
+ body: options.description
2846
+ });
2847
+ console.log(`PR created successfully: ${response.data.html_url}`);
2848
+ } catch (error) {
2849
+ if (error instanceof Error) {
2850
+ console.error("Failed to create PR:", error.message);
2851
+ } else {
2852
+ console.error("An unknown error occurred");
2853
+ }
2854
+ process.exit(1);
2855
+ }
2797
2856
  }
2798
2857
 
2799
2858
  // src/commands/create/index.ts
2800
2859
  function createCommand2(program3) {
2801
- program3.command("create").description("Create a new PR").requiredOption("--title <title>", "PR title").option("--description <description>", "PR description").option("--branch <branch>", "Target branch", "main").action(action);
2860
+ program3.command("create").description("Create a new PR").requiredOption("--title <title>", "PR title").requiredOption("--head <head>", "Head branch").requiredOption("--repo <repo>", "Repository (owner/repo)").option("--description <description>", "PR description").option("--base <base>", "Base branch", "main").action(action);
2861
+ }
2862
+
2863
+ // src/commands/debug/action.ts
2864
+ async function action2(options) {
2865
+ try {
2866
+ const config = readConfig();
2867
+ console.log("Current Configuration:");
2868
+ console.log(JSON.stringify(config, null, 2));
2869
+ } catch (error) {
2870
+ if (error instanceof Error) {
2871
+ console.error("Debug failed:", error.message);
2872
+ } else {
2873
+ console.error("An unknown error occurred");
2874
+ }
2875
+ process.exit(1);
2876
+ }
2877
+ }
2878
+
2879
+ // src/commands/debug/index.ts
2880
+ function debugCommand(program3) {
2881
+ program3.command("debug").description("Show debug information").option("--config", "Show configuration").action(action2);
2802
2882
  }
2803
2883
 
2804
2884
  // src/commands/index.ts
2805
2885
  function registerCommands(program3) {
2806
2886
  createCommand2(program3);
2887
+ debugCommand(program3);
2807
2888
  }
2808
2889
 
2809
2890
  // src/cli.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notion-github",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "description": "GitHub and Notion integration for PR automation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -18,15 +18,16 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "devDependencies": {
21
- "@types/node": "^16.0.0",
21
+ "@types/node": "^16.18.124",
22
22
  "tsup": "^8.0.0",
23
23
  "typescript": "^5.0.0"
24
24
  },
25
25
  "dependencies": {
26
26
  "@changesets/cli": "^2.27.11",
27
27
  "@notionhq/client": "^2.0.0",
28
- "@octokit/rest": "^19.0.0",
29
- "commander": "^11.0.0"
28
+ "@octokit/rest": "^19.0.13",
29
+ "commander": "^11.0.0",
30
+ "dotenv": "^16.4.7"
30
31
  },
31
32
  "bin": {
32
33
  "pr-cli": "dist/cli.js"