atl-fetch 1.0.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/dist/cli/cli.d.ts +61 -0
  4. package/dist/cli/cli.js +131 -0
  5. package/dist/cli/index.d.ts +5 -0
  6. package/dist/cli/index.js +4 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.js +13 -0
  9. package/dist/ports/file/file-port.d.ts +89 -0
  10. package/dist/ports/file/file-port.js +155 -0
  11. package/dist/ports/file/index.d.ts +1 -0
  12. package/dist/ports/file/index.js +1 -0
  13. package/dist/ports/http/http-port.d.ts +107 -0
  14. package/dist/ports/http/http-port.js +238 -0
  15. package/dist/ports/http/index.d.ts +1 -0
  16. package/dist/ports/http/index.js +1 -0
  17. package/dist/services/auth/auth-service.d.ts +79 -0
  18. package/dist/services/auth/auth-service.js +158 -0
  19. package/dist/services/auth/index.d.ts +1 -0
  20. package/dist/services/auth/index.js +1 -0
  21. package/dist/services/confluence/confluence-service.d.ts +152 -0
  22. package/dist/services/confluence/confluence-service.js +510 -0
  23. package/dist/services/confluence/index.d.ts +1 -0
  24. package/dist/services/confluence/index.js +1 -0
  25. package/dist/services/diff/diff-service.d.ts +84 -0
  26. package/dist/services/diff/diff-service.js +881 -0
  27. package/dist/services/diff/index.d.ts +1 -0
  28. package/dist/services/diff/index.js +1 -0
  29. package/dist/services/fetch/fetch-service.d.ts +112 -0
  30. package/dist/services/fetch/fetch-service.js +302 -0
  31. package/dist/services/fetch/index.d.ts +1 -0
  32. package/dist/services/fetch/index.js +1 -0
  33. package/dist/services/jira/index.d.ts +1 -0
  34. package/dist/services/jira/index.js +1 -0
  35. package/dist/services/jira/jira-service.d.ts +100 -0
  36. package/dist/services/jira/jira-service.js +354 -0
  37. package/dist/services/output/index.d.ts +4 -0
  38. package/dist/services/output/index.js +4 -0
  39. package/dist/services/output/output-service.d.ts +67 -0
  40. package/dist/services/output/output-service.js +228 -0
  41. package/dist/services/storage/index.d.ts +6 -0
  42. package/dist/services/storage/index.js +6 -0
  43. package/dist/services/storage/storage-service.d.ts +77 -0
  44. package/dist/services/storage/storage-service.js +738 -0
  45. package/dist/services/text-converter/index.d.ts +1 -0
  46. package/dist/services/text-converter/index.js +1 -0
  47. package/dist/services/text-converter/text-converter.d.ts +35 -0
  48. package/dist/services/text-converter/text-converter.js +681 -0
  49. package/dist/services/url-parser/index.d.ts +1 -0
  50. package/dist/services/url-parser/index.js +1 -0
  51. package/dist/services/url-parser/url-parser.d.ts +43 -0
  52. package/dist/services/url-parser/url-parser.js +283 -0
  53. package/dist/types/auth.d.ts +25 -0
  54. package/dist/types/auth.js +1 -0
  55. package/dist/types/confluence.d.ts +68 -0
  56. package/dist/types/confluence.js +1 -0
  57. package/dist/types/diff.d.ts +77 -0
  58. package/dist/types/diff.js +7 -0
  59. package/dist/types/fetch.d.ts +65 -0
  60. package/dist/types/fetch.js +1 -0
  61. package/dist/types/file.d.ts +22 -0
  62. package/dist/types/file.js +1 -0
  63. package/dist/types/http.d.ts +45 -0
  64. package/dist/types/http.js +1 -0
  65. package/dist/types/jira.d.ts +90 -0
  66. package/dist/types/jira.js +1 -0
  67. package/dist/types/output.d.ts +55 -0
  68. package/dist/types/output.js +7 -0
  69. package/dist/types/result.d.ts +104 -0
  70. package/dist/types/result.js +119 -0
  71. package/dist/types/storage.d.ts +209 -0
  72. package/dist/types/storage.js +6 -0
  73. package/dist/types/url-parser.d.ts +46 -0
  74. package/dist/types/url-parser.js +1 -0
  75. package/package.json +106 -0
