backlog-exporter 0.6.1 → 0.7.1

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
@@ -23,6 +23,9 @@ Backlog のデータをエクスポートするためのコマンドラインツ
23
23
  * [課題のエクスポート](#課題のエクスポート)
24
24
  * [基本的な使用方法](#基本的な使用方法)
25
25
  * [出力先を指定](#出力先を指定)
26
+ * [Markdownファイル名を課題キーにする](#markdownファイル名を課題キーにする)
27
+ * [課題キーでフォルダを作成する](#課題キーでフォルダを作成する)
28
+ * [課題キーでフォルダを作成し、Markdownファイル名も課題キーにする](#課題キーでフォルダを作成しmarkdownファイル名も課題キーにする)
26
29
  * [Wiki のエクスポート](#wiki-のエクスポート)
27
30
  * [基本的な使用方法](#基本的な使用方法)
28
31
  * [出力先を指定](#出力先を指定)
@@ -74,7 +77,7 @@ $ npm install -g backlog-exporter
74
77
  $ backlog-exporter COMMAND
75
78
  running command...
76
79
  $ backlog-exporter (--version)
77
- backlog-exporter/0.6.1 linux-x64 node-v24.3.0
80
+ backlog-exporter/0.7.1 linux-x64 node-v24.4.1
78
81
  $ backlog-exporter --help [COMMAND]
79
82
  USAGE
80
83
  $ backlog-exporter COMMAND
@@ -137,6 +140,15 @@ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KE
137
140
 
138
141
  # 出力先を指定
139
142
  $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./issues
143
+
144
+ # Markdownファイル名を課題キーにする
145
+ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName
146
+
147
+ # 課題キーでフォルダを作成する
148
+ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder
149
+
150
+ # 課題キーでフォルダを作成し、Markdownファイル名も課題キーにする
151
+ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder
140
152
  ```
141
153
 
142
154
  エクスポートされた課題は、指定したディレクトリ内に Markdown ファイルとして保存されます。ファイル名は課題のキーに基づいて自動的に生成されます。
@@ -146,21 +158,23 @@ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KE
146
158
  課題のエクスポートでは、Backlogのカスタム属性も含めて出力されます:
147
159
 
148
160
  ### 対応している値の型
161
+
149
162
  - **プリミティブ値**: 文字列、数値などの単純な値
150
163
  - **配列値**: 複数選択のカスタム属性(カンマ区切りで表示)
151
164
  - **オブジェクト値**: 単一選択のカスタム属性(name または value プロパティを使用)
152
165
 
153
166
  ### 表示形式
167
+
154
168
  カスタム属性はMarkdownテーブル形式で表示され、改行やパイプ文字も適切に処理されます:
155
169
 
156
170
  ```markdown
157
171
  ## カスタム属性
158
172
 
159
- | 属性名 | 値 |
160
- |--------|----|
161
- | 工数(エンジニア) | 3 |
162
- | 担当チーム | フロントエンド, バックエンド |
163
- | 詳細 | 実装内容<br>- 機能A<br>- 機能B |
173
+ | 属性名 | 値 |
174
+ | ------------------ | ------------------------------ |
175
+ | 工数(エンジニア) | 3 |
176
+ | 担当チーム | フロントエンド, バックエンド |
177
+ | 詳細 | 実装内容<br>- 機能A<br>- 機能B |
164
178
  ```
165
179
 
166
180
  # Wiki のエクスポート
@@ -197,10 +211,12 @@ $ backlog-exporter document --domain example.backlog.jp --projectIdOrKey PROJECT
197
211
  ドキュメントは **ツリー構造を保持** してエクスポートされます:
198
212
 
199
213
  ### ディレクトリ構造の保持
214
+
200
215
  - Backlogのドキュメントツリーの階層構造がそのままローカルディレクトリ構造として再現されます
201
216
  - フォルダはディレクトリとして作成され、ドキュメントはMarkdownファイルとして保存されます
202
217
 
203
218
  ### 出力例
219
+
204
220
  ```
205
221
  documents/
206
222
  ├── プロジェクト概要/
@@ -217,6 +233,7 @@ documents/
217
233
  ```
218
234
 
219
235
  ### 特徴
236
+
220
237
  - **階層構造の完全再現**: Backlogのフォルダ階層がそのまま保持されます
221
238
  - **重複処理の防止**: 同じドキュメントが複数回処理されることを防ぎます
222
239
  - **ファイル名の自動サニタイズ**: 不正な文字を自動的に除去して安全なファイル名を生成します
@@ -249,6 +266,7 @@ $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY
249
266
  `all`コマンドでは、以下のフラグを使用してエクスポート対象を制御できます:
250
267
 
251
268
  ### --only フラグ
269
+
252
270
  特定のデータタイプのみをエクスポートします。カンマ区切りで複数指定可能です。
253
271
 
254
272
  ```sh
@@ -260,6 +278,7 @@ $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY
260
278
  ```
261
279
 
262
280
  ### --exclude フラグ
281
+
263
282
  特定のデータタイプを除外してエクスポートします。カンマ区切りで複数指定可能です。
264
283
 
265
284
  ```sh
@@ -328,7 +347,7 @@ Backlogから課題・Wiki・ドキュメントを取得してMarkdownファイ
328
347
  ```
329
348
  USAGE
330
349
  $ backlog-exporter all --domain <value> --projectIdOrKey <value> [--apiKey <value>] [--exclude <value>]
331
- [-m <value>] [--only <value>] [-o <value>]
350
+ [--issueKeyFileName] [--issueKeyFolder] [-m <value>] [--only <value>] [-o <value>]
332
351
 
333
352
  FLAGS
334
353
  -m, --maxCount=<value> [default: 5000] 一度に取得する課題の最大数(デフォルト: 5000)
@@ -336,6 +355,8 @@ FLAGS
336
355
  --apiKey=<value> Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)
337
356
  --domain=<value> (required) Backlog domain (e.g. example.backlog.jp)
338
357
  --exclude=<value> Exclude the specified types, separated by commas (e.g., 'documents,wiki')
358
+ --issueKeyFileName ファイル名を課題キーにする
359
+ --issueKeyFolder 課題キーでフォルダを作成する
339
360
  --only=<value> Export only the specified types, separated by commas (e.g., 'issues,wiki')
340
361
  --projectIdOrKey=<value> (required) Backlog project ID or key
341
362
 
@@ -357,9 +378,18 @@ EXAMPLES
357
378
 
358
379
  $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000
359
380
  最大1000件の課題を取得する(デフォルトは5000件)
381
+
382
+ $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName
383
+ ファイル名を課題キーにする
384
+
385
+ $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder
386
+ 課題キーでフォルダを作成する
387
+
388
+ $ backlog-exporter all --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder
389
+ 課題キーでフォルダを作成し、ファイル名も課題キーにする
360
390
  ```
361
391
 
362
- _See code: [src/commands/all/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.6.1/src/commands/all/index.ts)_
392
+ _See code: [src/commands/all/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.7.1/src/commands/all/index.ts)_
363
393
 
364
394
  ## `backlog-exporter document`
365
395
 
@@ -391,7 +421,7 @@ EXAMPLES
391
421
  キーワード「仕様書」を含むドキュメントのみを取得する
392
422
  ```
393
423
 
394
- _See code: [src/commands/document/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.6.1/src/commands/document/index.ts)_
424
+ _See code: [src/commands/document/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.7.1/src/commands/document/index.ts)_
395
425
 
396
426
  ## `backlog-exporter help [COMMAND]`
397
427
 
@@ -419,14 +449,16 @@ Backlogから課題を取得してMarkdownファイルとして保存する
419
449
 
420
450
  ```
421
451
  USAGE
422
- $ backlog-exporter issue --domain <value> --projectIdOrKey <value> [--apiKey <value>] [-m <value>] [-o
423
- <value>] [--statusId <value>]
452
+ $ backlog-exporter issue --domain <value> --projectIdOrKey <value> [--apiKey <value>]
453
+ [--issueKeyFileName] [--issueKeyFolder] [-m <value>] [-o <value>] [--statusId <value>]
424
454
 
425
455
  FLAGS
426
456
  -m, --maxCount=<value> [default: 5000] 一度に取得する課題の最大数(デフォルト: 5000)
427
457
  -o, --output=<value> 出力ディレクトリパス
428
458
  --apiKey=<value> Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)
429
459
  --domain=<value> (required) Backlog domain (e.g. example.backlog.jp)
460
+ --issueKeyFileName ファイル名を課題キーにする
461
+ --issueKeyFolder 課題キーでフォルダを作成する
430
462
  --projectIdOrKey=<value> (required) Backlog project ID or key
431
463
  --statusId=<value> ステータスID(カンマ区切りで複数指定可能)
432
464
 
@@ -445,9 +477,18 @@ EXAMPLES
445
477
 
446
478
  $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 10000
447
479
  最大10000件の課題を取得する(デフォルトは5000件)
480
+
481
+ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName
482
+ ファイル名を課題キーにする
483
+
484
+ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder
485
+ 課題キーでフォルダを作成する
486
+
487
+ $ backlog-exporter issue --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder
488
+ 課題キーでフォルダを作成し、ファイル名も課題キーにする
448
489
  ```
449
490
 
450
- _See code: [src/commands/issue/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.6.1/src/commands/issue/index.ts)_
491
+ _See code: [src/commands/issue/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.7.1/src/commands/issue/index.ts)_
451
492
 
452
493
  ## `backlog-exporter plugins`
453
494
 
@@ -746,7 +787,7 @@ Backlogから最新データを取得して更新する
746
787
  ```
747
788
  USAGE
748
789
  $ backlog-exporter update [DIRECTORY] [--apiKey <value>] [--documentsOnly] [--domain <value>] [-f]
749
- [--issuesOnly] [--projectIdOrKey <value>] [--wikisOnly]
790
+ [--issueKeyFileName] [--issueKeyFolder] [--issuesOnly] [--projectIdOrKey <value>] [--wikisOnly]
750
791
 
751
792
  ARGUMENTS
752
793
  DIRECTORY 更新対象のディレクトリ(設定ファイルが保存されている場所)
@@ -756,6 +797,8 @@ FLAGS
756
797
  --apiKey=<value> Backlog API key (環境変数 BACKLOG_API_KEY からも自動読み取り可能)
757
798
  --documentsOnly ドキュメントのみを更新する
758
799
  --domain=<value> Backlog domain (e.g. example.backlog.jp)
800
+ --issueKeyFileName ファイル名を課題キーにする
801
+ --issueKeyFolder 課題キーでフォルダを作成する
759
802
  --issuesOnly 課題のみを更新する
760
803
  --projectIdOrKey=<value> Backlog project ID or key
761
804
  --wikisOnly Wikiのみを更新する
@@ -775,9 +818,18 @@ EXAMPLES
775
818
 
776
819
  $ backlog-exporter update ./my-project
777
820
  指定したディレクトリの設定を使用して更新する
821
+
822
+ $ backlog-exporter update --issueKeyFileName
823
+ ファイル名を課題キーにする
824
+
825
+ $ backlog-exporter update --issueKeyFolder
826
+ 課題キーでフォルダを作成する
827
+
828
+ $ backlog-exporter update --issueKeyFileName --issueKeyFolder
829
+ 課題キーでフォルダを作成し、ファイル名も課題キーにする
778
830
  ```
779
831
 
780
- _See code: [src/commands/update/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.6.1/src/commands/update/index.ts)_
832
+ _See code: [src/commands/update/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.7.1/src/commands/update/index.ts)_
781
833
 
782
834
  ## `backlog-exporter wiki`
783
835
 
@@ -804,7 +856,7 @@ EXAMPLES
804
856
  指定したディレクトリにWikiを保存する
805
857
  ```
806
858
 
807
- _See code: [src/commands/wiki/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.6.1/src/commands/wiki/index.ts)_
859
+ _See code: [src/commands/wiki/index.ts](https://github.com/ShuntaToda/backlog-exporter/blob/v0.7.1/src/commands/wiki/index.ts)_
808
860
  <!-- commandsstop -->
809
861
 
810
862
  # 出力形式
@@ -828,12 +880,12 @@ _See code: [src/commands/wiki/index.ts](https://github.com/ShuntaToda/backlog-ex
828
880
 
829
881
  ## カスタム属性
830
882
 
831
- | 属性名 | 値 |
832
- |--------|----|
833
- | 工数(エンジニア) | 3 |
834
- | 工数(PPO) | なし |
835
- | 担当チーム | フロントエンド, バックエンド |
836
- | 詳細 | 実装内容<br>- 機能A<br>- 機能B |
883
+ | 属性名 | 値 |
884
+ | ------------------ | ------------------------------ |
885
+ | 工数(エンジニア) | 3 |
886
+ | 工数(PPO) | なし |
887
+ | 担当チーム | フロントエンド, バックエンド |
888
+ | 詳細 | 実装内容<br>- 機能A<br>- 機能B |
837
889
 
838
890
  ## 詳細
839
891
 
@@ -892,10 +944,12 @@ Backlog の書式がそのまま保持されます。
892
944
  Backlog の書式がそのまま保持されます。
893
945
 
894
946
  ## 添付ファイル
947
+
895
948
  - **資料.pdf** (1024.5 KB) - 作成者: 山田太郎, 作成日時: 2023/01/01 10:00:00
896
949
  - **画像.png** (256.3 KB) - 作成者: 佐藤次郎, 作成日時: 2023/01/01 10:30:00
897
950
 
898
951
  ## タグ
952
+
899
953
  - 仕様書
900
954
  - 設計書
901
955
  ```
@@ -910,3 +964,13 @@ Backlog の書式がそのまま保持されます。
910
964
  - **キーワード検索**: ドキュメントの検索キーワード対応
911
965
  - **差分更新**: 前回の更新以降に変更されたデータのみを更新
912
966
  - **カスタム属性対応**: 課題のカスタム属性をテーブル形式で表示(配列・オブジェクト・プリミティブ値に対応)
967
+
968
+ ## 開発への貢献
969
+
970
+ backlog-exporterはオープンソースプロジェクトです。バグ報告、機能提案、プルリクエストなど、あらゆる形での貢献を歓迎しています。
971
+
972
+ 詳しくは [CONTRIBUTING.md](docs/CONTRIBUTING.md) をご覧ください。
973
+
974
+ ## ライセンス
975
+
976
+ このプロジェクトは[MIT License](LICENSE)の下で公開されています。
@@ -6,6 +6,8 @@ export default class All extends Command {
6
6
  apiKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  domain: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
8
  exclude: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ issueKeyFileName: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ issueKeyFolder: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
11
  maxCount: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
12
  only: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
13
  output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -24,6 +24,15 @@ export default class All extends Command {
24
24
  `,
25
25
  `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000
26
26
  最大1000件の課題を取得する(デフォルトは5000件)
27
+ `,
28
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName
29
+ ファイル名を課題キーにする
30
+ `,
31
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder
32
+ 課題キーでフォルダを作成する
33
+ `,
34
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder
35
+ 課題キーでフォルダを作成し、ファイル名も課題キーにする
27
36
  `,
28
37
  ];
29
38
  static flags = {
@@ -39,6 +48,14 @@ export default class All extends Command {
39
48
  description: "Exclude the specified types, separated by commas (e.g., 'documents,wiki')",
40
49
  required: false,
41
50
  }),
51
+ issueKeyFileName: Flags.boolean({
52
+ description: 'ファイル名を課題キーにする',
53
+ required: false,
54
+ }),
55
+ issueKeyFolder: Flags.boolean({
56
+ description: '課題キーでフォルダを作成する',
57
+ required: false,
58
+ }),
42
59
  maxCount: Flags.integer({
43
60
  char: 'm',
44
61
  default: 5000,
@@ -62,7 +79,7 @@ export default class All extends Command {
62
79
  async run() {
63
80
  const { flags } = await this.parse(All);
64
81
  try {
65
- const { domain, exclude, maxCount, only, projectIdOrKey } = flags;
82
+ const { domain, exclude, issueKeyFileName, issueKeyFolder, maxCount, only, projectIdOrKey } = flags;
66
83
  const apiKey = flags.apiKey || getApiKey(this);
67
84
  const outputRoot = flags.output || './backlog-data';
68
85
  // Check for conflicting flags
@@ -77,7 +94,7 @@ export default class All extends Command {
77
94
  else if (exclude) {
78
95
  const excludeTargets = exclude.split(',');
79
96
  const allTargets = ['issues', 'wiki', 'documents'];
80
- targets = allTargets.filter(target => !excludeTargets.includes(target));
97
+ targets = allTargets.filter((target) => !excludeTargets.includes(target));
81
98
  }
82
99
  else {
83
100
  targets = ['issues', 'wiki', 'documents'];
@@ -108,6 +125,8 @@ export default class All extends Command {
108
125
  apiKey,
109
126
  domain,
110
127
  folderType: FolderType.ISSUE,
128
+ issueKeyFileName,
129
+ issueKeyFolder,
111
130
  outputDir: issueOutput,
112
131
  projectIdOrKey,
113
132
  });
@@ -117,6 +136,8 @@ export default class All extends Command {
117
136
  apiKey,
118
137
  count: maxCount,
119
138
  domain,
139
+ issueKeyFileName,
140
+ issueKeyFolder,
120
141
  outputDir: issueOutput,
121
142
  projectId,
122
143
  });
@@ -5,6 +5,8 @@ export default class Issue extends Command {
5
5
  static flags: {
6
6
  apiKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  domain: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ issueKeyFileName: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ issueKeyFolder: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
10
  maxCount: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
9
11
  output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
12
  projectIdOrKey: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
@@ -20,6 +20,15 @@ export default class Issue extends Command {
20
20
  `,
21
21
  `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 10000
22
22
  最大10000件の課題を取得する(デフォルトは5000件)
23
+ `,
24
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName
25
+ ファイル名を課題キーにする
26
+ `,
27
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder
28
+ 課題キーでフォルダを作成する
29
+ `,
30
+ `<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder
31
+ 課題キーでフォルダを作成し、ファイル名も課題キーにする
23
32
  `,
24
33
  ];
25
34
  static flags = {
@@ -31,6 +40,14 @@ export default class Issue extends Command {
31
40
  description: 'Backlog domain (e.g. example.backlog.jp)',
32
41
  required: true,
33
42
  }),
43
+ issueKeyFileName: Flags.boolean({
44
+ description: 'ファイル名を課題キーにする',
45
+ required: false,
46
+ }),
47
+ issueKeyFolder: Flags.boolean({
48
+ description: '課題キーでフォルダを作成する',
49
+ required: false,
50
+ }),
34
51
  maxCount: Flags.integer({
35
52
  char: 'm',
36
53
  default: 5000,
@@ -54,7 +71,7 @@ export default class Issue extends Command {
54
71
  async run() {
55
72
  const { flags } = await this.parse(Issue);
56
73
  try {
57
- const { domain, maxCount, projectIdOrKey, statusId } = flags;
74
+ const { domain, issueKeyFileName, issueKeyFolder, maxCount, projectIdOrKey, statusId } = flags;
58
75
  const apiKey = flags.apiKey || getApiKey(this);
59
76
  const outputDir = flags.output || './backlog-issues';
60
77
  // 出力ディレクトリの作成
@@ -67,6 +84,8 @@ export default class Issue extends Command {
67
84
  apiKey,
68
85
  domain,
69
86
  folderType: FolderType.ISSUE,
87
+ issueKeyFileName,
88
+ issueKeyFolder,
70
89
  outputDir,
71
90
  projectIdOrKey,
72
91
  });
@@ -75,6 +94,8 @@ export default class Issue extends Command {
75
94
  apiKey,
76
95
  count: maxCount,
77
96
  domain,
97
+ issueKeyFileName,
98
+ issueKeyFolder,
78
99
  outputDir,
79
100
  projectId,
80
101
  statusId,
@@ -10,6 +10,8 @@ export default class Update extends Command {
10
10
  documentsOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
11
  domain: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ issueKeyFileName: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ issueKeyFolder: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
15
  issuesOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
16
  projectIdOrKey: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
17
  wikisOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -28,6 +28,15 @@ export default class Update extends Command {
28
28
  `,
29
29
  `<%= config.bin %> <%= command.id %> ./my-project
30
30
  指定したディレクトリの設定を使用して更新する
31
+ `,
32
+ `<%= config.bin %> <%= command.id %> --issueKeyFileName
33
+ ファイル名を課題キーにする
34
+ `,
35
+ `<%= config.bin %> <%= command.id %> --issueKeyFolder
36
+ 課題キーでフォルダを作成する
37
+ `,
38
+ `<%= config.bin %> <%= command.id %> --issueKeyFileName --issueKeyFolder
39
+ 課題キーでフォルダを作成し、ファイル名も課題キーにする
31
40
  `,
32
41
  ];
33
42
  static flags = {
@@ -48,6 +57,14 @@ export default class Update extends Command {
48
57
  description: '確認プロンプトをスキップする',
49
58
  required: false,
50
59
  }),
60
+ issueKeyFileName: Flags.boolean({
61
+ description: 'ファイル名を課題キーにする',
62
+ required: false,
63
+ }),
64
+ issueKeyFolder: Flags.boolean({
65
+ description: '課題キーでフォルダを作成する',
66
+ required: false,
67
+ }),
51
68
  issuesOnly: Flags.boolean({
52
69
  description: '課題のみを更新する',
53
70
  required: false,
@@ -177,6 +194,9 @@ export default class Update extends Command {
177
194
  const projectIdOrKey = flags.projectIdOrKey || settings.projectIdOrKey;
178
195
  const { folderType } = settings;
179
196
  const { documentsOnly, force, issuesOnly, wikisOnly } = flags;
197
+ // 設定ファイルからオプションを読み込み、コマンドライン引数で上書き
198
+ const issueKeyFileName = flags.issueKeyFileName ?? settings.issueKeyFileName ?? false;
199
+ const issueKeyFolder = flags.issueKeyFolder ?? settings.issueKeyFolder ?? false;
180
200
  // 必須パラメータの検証
181
201
  if (!domain) {
182
202
  this.warn(`${targetDir}: ドメインが指定されていません。スキップします。`);
@@ -220,6 +240,8 @@ export default class Update extends Command {
220
240
  await this.updateIssues({
221
241
  apiKey,
222
242
  domain,
243
+ issueKeyFileName,
244
+ issueKeyFolder,
223
245
  projectId,
224
246
  projectIdOrKey,
225
247
  targetDir,
@@ -279,6 +301,8 @@ export default class Update extends Command {
279
301
  apiKey: options.apiKey,
280
302
  count: 100,
281
303
  domain: options.domain,
304
+ issueKeyFileName: options.issueKeyFileName,
305
+ issueKeyFolder: options.issueKeyFolder,
282
306
  lastUpdated,
283
307
  outputDir: options.targetDir,
284
308
  projectId: options.projectId,
@@ -20,11 +20,15 @@ export declare function createCustomFieldsSection(customFields?: Array<{
20
20
  * @param options.outputDir 出力ディレクトリ
21
21
  * @param options.projectId プロジェクトID
22
22
  * @param options.statusId ステータスID
23
+ * @param options.issueKeyFileName ファイル名を課題キーにするかどうか
24
+ * @param options.issueKeyFolder 課題キーでフォルダを作成するかどうか
23
25
  */
24
26
  export declare function downloadIssues(command: Command, options: {
25
27
  apiKey: string;
26
28
  count?: number;
27
29
  domain: string;
30
+ issueKeyFileName?: boolean;
31
+ issueKeyFolder?: boolean;
28
32
  lastUpdated?: string;
29
33
  outputDir: string;
30
34
  projectId: number;
@@ -21,7 +21,7 @@ export function createCustomFieldsSection(customFields) {
21
21
  if (Array.isArray(customField.value)) {
22
22
  // 配列の場合(複数選択など)
23
23
  fieldValue = customField.value
24
- .map(item => item.name || item.value || String(item))
24
+ .map((item) => item.name || item.value || String(item))
25
25
  .join(', ');
26
26
  }
27
27
  else if (typeof customField.value === 'object' && customField.value !== null) {
@@ -35,9 +35,7 @@ export function createCustomFieldsSection(customFields) {
35
35
  }
36
36
  }
37
37
  // テーブル内では改行をHTMLの<br>タグに変換し、パイプ文字をエスケープ
38
- const escapedFieldValue = fieldValue
39
- .replaceAll('|', String.raw `\|`)
40
- .replaceAll('\n', '<br>');
38
+ const escapedFieldValue = fieldValue.replaceAll('|', String.raw `\|`).replaceAll('\n', '<br>');
41
39
  customFieldsSection += `| ${customField.name} | ${escapedFieldValue} |\n`;
42
40
  }
43
41
  return customFieldsSection;
@@ -53,6 +51,8 @@ export function createCustomFieldsSection(customFields) {
53
51
  * @param options.outputDir 出力ディレクトリ
54
52
  * @param options.projectId プロジェクトID
55
53
  * @param options.statusId ステータスID
54
+ * @param options.issueKeyFileName ファイル名を課題キーにするかどうか
55
+ * @param options.issueKeyFolder 課題キーでフォルダを作成するかどうか
56
56
  */
57
57
  export async function downloadIssues(command, options) {
58
58
  const baseUrl = `https://${options.domain}/api/v2`;
@@ -155,9 +155,22 @@ export async function downloadIssues(command, options) {
155
155
  // 年ごとのフォルダを作成
156
156
  // eslint-disable-next-line no-await-in-loop
157
157
  await fs.mkdir(yearDirPath, { recursive: true });
158
- // 年ごとのフォルダ内にMarkdownファイルを保存
159
- const issueFileName = `${sanitizeFileName(issue.summary)}.md`;
160
- const issueFilePath = path.join(yearDirPath, issueFileName);
158
+ let issueFilePath;
159
+ let issueFileName;
160
+ if (options.issueKeyFolder) {
161
+ // 年ごとのフォルダ内に、課題キーでフォルダを作成
162
+ const issueKeyDirPath = path.join(yearDirPath, issue.issueKey);
163
+ // eslint-disable-next-line no-await-in-loop
164
+ await fs.mkdir(issueKeyDirPath, { recursive: true });
165
+ // ファイル名を課題名(標準)にするか課題キーにするかを決定
166
+ issueFileName = options.issueKeyFileName ? `${issue.issueKey}.md` : `${sanitizeFileName(issue.summary)}.md`;
167
+ issueFilePath = path.join(issueKeyDirPath, issueFileName);
168
+ }
169
+ else {
170
+ // 年ごとのフォルダ内に、Markdownファイルを作成
171
+ issueFileName = options.issueKeyFileName ? `${issue.issueKey}.md` : `${sanitizeFileName(issue.summary)}.md`;
172
+ issueFilePath = path.join(yearDirPath, issueFileName);
173
+ }
161
174
  // カスタム属性セクションを作成
162
175
  const customFieldsSection = createCustomFieldsSection(issue.customFields);
163
176
  // Markdownファイルに書き込む
@@ -13,6 +13,8 @@ export interface Settings {
13
13
  apiKey?: string;
14
14
  domain?: string;
15
15
  folderType?: FolderType;
16
+ issueKeyFileName?: boolean;
17
+ issueKeyFolder?: boolean;
16
18
  lastUpdated?: string;
17
19
  outputDir?: string;
18
20
  projectIdOrKey?: string;
@@ -9,7 +9,10 @@
9
9
  "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-project\n指定したディレクトリに課題・Wiki・ドキュメントを保存する\n",
10
10
  "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --only issues,wiki\n課題とWikiのみを取得する\n",
11
11
  "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --exclude documents\nドキュメント以外(課題とWiki)を取得する\n",
12
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000\n最大1000件の課題を取得する(デフォルトは5000件)\n"
12
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 1000\n最大1000件の課題を取得する(デフォルトは5000件)\n",
13
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName\nファイル名を課題キーにする\n",
14
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder\n課題キーでフォルダを作成する\n",
15
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder\n課題キーでフォルダを作成し、ファイル名も課題キーにする\n"
13
16
  ],
14
17
  "flags": {
15
18
  "apiKey": {
@@ -36,6 +39,20 @@
36
39
  "multiple": false,
37
40
  "type": "option"
38
41
  },
42
+ "issueKeyFileName": {
43
+ "description": "ファイル名を課題キーにする",
44
+ "name": "issueKeyFileName",
45
+ "required": false,
46
+ "allowNo": false,
47
+ "type": "boolean"
48
+ },
49
+ "issueKeyFolder": {
50
+ "description": "課題キーでフォルダを作成する",
51
+ "name": "issueKeyFolder",
52
+ "required": false,
53
+ "allowNo": false,
54
+ "type": "boolean"
55
+ },
39
56
  "maxCount": {
40
57
  "char": "m",
41
58
  "description": "一度に取得する課題の最大数(デフォルト: 5000)",
@@ -88,14 +105,18 @@
88
105
  "index.js"
89
106
  ]
90
107
  },
91
- "document": {
108
+ "issue": {
92
109
  "aliases": [],
93
110
  "args": {},
94
- "description": "Backlogからドキュメントを取得してMarkdownファイルとして保存する",
111
+ "description": "Backlogから課題を取得してMarkdownファイルとして保存する",
95
112
  "examples": [
96
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\nドキュメントをMarkdownファイルとして保存する\n",
97
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-documents\n指定したディレクトリにドキュメントを保存する\n",
98
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --keyword 仕様書\nキーワード「仕様書」を含むドキュメントのみを取得する\n"
113
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\n課題をMarkdownファイルとして保存する\n",
114
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-issues\n指定したディレクトリに課題を保存する\n",
115
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --statusId 1,2,3\n指定したステータスIDの課題のみを取得する\n",
116
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 10000\n最大10000件の課題を取得する(デフォルトは5000件)\n",
117
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName\nファイル名を課題キーにする\n",
118
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFolder\n課題キーでフォルダを作成する\n",
119
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --issueKeyFileName --issueKeyFolder\n課題キーでフォルダを作成し、ファイル名も課題キーにする\n"
99
120
  ],
100
121
  "flags": {
101
122
  "apiKey": {
@@ -114,10 +135,26 @@
114
135
  "multiple": false,
115
136
  "type": "option"
116
137
  },
117
- "keyword": {
118
- "description": "検索キーワード",
119
- "name": "keyword",
138
+ "issueKeyFileName": {
139
+ "description": "ファイル名を課題キーにする",
140
+ "name": "issueKeyFileName",
120
141
  "required": false,
142
+ "allowNo": false,
143
+ "type": "boolean"
144
+ },
145
+ "issueKeyFolder": {
146
+ "description": "課題キーでフォルダを作成する",
147
+ "name": "issueKeyFolder",
148
+ "required": false,
149
+ "allowNo": false,
150
+ "type": "boolean"
151
+ },
152
+ "maxCount": {
153
+ "char": "m",
154
+ "description": "一度に取得する課題の最大数(デフォルト: 5000)",
155
+ "name": "maxCount",
156
+ "required": false,
157
+ "default": 5000,
121
158
  "hasDynamicHelp": false,
122
159
  "multiple": false,
123
160
  "type": "option"
@@ -138,11 +175,19 @@
138
175
  "hasDynamicHelp": false,
139
176
  "multiple": false,
140
177
  "type": "option"
178
+ },
179
+ "statusId": {
180
+ "description": "ステータスID(カンマ区切りで複数指定可能)",
181
+ "name": "statusId",
182
+ "required": false,
183
+ "hasDynamicHelp": false,
184
+ "multiple": false,
185
+ "type": "option"
141
186
  }
142
187
  },
143
188
  "hasDynamicHelp": false,
144
189
  "hiddenAliases": [],
145
- "id": "document",
190
+ "id": "issue",
146
191
  "pluginAlias": "backlog-exporter",
147
192
  "pluginName": "backlog-exporter",
148
193
  "pluginType": "core",
@@ -152,19 +197,18 @@
152
197
  "relativePath": [
153
198
  "dist",
154
199
  "commands",
155
- "document",
200
+ "issue",
156
201
  "index.js"
157
202
  ]
158
203
  },
159
- "issue": {
204
+ "document": {
160
205
  "aliases": [],
161
206
  "args": {},
162
- "description": "Backlogから課題を取得してMarkdownファイルとして保存する",
207
+ "description": "Backlogからドキュメントを取得してMarkdownファイルとして保存する",
163
208
  "examples": [
164
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\n課題をMarkdownファイルとして保存する\n",
165
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-issues\n指定したディレクトリに課題を保存する\n",
166
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --statusId 1,2,3\n指定したステータスIDの課題のみを取得する\n",
167
- "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --maxCount 10000\n最大10000件の課題を取得する(デフォルトは5000件)\n"
209
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY\nドキュメントをMarkdownファイルとして保存する\n",
210
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --output ./my-documents\n指定したディレクトリにドキュメントを保存する\n",
211
+ "<%= config.bin %> <%= command.id %> --domain example.backlog.jp --projectIdOrKey PROJECT_KEY --apiKey YOUR_API_KEY --keyword 仕様書\nキーワード「仕様書」を含むドキュメントのみを取得する\n"
168
212
  ],
169
213
  "flags": {
170
214
  "apiKey": {
@@ -183,12 +227,10 @@
183
227
  "multiple": false,
184
228
  "type": "option"
185
229
  },
186
- "maxCount": {
187
- "char": "m",
188
- "description": "一度に取得する課題の最大数(デフォルト: 5000)",
189
- "name": "maxCount",
230
+ "keyword": {
231
+ "description": "検索キーワード",
232
+ "name": "keyword",
190
233
  "required": false,
191
- "default": 5000,
192
234
  "hasDynamicHelp": false,
193
235
  "multiple": false,
194
236
  "type": "option"
@@ -209,19 +251,11 @@
209
251
  "hasDynamicHelp": false,
210
252
  "multiple": false,
211
253
  "type": "option"
212
- },
213
- "statusId": {
214
- "description": "ステータスID(カンマ区切りで複数指定可能)",
215
- "name": "statusId",
216
- "required": false,
217
- "hasDynamicHelp": false,
218
- "multiple": false,
219
- "type": "option"
220
254
  }
221
255
  },
222
256
  "hasDynamicHelp": false,
223
257
  "hiddenAliases": [],
224
- "id": "issue",
258
+ "id": "document",
225
259
  "pluginAlias": "backlog-exporter",
226
260
  "pluginName": "backlog-exporter",
227
261
  "pluginType": "core",
@@ -231,7 +265,7 @@
231
265
  "relativePath": [
232
266
  "dist",
233
267
  "commands",
234
- "issue",
268
+ "document",
235
269
  "index.js"
236
270
  ]
237
271
  },
@@ -249,7 +283,10 @@
249
283
  "<%= config.bin %> <%= command.id %>\nカレントディレクトリの設定を使用して更新する\n",
250
284
  "<%= config.bin %> <%= command.id %> --force\n確認プロンプトをスキップする\n",
251
285
  "<%= config.bin %> <%= command.id %> --apiKey YOUR_API_KEY --domain example.backlog.jp --projectIdOrKey PROJECT_KEY\n指定したパラメータで更新する(設定ファイルが存在する場合は上書きされます)\n",
252
- "<%= config.bin %> <%= command.id %> ./my-project\n指定したディレクトリの設定を使用して更新する\n"
286
+ "<%= config.bin %> <%= command.id %> ./my-project\n指定したディレクトリの設定を使用して更新する\n",
287
+ "<%= config.bin %> <%= command.id %> --issueKeyFileName\nファイル名を課題キーにする\n",
288
+ "<%= config.bin %> <%= command.id %> --issueKeyFolder\n課題キーでフォルダを作成する\n",
289
+ "<%= config.bin %> <%= command.id %> --issueKeyFileName --issueKeyFolder\n課題キーでフォルダを作成し、ファイル名も課題キーにする\n"
253
290
  ],
254
291
  "flags": {
255
292
  "apiKey": {
@@ -283,6 +320,20 @@
283
320
  "allowNo": false,
284
321
  "type": "boolean"
285
322
  },
323
+ "issueKeyFileName": {
324
+ "description": "ファイル名を課題キーにする",
325
+ "name": "issueKeyFileName",
326
+ "required": false,
327
+ "allowNo": false,
328
+ "type": "boolean"
329
+ },
330
+ "issueKeyFolder": {
331
+ "description": "課題キーでフォルダを作成する",
332
+ "name": "issueKeyFolder",
333
+ "required": false,
334
+ "allowNo": false,
335
+ "type": "boolean"
336
+ },
286
337
  "issuesOnly": {
287
338
  "description": "課題のみを更新する",
288
339
  "name": "issuesOnly",
@@ -382,5 +433,5 @@
382
433
  ]
383
434
  }
384
435
  },
385
- "version": "0.6.1"
436
+ "version": "0.7.1"
386
437
  }
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.6.1",
4
+ "version": "0.7.1",
5
5
  "author": "ShuntaToda",
6
6
  "bin": {
7
7
  "backlog-exporter": "bin/run.js"
@@ -28,6 +28,7 @@
28
28
  "mocha": "^10",
29
29
  "nock": "^14.0.1",
30
30
  "oclif": "^4",
31
+ "prettier": "^3.6.2",
31
32
  "shx": "^0.3.3",
32
33
  "ts-node": "^10",
33
34
  "typescript": "^5"
@@ -68,6 +69,8 @@
68
69
  },
69
70
  "scripts": {
70
71
  "build": "shx rm -rf dist && tsc -b",
72
+ "format": "prettier --write .",
73
+ "format:check": "prettier --check .",
71
74
  "lint": "eslint",
72
75
  "postpack": "shx rm -f oclif.manifest.json",
73
76
  "posttest": "npm run lint",