backlog-exporter 0.2.3 → 0.5.0

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/README.md CHANGED
@@ -13,7 +13,8 @@ Backlog のデータをエクスポートするためのコマンドラインツ
13
13
  * [使用方法](#使用方法)
14
14
  * [課題のエクスポート](#課題のエクスポート)
15
15
  * [Wikiのエクスポート](#wikiのエクスポート)
16
- * [課題とWikiの一括エクスポート](#課題とwikiの一括エクスポート)
16
+ * [ドキュメントのエクスポート](#ドキュメントのエクスポート)
17
+ * [課題・Wiki・ドキュメントの一括エクスポート](#課題wikiドキュメントの一括エクスポート)
17
18
  * [データの更新](#データの更新)
18
19
  * [npxを使った課題のエクスポート](#npxを使った課題のエクスポート)
19
20
  * [npxを使ったデータの更新](#npxを使ったデータの更新)
@@ -23,7 +24,11 @@ Backlog のデータをエクスポートするためのコマンドラインツ
23
24
  * [Wiki のエクスポート](#wiki-のエクスポート)
24
25
  * [基本的な使用方法](#基本的な使用方法)
25
26
  * [出力先を指定](#出力先を指定)
26
- * [課題と Wiki の一括エクスポート](#課題と-wiki-の一括エクスポート)
27
+ * [ドキュメント のエクスポート](#ドキュメント-のエクスポート)
28
+ * [基本的な使用方法](#基本的な使用方法)
29
+ * [出力先を指定](#出力先を指定)
30
+ * [キーワード検索](#キーワード検索)
31
+ * [課題・Wiki・ドキュメント の一括エクスポート](#課題wikiドキュメント-の一括エクスポート)
27
32
  * [基本的な使用方法](#基本的な使用方法)
28
33
  * [出力先を指定](#出力先を指定)
29
34
  * [データの更新](#データの更新)
@@ -32,11 +37,13 @@ Backlog のデータをエクスポートするためのコマンドラインツ
32
37
  * [確認プロンプトをスキップして更新](#確認プロンプトをスキップして更新)
33
38
  * [課題のみを更新](#課題のみを更新)
34
39
  * [Wikiのみを更新](#wikiのみを更新)
40
+ * [ドキュメントのみを更新](#ドキュメントのみを更新)
35
41
  * [APIキーを指定して更新](#apiキーを指定して更新)
36
42
  * [コマンド](#コマンド)
37
43
  * [出力形式](#出力形式)
38
44
  * [課題のタイトル](#課題のタイトル)
39
45
  * [Wiki のタイトル](#wiki-のタイトル)
46
+ * [ドキュメントのタイトル](#ドキュメントのタイトル)
40
47
  * [その他の特徴](#その他の特徴)
41
48
  <!-- tocstop -->
42
49
 
@@ -47,7 +54,8 @@ backlog-exporter は、Backlog のデータをローカルにエクスポート
47
54
 
48
55
  - **課題(Issue)のエクスポート**:Backlog の課題を Markdown ファイルとして保存
49
56
  - **Wiki 記事のエクスポート**:Backlog の Wiki 記事を Markdown ファイルとして保存
50
- - **一括エクスポート**:課題と Wiki を同時に取得する機能
57
+ - **ドキュメントのエクスポート**:Backlog のドキュメントを Markdown ファイルとして保存
58
+ - **一括エクスポート**:課題・Wiki・ドキュメントを同時に取得する機能
51
59
  - **データの更新**:既存のエクスポートデータを最新の状態に更新する機能
52
60
 
53
61
  # インストール
@@ -58,7 +66,7 @@ $ npm install -g backlog-exporter
58
66
  $ backlog-exporter COMMAND
59
67
  running command...
60
68
  $ backlog-exporter (--version)
61
- backlog-exporter/0.2.3 linux-x64 node-v23.9.0
69
+ backlog-exporter/0.5.0 linux-x64 node-v24.2.0
62
70
  $ backlog-exporter --help [COMMAND]
63
71
  USAGE
64
72
  $ backlog-exporter COMMAND
@@ -85,7 +93,10 @@ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KE
85
93
  # Wikiのエクスポート
86
94
  $ backlog-exporter wiki --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./wiki
87
95
 
88
- # 課題とWikiの一括エクスポート
96
+ # ドキュメントのエクスポート
97
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./documents
98
+
99
+ # 課題・Wiki・ドキュメントの一括エクスポート
89
100
  $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./backlog-data
90
101
 
91
102
  # データの更新
@@ -130,9 +141,56 @@ $ backlog-exporter wiki --domain example.backlog.jp --projectIdOrKey PROJECT_KEY
130
141
 
131
142
  エクスポートされた Wiki は、指定したディレクトリ内に Markdown ファイルとして保存されます。Wiki の階層構造は保持され、ディレクトリ構造として再現されます。
132
143
 
133
- # 課題と Wiki の一括エクスポート
144
+ # ドキュメント のエクスポート
145
+
146
+ `document`コマンドを使用すると、Backlog のドキュメントページを Markdown ファイルとしてエクスポートできます。
147
+
148
+ ```sh
149
+ # 基本的な使用方法
150
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY
151
+
152
+ # 出力先を指定
153
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./documents
154
+
155
+ # キーワード検索
156
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --keyword 仕様書
157
+ ```
158
+
159
+ ## ドキュメントの出力方法
160
+
161
+ ドキュメントは **ツリー構造を保持** してエクスポートされます:
134
162
 
135
- `all`コマンドを使用すると、課題と Wiki を一度に取得できます。
163
+ ### ディレクトリ構造の保持
164
+ - Backlogのドキュメントツリーの階層構造がそのままローカルディレクトリ構造として再現されます
165
+ - フォルダはディレクトリとして作成され、ドキュメントはMarkdownファイルとして保存されます
166
+
167
+ ### 出力例
168
+ ```
169
+ documents/
170
+ ├── プロジェクト概要/
171
+ │ ├── 要件定義書.md
172
+ │ └── 仕様書.md
173
+ ├── 設計書/
174
+ │ ├── システム設計/
175
+ │ │ ├── アーキテクチャ設計.md
176
+ │ │ └── データベース設計.md
177
+ │ └── UI設計/
178
+ │ ├── 画面設計書.md
179
+ │ └── ワイヤーフレーム.md
180
+ └── 運用手順書.md
181
+ ```
182
+
183
+ ### 特徴
184
+ - **階層構造の完全再現**: Backlogのフォルダ階層がそのまま保持されます
185
+ - **重複処理の防止**: 同じドキュメントが複数回処理されることを防ぎます
186
+ - **ファイル名の自動サニタイズ**: 不正な文字を自動的に除去して安全なファイル名を生成します
187
+ - **メタデータの保持**: 作成者、更新者、タグ、添付ファイル情報なども含めて保存されます
188
+
189
+ エクスポートされたドキュメントは、指定したディレクトリ内にツリー構造を保持したMarkdownファイルとして保存されます。
190
+
191
+ # 課題・Wiki・ドキュメント の一括エクスポート
192
+
193
+ `all`コマンドを使用すると、課題・Wiki・ドキュメントを一度に取得できます。
136
194
 
137
195
  ```sh
138
196
  # 基本的な使用方法
@@ -142,7 +200,7 @@ $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY
142
200
  $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./backlog-data
143
201
  ```
144
202
 
145
- 一括エクスポートでは、課題は`issues`ディレクトリに、Wiki は`wiki`ディレクトリに保存されます。
203
+ 一括エクスポートでは、課題は`issues`ディレクトリに、Wiki は`wiki`ディレクトリに、ドキュメントは`documents`ディレクトリに保存されます。
146
204
 
147
205
  # データの更新
148
206
 
@@ -164,16 +222,20 @@ $ backlog-exporter update --issuesOnly
164
222
  # Wikiのみを更新
165
223
  $ backlog-exporter update --wikisOnly
166
224
 
225
+ # ドキュメントのみを更新
226
+ $ backlog-exporter update --documentsOnly
227
+
167
228
  # APIキーを指定して更新
168
229
  $ backlog-exporter update --apiKey YOUR_API_KEY
169
230
  ```
170
231
 
171
- 更新コマンドは、各ディレクトリの設定ファイルに基づいて、課題や Wiki を自動的に更新します。設定ファイルが見つかったディレクトリでは、そのディレクトリ内のファイルが直接更新されます(サブフォルダは作成されません)。
232
+ 更新コマンドは、各ディレクトリの設定ファイルに基づいて、課題・Wiki・ドキュメントを自動的に更新します。設定ファイルが見つかったディレクトリでは、そのディレクトリ内のファイルが直接更新されます(サブフォルダは作成されません)。
172
233
 
173
234
  # コマンド
174
235
 
175
236
  <!-- commands -->
176
237
  * [`backlog-exporter all`](#backlog-exporter-all)
238
+ * [`backlog-exporter document`](#backlog-exporter-document)
177
239
  * [`backlog-exporter help [COMMAND]`](#backlog-exporter-help-command)
178
240
  * [`backlog-exporter issue`](#backlog-exporter-issue)
179
241
  * [`backlog-exporter plugins`](#backlog-exporter-plugins)
@@ -191,7 +253,7 @@ $ backlog-exporter update --apiKey YOUR_API_KEY
191
253
 
192
254
  ## `backlog-exporter all`
193
255
 
194
- Backlogから課題とWikiを取得してMarkdownファイルとして保存する
256
+ Backlogから課題・Wiki・ドキュメントを取得してMarkdownファイルとして保存する
195
257
 
196
258
  ```
197
259
  USAGE
@@ -206,20 +268,52 @@ FLAGS
206
268
  --projectIdOrKey=<value> (required) Backlog project ID or key
207
269
 
208
270
  DESCRIPTION
209
- Backlogから課題とWikiを取得してMarkdownファイルとして保存する
271
+ Backlogから課題・Wiki・ドキュメントを取得してMarkdownファイルとして保存する
210
272
 
211
273
  EXAMPLES
212
274
  $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY
213
- 課題とWikiMarkdownファイルとして保存する
275
+ 課題・Wiki・ドキュメントをMarkdownファイルとして保存する
214
276
 
215
277
  $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-project
216
- 指定したディレクトリに課題とWikiを保存する
278
+ 指定したディレクトリに課題・Wiki・ドキュメントを保存する
217
279
 
218
280
  $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000
219
- 最大1000件の課題を取得する(デフォルトは100件)
281
+ 最大1000件の課題を取得する(デフォルトは5000件)
282
+ ```
283
+
284
+ _See code: [src/commands/all/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.5.0/src/commands/all/index.ts)_
285
+
286
+ ## `backlog-exporter document`
287
+
288
+ Backlogからドキュメントを取得してMarkdownファイルとして保存する
289
+
290
+ ```
291
+ USAGE
292
+ $ backlog-exporter document --domain <value> --projectIdOrKey <value> [--apiKey <value>] [--keyword <value>]
293
+ [-o <value>]
294
+
295
+ FLAGS
296
+ -o, --output=<value> 出力ディレクトリパス
297
+ --apiKey=<value> Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)
298
+ --domain=<value> (required) Backlog domain (e.g. example.backlog.jp)
299
+ --keyword=<value> 検索キーワード
300
+ --projectIdOrKey=<value> (required) Backlog project ID or key
301
+
302
+ DESCRIPTION
303
+ Backlogからドキュメントを取得してMarkdownファイルとして保存する
304
+
305
+ EXAMPLES
306
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY
307
+ ドキュメントをMarkdownファイルとして保存する
308
+
309
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-documents
310
+ 指定したディレクトリにドキュメントを保存する
311
+
312
+ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --keyword 仕様書
313
+ キーワード「仕様書」を含むドキュメントのみを取得する
220
314
  ```
221
315
 
222
- _See code: [src/commands/all/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.2.3/src/commands/all/index.ts)_
316
+ _See code: [src/commands/document/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.5.0/src/commands/document/index.ts)_
223
317
 
224
318
  ## `backlog-exporter help [COMMAND]`
225
319
 
@@ -275,7 +369,7 @@ EXAMPLES
275
369
  最大10000件の課題を取得する(デフォルトは5000件)
276
370
  ```
277
371
 
278
- _See code: [src/commands/issue/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.2.3/src/commands/issue/index.ts)_
372
+ _See code: [src/commands/issue/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.5.0/src/commands/issue/index.ts)_
279
373
 
280
374
  ## `backlog-exporter plugins`
281
375
 
@@ -573,8 +667,8 @@ Backlogから最新データを取得して更新する
573
667
 
574
668
  ```
575
669
  USAGE
576
- $ backlog-exporter update [DIRECTORY] [--apiKey <value>] [--domain <value>] [-f] [--issuesOnly]
577
- [--projectIdOrKey <value>] [--wikisOnly]
670
+ $ backlog-exporter update [DIRECTORY] [--apiKey <value>] [--documentsOnly] [--domain <value>] [-f]
671
+ [--issuesOnly] [--projectIdOrKey <value>] [--wikisOnly]
578
672
 
579
673
  ARGUMENTS
580
674
  DIRECTORY 更新対象のディレクトリ(設定ファイルが保存されている場所)
@@ -582,6 +676,7 @@ ARGUMENTS
582
676
  FLAGS
583
677
  -f, --force 確認プロンプトをスキップする
584
678
  --apiKey=<value> Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)
679
+ --documentsOnly ドキュメントのみを更新する
585
680
  --domain=<value> Backlog domain (e.g. example.backlog.jp)
586
681
  --issuesOnly 課題のみを更新する
587
682
  --projectIdOrKey=<value> Backlog project ID or key
@@ -604,7 +699,7 @@ EXAMPLES
604
699
  指定したディレクトリの設定を使用して更新する
605
700
  ```
606
701
 
607
- _See code: [src/commands/update/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.2.3/src/commands/update/index.ts)_
702
+ _See code: [src/commands/update/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.5.0/src/commands/update/index.ts)_
608
703
 
609
704
  ## `backlog-exporter wiki`
610
705
 
@@ -631,7 +726,7 @@ EXAMPLES
631
726
  指定したディレクトリにWikiを保存する
632
727
  ```
633
728
 
634
- _See code: [src/commands/wiki/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.2.3/src/commands/wiki/index.ts)_
729
+ _See code: [src/commands/wiki/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.5.0/src/commands/wiki/index.ts)_
635
730
  <!-- commandsstop -->
636
731
 
637
732
  # 出力形式
@@ -689,6 +784,35 @@ Wiki は以下の形式で Markdown ファイルとして保存されます:
689
784
  Backlog の書式がそのまま保持されます。
690
785
  ```
691
786
 
787
+ ## ドキュメント の出力形式
788
+
789
+ ドキュメントは以下の形式で Markdown ファイルとして保存されます:
790
+
791
+ ```markdown
792
+ # ドキュメントのタイトル
793
+
794
+ [Backlog Document Link](https://example.backlog.jp/document/DOC-ID)
795
+
796
+ **ステータス**: 1 🎉
797
+ **作成者**: 山田太郎
798
+ **作成日時**: 2023/01/01 10:00:00
799
+ **更新者**: 佐藤次郎
800
+ **更新日時**: 2023/01/02 15:30:45
801
+
802
+ ## 内容
803
+
804
+ ここにドキュメントの本文内容が入ります。
805
+ Backlog の書式がそのまま保持されます。
806
+
807
+ ## 添付ファイル
808
+ - **資料.pdf** (1024.5 KB) - 作成者: 山田太郎, 作成日時: 2023/01/01 10:00:00
809
+ - **画像.png** (256.3 KB) - 作成者: 佐藤次郎, 作成日時: 2023/01/01 10:30:00
810
+
811
+ ## タグ
812
+ - 仕様書
813
+ - 設計書
814
+ ```
815
+
692
816
  # その他の特徴
693
817
 
694
818
  - **環境変数サポート**: 環境変数 `BACKLOG_API_KEY` を使用して API キーを設定可能
@@ -696,3 +820,5 @@ Backlog の書式がそのまま保持されます。
696
820
  - **並列処理**: 並列処理による高速なダウンロード
697
821
  - **ファイル名サニタイズ**: ファイル名の自動サニタイズ(不正な文字の除去)
698
822
  - **階層構造の保持**: Wiki の階層構造を保持したエクスポート
823
+ - **キーワード検索**: ドキュメントの検索キーワード対応
824
+ - **差分更新**: 前回の更新以降に変更されたデータのみを更新
@@ -1,23 +1,23 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
2
  import * as dotenv from 'dotenv';
3
3
  import path from 'node:path';
4
- import { downloadIssues, downloadWikis } from '../../utils/backlog-api.js';
4
+ import { downloadDocuments, downloadIssues, downloadWikis } from '../../utils/backlog-api.js';
5
5
  import { validateAndGetProjectId } from '../../utils/backlog.js';
6
6
  import { createOutputDirectory, getApiKey } from '../../utils/common.js';
7
7
  import { FolderType, updateSettings } from '../../utils/settings.js';
8
8
  // .envファイルを読み込む
9
9
  dotenv.config();
10
10
  export default class All extends Command {
11
- static description = 'Backlogから課題とWikiを取得してMarkdownファイルとして保存する';
11
+ static description = 'Backlogから課題・Wiki・ドキュメントを取得してMarkdownファイルとして保存する';
12
12
  static examples = [
13
13
  `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY
14
- 課題とWikiMarkdownファイルとして保存する
14
+ 課題・Wiki・ドキュメントをMarkdownファイルとして保存する
15
15
  `,
16
16
  `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-project
17
- 指定したディレクトリに課題とWikiを保存する
17
+ 指定したディレクトリに課題・Wiki・ドキュメントを保存する
18
18
  `,
19
19
  `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000
20
- 最大1000件の課題を取得する(デフォルトは100件)
20
+ 最大1000件の課題を取得する(デフォルトは5000件)
21
21
  `,
22
22
  ];
23
23
  static flags = {
@@ -62,6 +62,9 @@ export default class All extends Command {
62
62
  // Wikiの出力ディレクトリ
63
63
  const wikiOutput = path.join(outputRoot, 'wiki');
64
64
  await createOutputDirectory(wikiOutput);
65
+ // ドキュメントの出力ディレクトリ
66
+ const documentOutput = path.join(outputRoot, 'documents');
67
+ await createOutputDirectory(documentOutput);
65
68
  // 課題フォルダに設定ファイルを保存
66
69
  await updateSettings(issueOutput, {
67
70
  apiKey,
@@ -78,6 +81,14 @@ export default class All extends Command {
78
81
  outputDir: wikiOutput,
79
82
  projectIdOrKey,
80
83
  });
84
+ // ドキュメントフォルダに設定ファイルを保存
85
+ await updateSettings(documentOutput, {
86
+ apiKey,
87
+ domain,
88
+ folderType: FolderType.DOCUMENT,
89
+ outputDir: documentOutput,
90
+ projectIdOrKey,
91
+ });
81
92
  // 課題の取得と保存
82
93
  this.log('課題の取得を開始します...');
83
94
  await downloadIssues(this, {
@@ -105,6 +116,19 @@ export default class All extends Command {
105
116
  lastUpdated: new Date().toISOString(),
106
117
  });
107
118
  this.log('Wikiの取得が完了しました');
119
+ // ドキュメントの取得と保存
120
+ this.log('ドキュメントの取得を開始します...');
121
+ await downloadDocuments(this, {
122
+ apiKey,
123
+ domain,
124
+ outputDir: documentOutput,
125
+ projectId,
126
+ });
127
+ // ドキュメントフォルダの最終更新日時を更新
128
+ await updateSettings(documentOutput, {
129
+ lastUpdated: new Date().toISOString(),
130
+ });
131
+ this.log('ドキュメントの取得が完了しました');
108
132
  this.log('すべてのデータの取得が完了しました!');
109
133
  }
110
134
  catch (error) {
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Document extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ apiKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ domain: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ keyword: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ projectIdOrKey: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,83 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import * as dotenv from 'dotenv';
3
+ import { downloadDocuments } from '../../utils/backlog-api.js';
4
+ import { validateAndGetProjectId } from '../../utils/backlog.js';
5
+ import { createOutputDirectory, getApiKey } from '../../utils/common.js';
6
+ import { FolderType, updateSettings } from '../../utils/settings.js';
7
+ // .envファイルを読み込む
8
+ dotenv.config();
9
+ export default class Document extends Command {
10
+ static description = 'Backlogからドキュメントを取得してMarkdownファイルとして保存する';
11
+ static examples = [
12
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY
13
+ ドキュメントをMarkdownファイルとして保存する
14
+ `,
15
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-documents
16
+ 指定したディレクトリにドキュメントを保存する
17
+ `,
18
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --keyword 仕様書
19
+ キーワード「仕様書」を含むドキュメントのみを取得する
20
+ `,
21
+ ];
22
+ static flags = {
23
+ apiKey: Flags.string({
24
+ description: 'Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)',
25
+ required: false,
26
+ }),
27
+ domain: Flags.string({
28
+ description: 'Backlog domain (e.g. example.backlog.jp)',
29
+ required: true,
30
+ }),
31
+ keyword: Flags.string({
32
+ description: '検索キーワード',
33
+ required: false,
34
+ }),
35
+ output: Flags.string({
36
+ char: 'o',
37
+ description: '出力ディレクトリパス',
38
+ required: false,
39
+ }),
40
+ projectIdOrKey: Flags.string({
41
+ description: 'Backlog project ID or key',
42
+ required: true,
43
+ }),
44
+ };
45
+ async run() {
46
+ const { flags } = await this.parse(Document);
47
+ try {
48
+ const { domain, keyword, projectIdOrKey } = flags;
49
+ const apiKey = flags.apiKey || getApiKey(this);
50
+ const outputDir = flags.output || './backlog-documents';
51
+ // 出力ディレクトリの作成
52
+ await createOutputDirectory(outputDir);
53
+ // プロジェクトキーからプロジェクトIDを取得
54
+ const projectId = await validateAndGetProjectId(domain, projectIdOrKey, apiKey);
55
+ this.log(`プロジェクトID: ${projectId} を使用します`);
56
+ // 設定ファイルを保存
57
+ await updateSettings(outputDir, {
58
+ apiKey,
59
+ domain,
60
+ folderType: FolderType.DOCUMENT,
61
+ outputDir,
62
+ projectIdOrKey,
63
+ });
64
+ // ドキュメントの取得と保存
65
+ await downloadDocuments(this, {
66
+ apiKey,
67
+ domain,
68
+ keyword,
69
+ outputDir,
70
+ projectId,
71
+ });
72
+ // 最終更新日時を更新
73
+ await updateSettings(outputDir, {
74
+ lastUpdated: new Date().toISOString(),
75
+ });
76
+ this.log('ドキュメントの取得が完了しました!');
77
+ }
78
+ catch (error) {
79
+ const errorMessage = error instanceof Error ? error.message : String(error);
80
+ this.error(`ドキュメントの取得に失敗しました: ${errorMessage}`);
81
+ }
82
+ }
83
+ }
@@ -7,6 +7,7 @@ export default class Update extends Command {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  apiKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ documentsOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  domain: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
12
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
13
  issuesOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -18,6 +19,7 @@ export default class Update extends Command {
18
19
  private determineUpdateTargets;
19
20
  private findAndUpdateSettings;
20
21
  private updateDirectory;
22
+ private updateDocuments;
21
23
  private updateIssues;
22
24
  private updateWikis;
23
25
  }
@@ -2,7 +2,7 @@ import { Args, Command, Flags } from '@oclif/core';
2
2
  import * as dotenv from 'dotenv';
3
3
  import { access, readdir } from 'node:fs/promises';
4
4
  import { join } from 'node:path';
5
- import { downloadIssues, downloadWikis } from '../../utils/backlog-api.js';
5
+ import { downloadDocuments, downloadIssues, downloadWikis } from '../../utils/backlog-api.js';
6
6
  import { validateAndGetProjectId } from '../../utils/backlog.js';
7
7
  import { createOutputDirectory, getApiKey } from '../../utils/common.js';
8
8
  import { FolderType, getSettingsFilePath, loadSettings, updateSettings } from '../../utils/settings.js';
@@ -35,6 +35,10 @@ export default class Update extends Command {
35
35
  description: 'Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)',
36
36
  required: false,
37
37
  }),
38
+ documentsOnly: Flags.boolean({
39
+ description: 'ドキュメントのみを更新する',
40
+ required: false,
41
+ }),
38
42
  domain: Flags.string({
39
43
  description: 'Backlog domain (e.g. example.backlog.jp)',
40
44
  required: false,
@@ -81,7 +85,14 @@ export default class Update extends Command {
81
85
  if (options.folderType) {
82
86
  this.log(`- フォルダタイプ: ${options.folderType}`);
83
87
  }
84
- this.log(`- 更新対象: ${options.updateIssues ? '課題' : ''}${options.updateIssues && options.updateWikis ? 'と' : ''}${options.updateWikis ? 'Wiki' : ''}`);
88
+ const updateTargets = [];
89
+ if (options.updateIssues)
90
+ updateTargets.push('課題');
91
+ if (options.updateWikis)
92
+ updateTargets.push('Wiki');
93
+ if (options.updateDocuments)
94
+ updateTargets.push('ドキュメント');
95
+ this.log(`- 更新対象: ${updateTargets.join('・')}`);
85
96
  // 確認プロンプトを表示
86
97
  this.log('更新を実行しますか? (y/n)');
87
98
  process.stdin.resume();
@@ -99,20 +110,32 @@ export default class Update extends Command {
99
110
  return response;
100
111
  }
101
112
  // 更新対象の決定
102
- determineUpdateTargets(folderType, issuesOnly, wikisOnly) {
103
- let updateIssues = !wikisOnly;
104
- let updateWikis = !issuesOnly;
105
- // フォルダタイプがISSUEの場合は課題のみ更新
106
- if (folderType === FolderType.ISSUE) {
107
- updateIssues = true;
108
- updateWikis = false;
109
- }
110
- // フォルダタイプがWIKIの場合はWikiのみ更新
111
- else if (folderType === FolderType.WIKI) {
112
- updateIssues = false;
113
- updateWikis = true;
114
- }
115
- return { updateIssues, updateWikis };
113
+ determineUpdateTargets(folderType, documentsOnly, issuesOnly, wikisOnly) {
114
+ let updateIssues = !wikisOnly && !documentsOnly;
115
+ let updateWikis = !issuesOnly && !documentsOnly;
116
+ let updateDocuments = !issuesOnly && !wikisOnly;
117
+ // フォルダタイプに応じて更新対象を決定
118
+ switch (folderType) {
119
+ case FolderType.DOCUMENT: {
120
+ updateIssues = false;
121
+ updateWikis = false;
122
+ updateDocuments = true;
123
+ break;
124
+ }
125
+ case FolderType.ISSUE: {
126
+ updateIssues = true;
127
+ updateWikis = false;
128
+ updateDocuments = false;
129
+ break;
130
+ }
131
+ case FolderType.WIKI: {
132
+ updateIssues = false;
133
+ updateWikis = true;
134
+ updateDocuments = false;
135
+ break;
136
+ }
137
+ }
138
+ return { updateDocuments, updateIssues, updateWikis };
116
139
  }
117
140
  // 設定ファイルを探索して更新を実行
118
141
  async findAndUpdateSettings(targetDir, flags) {
@@ -150,11 +173,10 @@ export default class Update extends Command {
150
173
  // 設定ファイルを読み込む
151
174
  const settings = await loadSettings(targetDir);
152
175
  // コマンドライン引数と設定ファイルを組み合わせて使用する値を決定
153
- const apiKey = flags.apiKey || settings.apiKey || getApiKey(this);
154
176
  const domain = flags.domain || settings.domain;
155
177
  const projectIdOrKey = flags.projectIdOrKey || settings.projectIdOrKey;
156
178
  const { folderType } = settings;
157
- const { force, issuesOnly, wikisOnly } = flags;
179
+ const { documentsOnly, force, issuesOnly, wikisOnly } = flags;
158
180
  // 必須パラメータの検証
159
181
  if (!domain) {
160
182
  this.warn(`${targetDir}: ドメインが指定されていません。スキップします。`);
@@ -164,8 +186,17 @@ export default class Update extends Command {
164
186
  this.warn(`${targetDir}: プロジェクトIDまたはキーが指定されていません。スキップします。`);
165
187
  return;
166
188
  }
189
+ // APIキーの検証
190
+ let apiKey;
191
+ try {
192
+ apiKey = flags.apiKey || settings.apiKey || getApiKey(this);
193
+ }
194
+ catch {
195
+ this.warn(`${targetDir}: APIキーが指定されていません。--apiKey フラグまたは BACKLOG_API_KEY 環境変数で設定してください。`);
196
+ return;
197
+ }
167
198
  // 更新対象の決定
168
- const { updateIssues, updateWikis } = this.determineUpdateTargets(folderType, issuesOnly, wikisOnly);
199
+ const { updateDocuments, updateIssues, updateWikis } = this.determineUpdateTargets(folderType, documentsOnly, issuesOnly, wikisOnly);
169
200
  // 更新前の確認
170
201
  const confirmed = await this.confirmUpdate({
171
202
  domain,
@@ -173,6 +204,7 @@ export default class Update extends Command {
173
204
  force: force || false,
174
205
  projectIdOrKey,
175
206
  targetDir,
207
+ updateDocuments,
176
208
  updateIssues,
177
209
  updateWikis,
178
210
  });
@@ -202,8 +234,41 @@ export default class Update extends Command {
202
234
  targetDir,
203
235
  });
204
236
  }
237
+ // ドキュメントの更新
238
+ if (updateDocuments) {
239
+ await this.updateDocuments({
240
+ apiKey,
241
+ domain,
242
+ projectId,
243
+ projectIdOrKey,
244
+ targetDir,
245
+ });
246
+ }
205
247
  this.log(`${targetDir} の更新が完了しました!`);
206
248
  }
249
+ // ドキュメントの更新
250
+ async updateDocuments(options) {
251
+ this.log('ドキュメントの更新を開始します...');
252
+ // 設定ファイルから前回の更新日時を取得
253
+ const { lastUpdated } = await loadSettings(options.targetDir);
254
+ await downloadDocuments(this, {
255
+ apiKey: options.apiKey,
256
+ domain: options.domain,
257
+ lastUpdated,
258
+ outputDir: options.targetDir,
259
+ projectId: options.projectId,
260
+ });
261
+ // 設定ファイルを更新
262
+ await updateSettings(options.targetDir, {
263
+ apiKey: options.apiKey,
264
+ domain: options.domain,
265
+ folderType: FolderType.DOCUMENT,
266
+ lastUpdated: new Date().toISOString(),
267
+ outputDir: options.targetDir,
268
+ projectIdOrKey: options.projectIdOrKey,
269
+ });
270
+ this.log('ドキュメントの更新が完了しました');
271
+ }
207
272
  // 課題の更新
208
273
  async updateIssues(options) {
209
274
  this.log('課題の更新を開始します...');
@@ -25,3 +25,16 @@ export declare function downloadWikis(command: Command, options: {
25
25
  outputDir: string;
26
26
  projectIdOrKey: string;
27
27
  }): Promise<void>;
28
+ /**
29
+ * Backlogからドキュメントをダウンロードする
30
+ * @param command コマンドインスタンス
31
+ * @param options ドキュメントダウンロードのオプション
32
+ */
33
+ export declare function downloadDocuments(command: Command, options: {
34
+ apiKey: string;
35
+ domain: string;
36
+ keyword?: string;
37
+ lastUpdated?: string;
38
+ outputDir: string;
39
+ projectId: number;
40
+ }): Promise<void>;
@@ -3,6 +3,7 @@ import * as fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import process from 'node:process';
5
5
  import { sanitizeFileName, sanitizeWikiFileName } from './common.js';
6
+ import { appendLog } from './log.js';
6
7
  import { RateLimiter } from './sleep.js';
7
8
  /**
8
9
  * Backlogから課題をダウンロードする
@@ -130,6 +131,9 @@ export async function downloadIssues(command, options) {
130
131
  ${issue.description || '詳細情報なし'}${commentsSection}`;
131
132
  // eslint-disable-next-line no-await-in-loop
132
133
  await fs.writeFile(issueFilePath, markdownContent);
134
+ // ログに記録
135
+ // eslint-disable-next-line no-await-in-loop
136
+ await appendLog(options.outputDir, `課題「${issue.summary}」を更新しました: ${backlogIssueUrl}`);
133
137
  }
134
138
  catch (error) {
135
139
  command.warn(`課題 ${issue.issueKey} の保存に失敗しました: ${error instanceof Error ? error.message : String(error)}`);
@@ -238,6 +242,9 @@ export async function downloadWikis(command, options) {
238
242
  const markdownContent = `# ${wiki.name}\n\n[Backlog Wiki Link](${backlogWikiUrl})\n\n${content}`;
239
243
  // eslint-disable-next-line no-await-in-loop
240
244
  await fs.writeFile(wikiFilePath, markdownContent);
245
+ // ログに記録
246
+ // eslint-disable-next-line no-await-in-loop
247
+ await appendLog(options.outputDir, `Wiki「${wiki.name}」を更新しました: ${backlogWikiUrl}`);
241
248
  // 進捗状況を一行で更新
242
249
  const wikiIndex = filteredWikis.indexOf(wiki) + 1;
243
250
  process.stdout.write(`\rWikiを保存中... (${wikiIndex}/${filteredWikis.length}件)`);
@@ -248,3 +255,123 @@ export async function downloadWikis(command, options) {
248
255
  }
249
256
  command.log('\nWikiのダウンロードが完了しました!');
250
257
  }
258
+ /**
259
+ * Backlogからドキュメントをダウンロードする
260
+ * @param command コマンドインスタンス
261
+ * @param options ドキュメントダウンロードのオプション
262
+ */
263
+ export async function downloadDocuments(command, options) {
264
+ const baseUrl = `https://${options.domain}/api/v2`;
265
+ command.log('ドキュメントの取得を開始します...');
266
+ // APIリクエスト数をカウントするためのRateLimiterを作成
267
+ const rateLimiter = new RateLimiter(command);
268
+ // ドキュメントツリーの取得
269
+ command.log('ドキュメントツリーを取得しています...');
270
+ // APIリクエスト数をインクリメント
271
+ await rateLimiter.increment();
272
+ const documentTree = await ky
273
+ .get(`${baseUrl}/documents/tree?projectIdOrKey=${options.projectId}&apiKey=${options.apiKey}`)
274
+ .json();
275
+ command.log('アクティブなドキュメントツリーを処理します...');
276
+ // ツリー構造をトラバースして、各ドキュメントの詳細を取得・保存
277
+ const processedDocuments = [];
278
+ /**
279
+ * ドキュメントノードを再帰的に処理する
280
+ */
281
+ const processDocumentNode = async (node, currentPath) => {
282
+ // フォルダの場合
283
+ if (node.children && node.children.length > 0) {
284
+ // フォルダを作成
285
+ const folderPath = path.join(options.outputDir, currentPath, sanitizeFileName(node.name));
286
+ await fs.mkdir(folderPath, { recursive: true });
287
+ // 子ノードを処理
288
+ for (const child of node.children) {
289
+ // eslint-disable-next-line no-await-in-loop
290
+ await processDocumentNode(child, path.join(currentPath, sanitizeFileName(node.name)));
291
+ }
292
+ }
293
+ else {
294
+ // ドキュメントファイルの場合
295
+ try {
296
+ // 既に処理済みのドキュメントはスキップ
297
+ if (processedDocuments.includes(node.id)) {
298
+ return;
299
+ }
300
+ processedDocuments.push(node.id);
301
+ // APIリクエスト数をインクリメント
302
+ await rateLimiter.increment();
303
+ // 進捗状況を表示
304
+ process.stdout.write(`\rドキュメント「${node.name}」を処理中...`);
305
+ // ドキュメント詳細を取得
306
+ const documentDetail = await ky.get(`${baseUrl}/documents/${node.id}?apiKey=${options.apiKey}`).json();
307
+ // 前回の更新日時チェック
308
+ if (options.lastUpdated) {
309
+ const lastUpdatedDate = new Date(options.lastUpdated);
310
+ const documentUpdatedDate = new Date(documentDetail.updated);
311
+ if (documentUpdatedDate <= lastUpdatedDate) {
312
+ return; // 更新が必要ない場合はスキップ
313
+ }
314
+ }
315
+ // ファイルパスを構築
316
+ const sanitizedTitle = sanitizeFileName(documentDetail.title);
317
+ const documentFileName = `${sanitizedTitle}.md`;
318
+ const documentFilePath = path.join(options.outputDir, currentPath, documentFileName);
319
+ // ディレクトリを作成(必要に応じて)
320
+ const dirPath = path.dirname(documentFilePath);
321
+ await fs.mkdir(dirPath, { recursive: true });
322
+ // Backlogのドキュメントへのリンクを作成
323
+ const backlogDocumentUrl = `https://${options.domain}/document/${node.id}`;
324
+ // 添付ファイルリストの作成
325
+ let attachmentsSection = '';
326
+ if (documentDetail.attachments && documentDetail.attachments.length > 0) {
327
+ attachmentsSection = '\n\n## 添付ファイル\n';
328
+ for (const attachment of documentDetail.attachments) {
329
+ const attachmentDate = new Date(attachment.created).toLocaleString('ja-JP');
330
+ const fileSize = (attachment.size / 1024).toFixed(1);
331
+ attachmentsSection += `- **${attachment.name}** (${fileSize} KB) - 作成者: ${attachment.createdUser.name}, 作成日時: ${attachmentDate}\n`;
332
+ }
333
+ }
334
+ // タグリストの作成
335
+ let tagsSection = '';
336
+ if (documentDetail.tags && documentDetail.tags.length > 0) {
337
+ tagsSection = '\n\n## タグ\n';
338
+ for (const tag of documentDetail.tags) {
339
+ tagsSection += `- ${tag.name}\n`;
340
+ }
341
+ }
342
+ // 作成者・更新者情報
343
+ const createdDate = new Date(documentDetail.created).toLocaleString('ja-JP');
344
+ const updatedDate = new Date(documentDetail.updated).toLocaleString('ja-JP');
345
+ // Markdownファイルに書き込む
346
+ const markdownContent = `# ${documentDetail.title}
347
+
348
+ [Backlog Document Link](${backlogDocumentUrl})
349
+
350
+ **ステータス**: ${documentDetail.statusId}${documentDetail.emoji ? ` ${documentDetail.emoji}` : ''}
351
+ **作成者**: ${documentDetail.createdUser.name}
352
+ **作成日時**: ${createdDate}
353
+ **更新者**: ${documentDetail.updatedUser.name}
354
+ **更新日時**: ${updatedDate}
355
+
356
+ ## 内容
357
+
358
+ ${documentDetail.plain || '(内容なし)'}${attachmentsSection}${tagsSection}`;
359
+ await fs.writeFile(documentFilePath, markdownContent);
360
+ // ログに記録
361
+ await appendLog(options.outputDir, `ドキュメント「${documentDetail.title}」を更新しました: ${backlogDocumentUrl}`);
362
+ }
363
+ catch (error) {
364
+ command.warn(`ドキュメント ${node.name} の取得に失敗しました: ${error instanceof Error ? error.message : String(error)}`);
365
+ }
366
+ }
367
+ };
368
+ // アクティブツリーのルートから処理開始
369
+ if (documentTree.activeTree.children && documentTree.activeTree.children.length > 0) {
370
+ for (const rootNode of documentTree.activeTree.children) {
371
+ // eslint-disable-next-line no-await-in-loop
372
+ await processDocumentNode(rootNode, '');
373
+ }
374
+ }
375
+ command.log(`\n合計 ${processedDocuments.length}件のドキュメントが処理されました。`);
376
+ command.log('ドキュメントのダウンロードが完了しました!');
377
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 更新ログを記録する
3
+ * @param outputDir 出力ディレクトリ
4
+ * @param message ログメッセージ
5
+ */
6
+ export declare function appendLog(outputDir: string, message: string): Promise<void>;
@@ -0,0 +1,18 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ /**
4
+ * 更新ログを記録する
5
+ * @param outputDir 出力ディレクトリ
6
+ * @param message ログメッセージ
7
+ */
8
+ export async function appendLog(outputDir, message) {
9
+ const logPath = path.join(outputDir, 'backlog-update.log');
10
+ const timestamp = new Date().toLocaleString('ja-JP');
11
+ const logMessage = `[${timestamp}] ${message}\n`;
12
+ try {
13
+ await fs.appendFile(logPath, logMessage, 'utf8');
14
+ }
15
+ catch (error) {
16
+ console.error(`ログの記録に失敗しました: ${error instanceof Error ? error.message : String(error)}`);
17
+ }
18
+ }
@@ -2,6 +2,7 @@
2
2
  * フォルダタイプの定義
3
3
  */
4
4
  export declare enum FolderType {
5
+ DOCUMENT = "document",
5
6
  ISSUE = "issue",
6
7
  WIKI = "wiki"
7
8
  }
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  */
6
6
  export var FolderType;
7
7
  (function (FolderType) {
8
+ FolderType["DOCUMENT"] = "document";
8
9
  FolderType["ISSUE"] = "issue";
9
10
  FolderType["WIKI"] = "wiki";
10
11
  })(FolderType || (FolderType = {}));
@@ -3,11 +3,11 @@
3
3
  "all": {
4
4
  "aliases": [],
5
5
  "args": {},
6
- "description": "Backlogから課題とWikiを取得してMarkdownファイルとして保存する",
6
+ "description": "Backlogから課題・Wiki・ドキュメントを取得してMarkdownファイルとして保存する",
7
7
  "examples": [
8
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\n課題とWikiMarkdownファイルとして保存する\n",
9
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-project\n指定したディレクトリに課題とWikiを保存する\n",
10
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000\n最大1000件の課題を取得する(デフォルトは100件)\n"
8
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\n課題・Wiki・ドキュメントをMarkdownファイルとして保存する\n",
9
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-project\n指定したディレクトリに課題・Wiki・ドキュメントを保存する\n",
10
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000\n最大1000件の課題を取得する(デフォルトは5000件)\n"
11
11
  ],
12
12
  "flags": {
13
13
  "apiKey": {
@@ -70,6 +70,74 @@
70
70
  "index.js"
71
71
  ]
72
72
  },
73
+ "document": {
74
+ "aliases": [],
75
+ "args": {},
76
+ "description": "Backlogからドキュメントを取得してMarkdownファイルとして保存する",
77
+ "examples": [
78
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\nドキュメントをMarkdownファイルとして保存する\n",
79
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-documents\n指定したディレクトリにドキュメントを保存する\n",
80
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --keyword 仕様書\nキーワード「仕様書」を含むドキュメントのみを取得する\n"
81
+ ],
82
+ "flags": {
83
+ "apiKey": {
84
+ "description": "Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)",
85
+ "name": "apiKey",
86
+ "required": false,
87
+ "hasDynamicHelp": false,
88
+ "multiple": false,
89
+ "type": "option"
90
+ },
91
+ "domain": {
92
+ "description": "Backlog domain (e.g. example.backlog.jp)",
93
+ "name": "domain",
94
+ "required": true,
95
+ "hasDynamicHelp": false,
96
+ "multiple": false,
97
+ "type": "option"
98
+ },
99
+ "keyword": {
100
+ "description": "検索キーワード",
101
+ "name": "keyword",
102
+ "required": false,
103
+ "hasDynamicHelp": false,
104
+ "multiple": false,
105
+ "type": "option"
106
+ },
107
+ "output": {
108
+ "char": "o",
109
+ "description": "出力ディレクトリパス",
110
+ "name": "output",
111
+ "required": false,
112
+ "hasDynamicHelp": false,
113
+ "multiple": false,
114
+ "type": "option"
115
+ },
116
+ "projectIdOrKey": {
117
+ "description": "Backlog project ID or key",
118
+ "name": "projectIdOrKey",
119
+ "required": true,
120
+ "hasDynamicHelp": false,
121
+ "multiple": false,
122
+ "type": "option"
123
+ }
124
+ },
125
+ "hasDynamicHelp": false,
126
+ "hiddenAliases": [],
127
+ "id": "document",
128
+ "pluginAlias": "backlog-exporter",
129
+ "pluginName": "backlog-exporter",
130
+ "pluginType": "core",
131
+ "strict": true,
132
+ "enableJsonFlag": false,
133
+ "isESM": true,
134
+ "relativePath": [
135
+ "dist",
136
+ "commands",
137
+ "document",
138
+ "index.js"
139
+ ]
140
+ },
73
141
  "issue": {
74
142
  "aliases": [],
75
143
  "args": {},
@@ -174,6 +242,13 @@
174
242
  "multiple": false,
175
243
  "type": "option"
176
244
  },
245
+ "documentsOnly": {
246
+ "description": "ドキュメントのみを更新する",
247
+ "name": "documentsOnly",
248
+ "required": false,
249
+ "allowNo": false,
250
+ "type": "boolean"
251
+ },
177
252
  "domain": {
178
253
  "description": "Backlog domain (e.g. example.backlog.jp)",
179
254
  "name": "domain",
@@ -289,5 +364,5 @@
289
364
  ]
290
365
  }
291
366
  },
292
- "version": "0.2.3"
367
+ "version": "0.5.0"
293
368
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "backlog-exporter",
3
3
  "description": "A new CLI generated with oclif",
4
- "version": "0.2.3",
4
+ "version": "0.5.0",
5
5
  "author": "ShuntaToda",
6
6
  "bin": {
7
7
  "backlog-exporter": "bin/run.js"
@@ -76,4 +76,4 @@
76
76
  "version": "oclif readme && git add README.md"
77
77
  },
78
78
  "types": "dist/index.d.ts"
79
- }
79
+ }