@@ -0,0 +1 @@
1
+ export { parseUrl } from './url-parser.js';
@@ -0,0 +1 @@
1
+ export { parseUrl } from './url-parser.js';
@@ -0,0 +1,43 @@
1
+ import { type Result } from 'neverthrow';
2
+ import type { UrlParseError, UrlParseResult } from '../../types/url-parser.js';
3
+ /**
4
+ * Atlassian Cloud の URL を解析し、リソース情報を抽出する
5
+ *
6
+ * サポートする URL 形式:
7
+ * - Jira Issue: `https://{org}.atlassian.net/browse/{ISSUE-KEY}`
8
+ * - Jira Board: `https://{org}.atlassian.net/jira/software/projects/{PROJECT}/boards/{id}?selectedIssue={ISSUE-KEY}`
9
+ * - Confluence Page: `https://{org}.atlassian.net/wiki/spaces/{SPACE}/pages/{PAGE-ID}/{TITLE}`
10
+ *
11
+ * @param url - 解析対象の Atlassian Cloud URL(完全な URL 文字列)
12
+ * @returns 成功時は {@link UrlParseResult} を含む Ok、失敗時は {@link UrlParseError} を含む Err
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // 成功例: Jira Issue URL
17
+ * const result = parseUrl('https://mycompany.atlassian.net/browse/PROJ-123');
18
+ * if (result.isOk()) {
19
+ * console.log(result.value);
20
+ * // { type: 'jira', organization: 'mycompany', resourceId: 'PROJ-123', projectKey: 'PROJ' }
21
+ * }
22
+ * ```
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // 成功例: Confluence ページ URL
27
+ * const result = parseUrl('https://mycompany.atlassian.net/wiki/spaces/DOCS/pages/123456789/Title');
28
+ * if (result.isOk()) {
29
+ * console.log(result.value);
30
+ * // { type: 'confluence', organization: 'mycompany', resourceId: '123456789', spaceKey: 'DOCS' }
31
+ * }
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // 失敗例: Atlassian Cloud 以外の URL
37
+ * const result = parseUrl('https://example.com/browse/PROJ-123');
38
+ * if (result.isErr()) {
39
+ * console.log(result.error.kind); // 'UNSUPPORTED_HOST'
40
+ * }
41
+ * ```
42
+ */
43
+ export declare function parseUrl(url: string): Result<UrlParseResult, UrlParseError>;
@@ -0,0 +1,283 @@
1
+ import { err, ok } from 'neverthrow';
2
+ /**
3
+ * Atlassian Cloud のホスト名パターン
4
+ *
5
+ * キャプチャグループ:
6
+ * - グループ1: 組織名(サブドメイン部分)
7
+ *
8
+ * @example
9
+ * // マッチする例
10
+ * 'mycompany.atlassian.net' // グループ1: 'mycompany'
11
+ * 'my-company-name.atlassian.net' // グループ1: 'my-company-name'
12
+ *
13
+ * @example
14
+ * // マッチしない例
15
+ * 'jira.mycompany.com' // Atlassian Cloud ではない
16
+ * 'atlassian.net' // サブドメインがない
17
+ */
18
+ const ATLASSIAN_CLOUD_HOST_PATTERN = /^([a-z0-9-]+)\.atlassian\.net$/i;
19
+ /**
20
+ * Jira Issue キーのパターン
21
+ *
22
+ * Issue キーは `{プロジェクトキー}-{番号}` の形式。
23
+ * プロジェクトキーは英大文字で始まり、英大文字または数字が続く。
24
+ *
25
+ * キャプチャグループ:
26
+ * - グループ1: プロジェクトキー
27
+ * - グループ2: Issue 番号
28
+ *
29
+ * @example
30
+ * // マッチする例
31
+ * 'PROJ-123' // グループ1: 'PROJ', グループ2: '123'
32
+ * 'ABC-1' // グループ1: 'ABC', グループ2: '1'
33
+ * 'A1B2-999' // グループ1: 'A1B2', グループ2: '999'
34
+ *
35
+ * @example
36
+ * // マッチしない例
37
+ * 'proj-123' // 小文字(ただし i フラグにより実際はマッチする)
38
+ * 'PROJ' // 番号がない
39
+ * '123-PROJ' // 順序が逆
40
+ */
41
+ const JIRA_ISSUE_KEY_PATTERN = /^([A-Z][A-Z0-9]*)-(\d+)$/i;
42
+ /**
43
+ * Confluence ページ URL のパスパターン
44
+ *
45
+ * `/wiki/spaces/{spaceKey}/pages/{pageId}` または
46
+ * `/wiki/spaces/{spaceKey}/pages/{pageId}/{title}` 形式をマッチ。
47
+ *
48
+ * キャプチャグループ:
49
+ * - グループ1: スペースキー
50
+ * - グループ2: ページ ID(任意の文字列、後で数字かどうか検証)
51
+ *
52
+ * @example
53
+ * // マッチする例
54
+ * '/wiki/spaces/DOCS/pages/123456789' // グループ1: 'DOCS', グループ2: '123456789'
55
+ * '/wiki/spaces/TEAM/pages/987654321/Page+Title' // グループ1: 'TEAM', グループ2: '987654321'
56
+ *
57
+ * @example
58
+ * // マッチしない例
59
+ * '/wiki/display/DOCS/Page' // 古い形式
60
+ * '/wiki/spaces/DOCS/overview' // ページではない
61
+ */
62
+ const CONFLUENCE_PAGE_PATH_PATTERN = /^\/wiki\/spaces\/([^/]+)\/pages\/([^/]+)(?:\/.*)?$/;
63
+ /**
64
+ * ページ ID が有効な数字形式かどうかを検証するパターン
65
+ */
66
+ const PAGE_ID_PATTERN = /^\d+$/;
67
+ /**
68
+ * Atlassian Cloud の URL を解析し、リソース情報を抽出する
69
+ *
70
+ * サポートする URL 形式:
71
+ * - Jira Issue: `https://{org}.atlassian.net/browse/{ISSUE-KEY}`
72
+ * - Jira Board: `https://{org}.atlassian.net/jira/software/projects/{PROJECT}/boards/{id}?selectedIssue={ISSUE-KEY}`
73
+ * - Confluence Page: `https://{org}.atlassian.net/wiki/spaces/{SPACE}/pages/{PAGE-ID}/{TITLE}`
74
+ *
75
+ * @param url - 解析対象の Atlassian Cloud URL(完全な URL 文字列)
76
+ * @returns 成功時は {@link UrlParseResult} を含む Ok、失敗時は {@link UrlParseError} を含む Err
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * // 成功例: Jira Issue URL
81
+ * const result = parseUrl('https://mycompany.atlassian.net/browse/PROJ-123');
82
+ * if (result.isOk()) {
83
+ * console.log(result.value);
84
+ * // { type: 'jira', organization: 'mycompany', resourceId: 'PROJ-123', projectKey: 'PROJ' }
85
+ * }
86
+ * ```
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * // 成功例: Confluence ページ URL
91
+ * const result = parseUrl('https://mycompany.atlassian.net/wiki/spaces/DOCS/pages/123456789/Title');
92
+ * if (result.isOk()) {
93
+ * console.log(result.value);
94
+ * // { type: 'confluence', organization: 'mycompany', resourceId: '123456789', spaceKey: 'DOCS' }
95
+ * }
96
+ * ```
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * // 失敗例: Atlassian Cloud 以外の URL
101
+ * const result = parseUrl('https://example.com/browse/PROJ-123');
102
+ * if (result.isErr()) {
103
+ * console.log(result.error.kind); // 'UNSUPPORTED_HOST'
104
+ * }
105
+ * ```
106
+ */
107
+ export function parseUrl(url) {
108
+ // 空文字列チェック
109
+ if (url.trim() === '') {
110
+ return err({
111
+ kind: 'INVALID_FORMAT',
112
+ message: 'URL が空です。有効な Atlassian Cloud URL を指定してください。',
113
+ });
114
+ }
115
+ // URL のパース
116
+ let parsedUrl;
117
+ try {
118
+ parsedUrl = new URL(url);
119
+ }
120
+ catch {
121
+ return err({
122
+ kind: 'INVALID_FORMAT',
123
+ message: `無効な URL 形式です: ${url}`,
124
+ });
125
+ }
126
+ // Atlassian Cloud ホストの検証
127
+ const hostMatch = ATLASSIAN_CLOUD_HOST_PATTERN.exec(parsedUrl.hostname);
128
+ if (!hostMatch) {
129
+ return err({
130
+ kind: 'UNSUPPORTED_HOST',
131
+ message: `Atlassian Cloud 以外の URL はサポートされていません: ${parsedUrl.hostname}`,
132
+ });
133
+ }
134
+ const organization = hostMatch[1];
135
+ if (organization === undefined) {
136
+ return err({
137
+ kind: 'INVALID_FORMAT',
138
+ message: '組織名を抽出できませんでした。',
139
+ });
140
+ }
141
+ // Confluence URL のパース(/wiki/ で始まる場合)
142
+ if (parsedUrl.pathname.startsWith('/wiki/')) {
143
+ return parseConfluenceUrl(parsedUrl, organization);
144
+ }
145
+ // Jira Issue URL のパース
146
+ return parseJiraUrl(parsedUrl, organization);
147
+ }
148
+ /**
149
+ * Jira URL を解析し、Issue 情報を抽出する
150
+ *
151
+ * サポートする URL パターン:
152
+ * 1. `/browse/{ISSUE-KEY}` - 標準的な Issue ページ URL
153
+ * 2. `/jira/software/projects/{PROJECT}/boards/{id}?selectedIssue={ISSUE-KEY}` - ボード上で選択された Issue
154
+ *
155
+ * @param parsedUrl - パース済みの URL オブジェクト
156
+ * @param organization - Atlassian Cloud の組織名(サブドメイン)
157
+ * @returns 成功時は {@link UrlParseResult} を含む Ok、失敗時は {@link UrlParseError} を含む Err
158
+ *
159
+ * @internal この関数は内部実装であり、外部から直接呼び出すべきではありません
160
+ */
161
+ function parseJiraUrl(parsedUrl, organization) {
162
+ const pathname = parsedUrl.pathname;
163
+ // /browse/{key} 形式
164
+ if (pathname.startsWith('/browse/')) {
165
+ const issueKey = pathname.slice('/browse/'.length);
166
+ return validateAndCreateJiraResult(issueKey, organization);
167
+ }
168
+ // /jira/software/projects/.../boards/...?selectedIssue={key} 形式
169
+ if (pathname.includes('/jira/software/projects/')) {
170
+ const selectedIssue = parsedUrl.searchParams.get('selectedIssue');
171
+ if (!selectedIssue) {
172
+ return err({
173
+ kind: 'MISSING_RESOURCE_ID',
174
+ message: 'selectedIssue パラメータが見つかりません。',
175
+ });
176
+ }
177
+ return validateAndCreateJiraResult(selectedIssue, organization);
178
+ }
179
+ return err({
180
+ kind: 'MISSING_RESOURCE_ID',
181
+ message: 'サポートされている Jira URL 形式ではありません。',
182
+ });
183
+ }
184
+ /**
185
+ * Jira Issue キーを検証し、パース結果オブジェクトを生成する
186
+ *
187
+ * Issue キーの形式 `{PROJECT}-{NUMBER}` を検証し、
188
+ * 有効な場合は {@link UrlParseResult} を生成して返す。
189
+ *
190
+ * @param issueKey - 検証対象の Issue キー(例: 'PROJ-123')
191
+ * @param organization - Atlassian Cloud の組織名(サブドメイン)
192
+ * @returns 成功時は {@link UrlParseResult} を含む Ok、失敗時は {@link UrlParseError} を含む Err
193
+ *
194
+ * @remarks
195
+ * エラーケース:
196
+ * - 空文字列の場合: `MISSING_RESOURCE_ID`
197
+ * - 形式が不正な場合: `INVALID_FORMAT`
198
+ *
199
+ * @internal この関数は内部実装であり、外部から直接呼び出すべきではありません
200
+ */
201
+ function validateAndCreateJiraResult(issueKey, organization) {
202
+ // 空チェック
203
+ if (issueKey.trim() === '') {
204
+ return err({
205
+ kind: 'MISSING_RESOURCE_ID',
206
+ message: 'Issue キーが指定されていません。',
207
+ });
208
+ }
209
+ // Issue キー形式の検証
210
+ const keyMatch = JIRA_ISSUE_KEY_PATTERN.exec(issueKey);
211
+ if (!keyMatch) {
212
+ return err({
213
+ kind: 'INVALID_FORMAT',
214
+ message: `無効な Issue キー形式です: ${issueKey}。形式は PROJECT-123 のようにしてください。`,
215
+ });
216
+ }
217
+ const projectKey = keyMatch[1];
218
+ if (projectKey === undefined) {
219
+ return err({
220
+ kind: 'INVALID_FORMAT',
221
+ message: 'プロジェクトキーを抽出できませんでした。',
222
+ });
223
+ }
224
+ return ok({
225
+ organization,
226
+ projectKey,
227
+ resourceId: issueKey,
228
+ type: 'jira',
229
+ });
230
+ }
231
+ /**
232
+ * Confluence URL を解析し、ページ情報を抽出する
233
+ *
234
+ * サポートする URL パターン:
235
+ * 1. `/wiki/spaces/{SPACE}/pages/{PAGE-ID}` - タイトルなし
236
+ * 2. `/wiki/spaces/{SPACE}/pages/{PAGE-ID}/{TITLE}` - タイトルあり
237
+ *
238
+ * @param parsedUrl - パース済みの URL オブジェクト
239
+ * @param organization - Atlassian Cloud の組織名(サブドメイン)
240
+ * @returns 成功時は {@link UrlParseResult} を含む Ok、失敗時は {@link UrlParseError} を含む Err
241
+ *
242
+ * @internal この関数は内部実装であり、外部から直接呼び出すべきではありません
243
+ */
244
+ function parseConfluenceUrl(parsedUrl, organization) {
245
+ const pathname = parsedUrl.pathname;
246
+ // /wiki/spaces/{space}/pages/{id} 形式
247
+ const pageMatch = CONFLUENCE_PAGE_PATH_PATTERN.exec(pathname);
248
+ if (!pageMatch) {
249
+ return err({
250
+ kind: 'MISSING_RESOURCE_ID',
251
+ message: 'サポートされている Confluence URL 形式ではありません。/wiki/spaces/{SPACE}/pages/{PAGE-ID} 形式を使用してください。',
252
+ });
253
+ }
254
+ const spaceKey = pageMatch[1];
255
+ const pageId = pageMatch[2];
256
+ // スペースキーの検証
257
+ if (spaceKey === undefined || spaceKey.trim() === '') {
258
+ return err({
259
+ kind: 'MISSING_RESOURCE_ID',
260
+ message: 'スペースキーが指定されていません。',
261
+ });
262
+ }
263
+ // ページ ID の検証
264
+ if (pageId === undefined || pageId.trim() === '') {
265
+ return err({
266
+ kind: 'MISSING_RESOURCE_ID',
267
+ message: 'ページ ID が指定されていません。',
268
+ });
269
+ }
270
+ // ページ ID が数字形式かどうかを検証
271
+ if (!PAGE_ID_PATTERN.test(pageId)) {
272
+ return err({
273
+ kind: 'INVALID_FORMAT',
274
+ message: `無効なページ ID 形式です: ${pageId}。ページ ID は数字のみで構成される必要があります。`,
275
+ });
276
+ }
277
+ return ok({
278
+ organization,
279
+ resourceId: pageId,
280
+ spaceKey,
281
+ type: 'confluence',
282
+ });
283
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * 認証情報の型
3
+ */
4
+ export interface Credentials {
5
+ /** Atlassian アカウントのメールアドレス */
6
+ readonly email: string;
7
+ /** Atlassian API トークン */
8
+ readonly apiToken: string;
9
+ }
10
+ /**
11
+ * 認証エラーの型
12
+ */
13
+ export type AuthError = {
14
+ kind: 'MISSING_EMAIL';
15
+ message: string;
16
+ } | {
17
+ kind: 'MISSING_TOKEN';
18
+ message: string;
19
+ } | {
20
+ kind: 'INVALID_EMAIL';
21
+ message: string;
22
+ } | {
23
+ kind: 'INVALID_CREDENTIALS';
24
+ message: string;
25
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Confluence ページのバージョン情報の型
3
+ */
4
+ export interface ConfluenceVersion {
5
+ /** バージョン番号 */
6
+ readonly number: number;
7
+ /** 作成者の表示名 */
8
+ readonly by: string;
9
+ /** 作成日時(ISO 8601 形式) */
10
+ readonly when: string;
11
+ /** バージョンメッセージ(null の場合はメッセージなし) */
12
+ readonly message: string | null;
13
+ /** 本文(バージョン詳細取得時のみ) */
14
+ readonly body?: string;
15
+ }
16
+ /**
17
+ * Confluence ページの添付ファイルの型
18
+ */
19
+ export interface ConfluenceAttachment {
20
+ /** 添付ファイル ID */
21
+ readonly id: string;
22
+ /** ファイルタイトル */
23
+ readonly title: string;
24
+ /** メディアタイプ */
25
+ readonly mediaType: string;
26
+ /** ファイルサイズ(バイト) */
27
+ readonly fileSize: number;
28
+ /** ダウンロード URL */
29
+ readonly downloadUrl: string;
30
+ }
31
+ /**
32
+ * Confluence ページの型
33
+ */
34
+ export interface ConfluencePage {
35
+ /** ページ ID */
36
+ readonly id: string;
37
+ /** ページタイトル */
38
+ readonly title: string;
39
+ /** ページ本文(HTML 形式) */
40
+ readonly body: string;
41
+ /** スペースキー */
42
+ readonly spaceKey: string;
43
+ /** 現在のバージョン番号 */
44
+ readonly currentVersion: number;
45
+ /** バージョン一覧 */
46
+ readonly versions: readonly ConfluenceVersion[];
47
+ /** 添付ファイル一覧 */
48
+ readonly attachments: readonly ConfluenceAttachment[];
49
+ }
50
+ /**
51
+ * Confluence サービスのエラーの型
52
+ */
53
+ export type ConfluenceError = {
54
+ kind: 'NOT_FOUND';
55
+ message: string;
56
+ } | {
57
+ kind: 'FORBIDDEN';
58
+ message: string;
59
+ } | {
60
+ kind: 'AUTH_FAILED';
61
+ message: string;
62
+ } | {
63
+ kind: 'NETWORK_ERROR';
64
+ message: string;
65
+ } | {
66
+ kind: 'PARSE_ERROR';
67
+ message: string;
68
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,77 @@
1
+ /**
2
+ * 差分計算に関する型定義
3
+ *
4
+ * DiffService で使用する型を定義する。
5
+ * unified diff 形式での出力、差分統計の計算に対応。
6
+ */
7
+ /**
8
+ * 差分オプション
9
+ *
10
+ * 差分計算時の設定を指定する。
11
+ */
12
+ export interface DiffOptions {
13
+ /** カラー出力を有効にするか */
14
+ readonly colorEnabled: boolean;
15
+ /** コンテキスト行数(デフォルト: 3) */
16
+ readonly contextLines?: number;
17
+ }
18
+ /**
19
+ * 差分行の種別
20
+ */
21
+ export type DiffLineType = 'add' | 'remove' | 'context';
22
+ /**
23
+ * 差分行
24
+ *
25
+ * 1行分の差分情報を表す。
26
+ */
27
+ export interface DiffLine {
28
+ /** 行の種別 */
29
+ readonly type: DiffLineType;
30
+ /** 行の内容 */
31
+ readonly content: string;
32
+ }
33
+ /**
34
+ * 差分ハンク
35
+ *
36
+ * 連続した差分行のグループを表す。
37
+ * unified diff 形式の @@ -start,lines +start,lines @@ に対応。
38
+ */
39
+ export interface DiffHunk {
40
+ /** 変更前テキストでの開始行番号 */
41
+ readonly oldStart: number;
42
+ /** 変更前テキストでの行数 */
43
+ readonly oldLines: number;
44
+ /** 変更後テキストでの開始行番号 */
45
+ readonly newStart: number;
46
+ /** 変更後テキストでの行数 */
47
+ readonly newLines: number;
48
+ /** 差分行のリスト */
49
+ readonly lines: readonly DiffLine[];
50
+ }
51
+ /**
52
+ * 差分統計
53
+ *
54
+ * 差分の追加・削除行数を集計した情報。
55
+ */
56
+ export interface DiffStats {
57
+ /** 追加された行数 */
58
+ readonly additions: number;
59
+ /** 削除された行数 */
60
+ readonly deletions: number;
61
+ /** 変更があったハンクの数 */
62
+ readonly changes: number;
63
+ }
64
+ /**
65
+ * 差分結果
66
+ *
67
+ * 差分計算の結果を表す。
68
+ * ハンクのリストとフォーマット済み文字列を含む。
69
+ */
70
+ export interface DiffResult {
71
+ /** 差分ハンクのリスト */
72
+ readonly hunks: readonly DiffHunk[];
73
+ /** unified diff 形式でフォーマットされた文字列 */
74
+ readonly formatted: string;
75
+ /** 差分統計 */
76
+ readonly stats: DiffStats;
77
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 差分計算に関する型定義
3
+ *
4
+ * DiffService で使用する型を定義する。
5
+ * unified diff 形式での出力、差分統計の計算に対応。
6
+ */
7
+ export {};
@@ -0,0 +1,65 @@
1
+ import type { ConfluencePage } from './confluence.js';
2
+ import type { JiraIssue } from './jira.js';
3
+ /**
4
+ * Fetch 結果の型(判別共用体)
5
+ *
6
+ * Jira または Confluence のいずれかのデータを含む
7
+ */
8
+ export type FetchResult = {
9
+ readonly type: 'jira';
10
+ readonly data: JiraIssue;
11
+ } | {
12
+ readonly type: 'confluence';
13
+ readonly data: ConfluencePage;
14
+ };
15
+ /**
16
+ * Fetch サービスのエラーの型
17
+ */
18
+ export type FetchError = {
19
+ kind: 'URL_PARSE_ERROR';
20
+ message: string;
21
+ } | {
22
+ kind: 'JIRA_ERROR';
23
+ message: string;
24
+ } | {
25
+ kind: 'CONFLUENCE_ERROR';
26
+ message: string;
27
+ } | {
28
+ kind: 'AUTH_FAILED';
29
+ message: string;
30
+ } | {
31
+ kind: 'NOT_FOUND';
32
+ message: string;
33
+ } | {
34
+ kind: 'FORBIDDEN';
35
+ message: string;
36
+ } | {
37
+ kind: 'NETWORK_ERROR';
38
+ message: string;
39
+ } | {
40
+ kind: 'OUTPUT_ERROR';
41
+ message: string;
42
+ } | {
43
+ kind: 'STORAGE_ERROR';
44
+ message: string;
45
+ };
46
+ /**
47
+ * FetchAndSave のオプションの型
48
+ */
49
+ export interface FetchAndSaveOptions {
50
+ /** 出力先ベースディレクトリ */
51
+ readonly baseDir: string;
52
+ /** 入力 URL */
53
+ readonly sourceUrl: string;
54
+ /** CLI バージョン */
55
+ readonly cliVersion: string;
56
+ }
57
+ /**
58
+ * FetchAndSave の結果の型
59
+ */
60
+ export interface FetchAndSaveResult {
61
+ /** 保存先ディレクトリパス */
62
+ readonly directory: string;
63
+ /** 生成された Manifest */
64
+ readonly manifest: import('./storage.js').Manifest;
65
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ファイルエラーの型
3
+ *
4
+ * FilePort の操作で発生するエラーを表現する判別共用体。
5
+ */
6
+ export type FileError = {
7
+ kind: 'WRITE_FAILED';
8
+ path: string;
9
+ message: string;
10
+ } | {
11
+ kind: 'PERMISSION_DENIED';
12
+ path: string;
13
+ message: string;
14
+ } | {
15
+ kind: 'DISK_FULL';
16
+ path: string;
17
+ message: string;
18
+ } | {
19
+ kind: 'READ_FAILED';
20
+ path: string;
21
+ message: string;
22
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ /**
2
+ * HTTP リクエストオプションの型
3
+ */
4
+ export interface HttpRequestOptions {
5
+ /** HTTP メソッド */
6
+ readonly method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
7
+ /** リクエストヘッダー */
8
+ readonly headers?: Record<string, string>;
9
+ /** リクエストボディ */
10
+ readonly body?: string;
11
+ /** タイムアウト(ミリ秒) */
12
+ readonly timeout?: number;
13
+ }
14
+ /**
15
+ * HTTP レスポンスの型
16
+ */
17
+ export interface HttpResponse<T> {
18
+ /** HTTP ステータスコード */
19
+ readonly status: number;
20
+ /** レスポンスヘッダー */
21
+ readonly headers: Record<string, string>;
22
+ /** レスポンスデータ */
23
+ readonly data: T;
24
+ }
25
+ /**
26
+ * HTTP エラーの型
27
+ */
28
+ export type HttpError = {
29
+ kind: 'NETWORK_ERROR';
30
+ message: string;
31
+ } | {
32
+ kind: 'TIMEOUT';
33
+ message: string;
34
+ } | {
35
+ kind: 'HTTP_ERROR';
36
+ status: number;
37
+ message: string;
38
+ };
39
+ /**
40
+ * ダウンロード進捗コールバックの型
41
+ *
42
+ * @param transferred - 転送済みバイト数
43
+ * @param total - 総バイト数(不明な場合は undefined)
44
+ */
45
+ export type ProgressCallback = (transferred: number, total: number | undefined) => void;
@@ -0,0 +1 @@
1
+ export {};