tdecollab 0.1.3 → 0.2.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.
@@ -347,6 +347,381 @@ function loadConfluenceConfig() {
347
347
  }
348
348
  };
349
349
  }
350
+ function loadJiraConfig() {
351
+ const baseUrl = getEnvOrThrow("JIRA_BASE_URL", "JIRA \uAE30\uBCF8 URL");
352
+ const username = process.env.JIRA_USERNAME;
353
+ const token = getEnvOrThrow("JIRA_API_TOKEN", "JIRA API \uD1A0\uD070");
354
+ return {
355
+ baseUrl,
356
+ auth: {
357
+ username,
358
+ token
359
+ }
360
+ };
361
+ }
362
+ function loadGitlabConfig() {
363
+ const baseUrl = process.env.GITLAB_BASE_URL || "https://gitlab.com";
364
+ const token = getEnvOrThrow("GITLAB_PRIVATE_TOKEN", "GitLab Private Token");
365
+ return {
366
+ baseUrl,
367
+ auth: {
368
+ token
369
+ }
370
+ };
371
+ }
372
+
373
+ // src/jira/api/issue.ts
374
+ var JiraIssueApi = class {
375
+ constructor(client) {
376
+ this.client = client;
377
+ }
378
+ async getIssue(issueKey, fields, expand) {
379
+ const params = {};
380
+ if (fields && fields.length > 0) {
381
+ params.fields = fields.join(",");
382
+ }
383
+ if (expand && expand.length > 0) {
384
+ params.expand = expand.join(",");
385
+ }
386
+ const response = await this.client.get(`/rest/api/2/issue/${issueKey}`, { params });
387
+ return response.data;
388
+ }
389
+ async createIssue(params) {
390
+ const fields = {
391
+ project: { key: params.projectKey },
392
+ summary: params.summary,
393
+ issuetype: { name: params.issueType }
394
+ };
395
+ if (params.description) fields.description = params.description;
396
+ if (params.assignee) fields.assignee = { name: params.assignee };
397
+ if (params.priority) fields.priority = { name: params.priority };
398
+ if (params.labels) fields.labels = params.labels;
399
+ if (params.components) {
400
+ fields.components = params.components.map((name) => ({ name }));
401
+ }
402
+ if (params.parentKey) {
403
+ fields.parent = { key: params.parentKey };
404
+ }
405
+ if (params.customFields) {
406
+ Object.assign(fields, params.customFields);
407
+ }
408
+ const response = await this.client.post("/rest/api/2/issue", { fields });
409
+ return response.data;
410
+ }
411
+ async updateIssue(issueKey, params) {
412
+ const fields = {};
413
+ if (params.summary) fields.summary = params.summary;
414
+ if (params.description !== void 0) fields.description = params.description;
415
+ if (params.assignee !== void 0) fields.assignee = params.assignee ? { name: params.assignee } : null;
416
+ if (params.priority) fields.priority = { name: params.priority };
417
+ if (params.labels) fields.labels = params.labels;
418
+ if (params.components) {
419
+ fields.components = params.components.map((name) => ({ name }));
420
+ }
421
+ if (params.customFields) {
422
+ Object.assign(fields, params.customFields);
423
+ }
424
+ await this.client.put(`/rest/api/2/issue/${issueKey}`, { fields });
425
+ }
426
+ async deleteIssue(issueKey, deleteSubtasks = false) {
427
+ await this.client.delete(`/rest/api/2/issue/${issueKey}`, {
428
+ params: { deleteSubtasks }
429
+ });
430
+ }
431
+ };
432
+
433
+ // src/jira/api/search.ts
434
+ var JiraSearchApi = class {
435
+ constructor(client) {
436
+ this.client = client;
437
+ }
438
+ async searchByJql(jql, startAt = 0, maxResults = 50, fields) {
439
+ const params = {
440
+ jql,
441
+ startAt,
442
+ maxResults
443
+ };
444
+ if (fields && fields.length > 0) {
445
+ params.fields = fields.join(",");
446
+ }
447
+ const response = await this.client.get("/rest/api/2/search", { params });
448
+ return response.data;
449
+ }
450
+ };
451
+
452
+ // src/jira/api/transition.ts
453
+ var JiraTransitionApi = class {
454
+ constructor(client) {
455
+ this.client = client;
456
+ }
457
+ async getTransitions(issueKey) {
458
+ const response = await this.client.get(`/rest/api/2/issue/${issueKey}/transitions`);
459
+ return response.data.transitions;
460
+ }
461
+ async doTransition(issueKey, transitionId, fields) {
462
+ const data = {
463
+ transition: { id: transitionId }
464
+ };
465
+ if (fields) {
466
+ data.fields = fields;
467
+ }
468
+ await this.client.post(`/rest/api/2/issue/${issueKey}/transitions`, data);
469
+ }
470
+ };
471
+
472
+ // src/jira/api/comment.ts
473
+ var JiraCommentApi = class {
474
+ constructor(client) {
475
+ this.client = client;
476
+ }
477
+ async getComments(issueKey, startAt = 0, maxResults = 50) {
478
+ const response = await this.client.get(`/rest/api/2/issue/${issueKey}/comment`, {
479
+ params: { startAt, maxResults }
480
+ });
481
+ return response.data;
482
+ }
483
+ async addComment(issueKey, body) {
484
+ const response = await this.client.post(`/rest/api/2/issue/${issueKey}/comment`, { body });
485
+ return response.data;
486
+ }
487
+ async updateComment(issueKey, commentId, body) {
488
+ const response = await this.client.put(
489
+ `/rest/api/2/issue/${issueKey}/comment/${commentId}`,
490
+ { body }
491
+ );
492
+ return response.data;
493
+ }
494
+ async deleteComment(issueKey, commentId) {
495
+ await this.client.delete(`/rest/api/2/issue/${issueKey}/comment/${commentId}`);
496
+ }
497
+ };
498
+
499
+ // src/jira/api/project.ts
500
+ var JiraProjectApi = class {
501
+ constructor(client) {
502
+ this.client = client;
503
+ }
504
+ async getProjects() {
505
+ const response = await this.client.get("/rest/api/2/project");
506
+ return response.data;
507
+ }
508
+ async getProject(projectKey) {
509
+ const response = await this.client.get(`/rest/api/2/project/${projectKey}`);
510
+ return response.data;
511
+ }
512
+ async getBoards(projectKeyOrId, type) {
513
+ const params = {};
514
+ if (projectKeyOrId) params.projectKeyOrId = projectKeyOrId;
515
+ if (type) params.type = type;
516
+ const response = await this.client.get("/rest/agile/1.0/board", { params });
517
+ return response.data;
518
+ }
519
+ async getSprints(boardId, state) {
520
+ const params = {};
521
+ if (state) params.state = state;
522
+ const response = await this.client.get(`/rest/agile/1.0/board/${boardId}/sprint`, {
523
+ params
524
+ });
525
+ return response.data;
526
+ }
527
+ };
528
+
529
+ // src/jira/api/client.ts
530
+ function createJiraClient(config) {
531
+ return createHttpClient(config);
532
+ }
533
+
534
+ // src/gitlab/api/project.ts
535
+ var GitlabProjectApi = class {
536
+ constructor(client) {
537
+ this.client = client;
538
+ }
539
+ async getProjects(params) {
540
+ const response = await this.client.get("/projects", {
541
+ params: {
542
+ search: params?.search,
543
+ owned: params?.owned,
544
+ membership: params?.membership,
545
+ per_page: params?.perPage || 20
546
+ }
547
+ });
548
+ return response.data;
549
+ }
550
+ async getProject(projectId) {
551
+ const response = await this.client.get(`/projects/${encodeURIComponent(projectId)}`);
552
+ return response.data;
553
+ }
554
+ };
555
+
556
+ // src/gitlab/api/merge-request.ts
557
+ var GitlabMergeRequestApi = class {
558
+ constructor(client) {
559
+ this.client = client;
560
+ }
561
+ async getMergeRequests(projectId, params) {
562
+ const response = await this.client.get(`/projects/${projectId}/merge_requests`, {
563
+ params: {
564
+ state: params?.state || "opened",
565
+ scope: params?.scope,
566
+ labels: params?.labels,
567
+ per_page: params?.perPage || 20
568
+ }
569
+ });
570
+ return response.data;
571
+ }
572
+ async getMergeRequest(projectId, mrIid) {
573
+ const response = await this.client.get(
574
+ `/projects/${projectId}/merge_requests/${mrIid}`
575
+ );
576
+ return response.data;
577
+ }
578
+ async getMergeRequestChanges(projectId, mrIid) {
579
+ const response = await this.client.get(
580
+ `/projects/${projectId}/merge_requests/${mrIid}/changes`
581
+ );
582
+ return response.data;
583
+ }
584
+ async createMergeRequest(projectId, data) {
585
+ const response = await this.client.post(`/projects/${projectId}/merge_requests`, data);
586
+ return response.data;
587
+ }
588
+ async updateMergeRequest(projectId, mrIid, data) {
589
+ const response = await this.client.put(
590
+ `/projects/${projectId}/merge_requests/${mrIid}`,
591
+ data
592
+ );
593
+ return response.data;
594
+ }
595
+ async mergeMergeRequest(projectId, mrIid, params) {
596
+ const response = await this.client.put(
597
+ `/projects/${projectId}/merge_requests/${mrIid}/merge`,
598
+ params
599
+ );
600
+ return response.data;
601
+ }
602
+ async getMergeRequestNotes(projectId, mrIid) {
603
+ const response = await this.client.get(
604
+ `/projects/${projectId}/merge_requests/${mrIid}/notes`
605
+ );
606
+ return response.data;
607
+ }
608
+ async addMergeRequestNote(projectId, mrIid, body) {
609
+ const response = await this.client.post(
610
+ `/projects/${projectId}/merge_requests/${mrIid}/notes`,
611
+ { body }
612
+ );
613
+ return response.data;
614
+ }
615
+ };
616
+
617
+ // src/gitlab/api/pipeline.ts
618
+ var GitlabPipelineApi = class {
619
+ constructor(client) {
620
+ this.client = client;
621
+ }
622
+ async getPipelines(projectId, params) {
623
+ const response = await this.client.get(`/projects/${projectId}/pipelines`, {
624
+ params: {
625
+ status: params?.status,
626
+ ref: params?.ref,
627
+ per_page: params?.perPage || 20
628
+ }
629
+ });
630
+ return response.data;
631
+ }
632
+ async getPipeline(projectId, pipelineId) {
633
+ const response = await this.client.get(
634
+ `/projects/${projectId}/pipelines/${pipelineId}`
635
+ );
636
+ return response.data;
637
+ }
638
+ async getPipelineJobs(projectId, pipelineId) {
639
+ const response = await this.client.get(
640
+ `/projects/${projectId}/pipelines/${pipelineId}/jobs`
641
+ );
642
+ return response.data;
643
+ }
644
+ async getMergeRequestPipelines(projectId, mrIid) {
645
+ const response = await this.client.get(
646
+ `/projects/${projectId}/merge_requests/${mrIid}/pipelines`
647
+ );
648
+ return response.data;
649
+ }
650
+ };
651
+
652
+ // src/gitlab/api/branch.ts
653
+ var GitlabBranchApi = class {
654
+ constructor(client) {
655
+ this.client = client;
656
+ }
657
+ async getBranches(projectId, params) {
658
+ const response = await this.client.get(`/projects/${projectId}/repository/branches`, {
659
+ params: {
660
+ search: params?.search,
661
+ per_page: params?.perPage || 20
662
+ }
663
+ });
664
+ return response.data;
665
+ }
666
+ async getBranch(projectId, branchName) {
667
+ const response = await this.client.get(
668
+ `/projects/${projectId}/repository/branches/${encodeURIComponent(branchName)}`
669
+ );
670
+ return response.data;
671
+ }
672
+ async createBranch(projectId, branchName, ref) {
673
+ const response = await this.client.post(`/projects/${projectId}/repository/branches`, {
674
+ branch: branchName,
675
+ ref
676
+ });
677
+ return response.data;
678
+ }
679
+ async deleteBranch(projectId, branchName) {
680
+ await this.client.delete(
681
+ `/projects/${projectId}/repository/branches/${encodeURIComponent(branchName)}`
682
+ );
683
+ }
684
+ };
685
+
686
+ // src/gitlab/api/repository.ts
687
+ var GitlabRepositoryApi = class {
688
+ constructor(client) {
689
+ this.client = client;
690
+ }
691
+ async getFile(projectId, filePath, ref) {
692
+ const encodedPath = encodeURIComponent(filePath);
693
+ const response = await this.client.get(
694
+ `/projects/${projectId}/repository/files/${encodedPath}`,
695
+ { params: { ref: ref || "HEAD" } }
696
+ );
697
+ const file = response.data;
698
+ if (file.encoding === "base64") {
699
+ file.content = Buffer.from(file.content, "base64").toString("utf-8");
700
+ }
701
+ return file;
702
+ }
703
+ async getTree(projectId, params) {
704
+ const response = await this.client.get(`/projects/${projectId}/repository/tree`, {
705
+ params: {
706
+ path: params?.path,
707
+ ref: params?.ref,
708
+ recursive: params?.recursive,
709
+ per_page: params?.perPage || 100
710
+ }
711
+ });
712
+ return response.data;
713
+ }
714
+ };
715
+
716
+ // src/gitlab/api/client.ts
717
+ function createGitlabClient(config) {
718
+ const client = createHttpClient({
719
+ ...config,
720
+ baseUrl: `${config.baseUrl}/api/v4`
721
+ });
722
+ client.defaults.headers.common["PRIVATE-TOKEN"] = config.auth.token;
723
+ return client;
724
+ }
350
725
 
351
726
  export {
352
727
  ConfluenceContentApi,
@@ -355,6 +730,20 @@ export {
355
730
  createConfluenceClient,
356
731
  MarkdownToStorageConverter,
357
732
  StorageToMarkdownConverter,
358
- loadConfluenceConfig
733
+ loadConfluenceConfig,
734
+ loadJiraConfig,
735
+ loadGitlabConfig,
736
+ JiraIssueApi,
737
+ JiraSearchApi,
738
+ JiraTransitionApi,
739
+ JiraCommentApi,
740
+ JiraProjectApi,
741
+ createJiraClient,
742
+ GitlabProjectApi,
743
+ GitlabMergeRequestApi,
744
+ GitlabPipelineApi,
745
+ GitlabBranchApi,
746
+ GitlabRepositoryApi,
747
+ createGitlabClient
359
748
  };
360
- //# sourceMappingURL=chunk-K5LQBRHJ.js.map
749
+ //# sourceMappingURL=chunk-2IQ4QMK3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/confluence/api/content.ts","../src/confluence/api/space.ts","../src/confluence/api/search.ts","../src/common/http-client.ts","../src/common/errors.ts","../src/confluence/api/client.ts","../src/confluence/converters/md-to-storage.ts","../src/confluence/converters/storage-to-md.ts","../src/common/config.ts","../src/jira/api/issue.ts","../src/jira/api/search.ts","../src/jira/api/transition.ts","../src/jira/api/comment.ts","../src/jira/api/project.ts","../src/jira/api/client.ts","../src/gitlab/api/project.ts","../src/gitlab/api/merge-request.ts","../src/gitlab/api/pipeline.ts","../src/gitlab/api/branch.ts","../src/gitlab/api/repository.ts","../src/gitlab/api/client.ts"],"sourcesContent":["import { AxiosInstance } from 'axios';\nimport { ConfluencePageResponse, CreatePageParams, UpdatePageParams, ConfluenceLabel, ConfluenceAttachmentResponse } from '../types.js';\n\n\nexport class ConfluenceContentApi {\n constructor(private client: AxiosInstance) { }\n\n async getPage(id: string, expand?: string[]): Promise<ConfluencePageResponse> {\n const expandParam = expand ? expand.join(',') : 'body.storage,version,space,metadata.labels';\n const response = await this.client.get(`/rest/api/content/${id}`, {\n params: { expand: expandParam }\n });\n return response.data;\n }\n\n async getPageByTitle(spaceKey: string, title: string, expand?: string[]): Promise<ConfluencePageResponse | null> {\n const expandParam = expand ? expand.join(',') : 'body.storage,version,space';\n const response = await this.client.get('/rest/api/content', {\n params: {\n spaceKey,\n title,\n expand: expandParam,\n limit: 1\n }\n });\n\n if (response.data.results && response.data.results.length > 0) {\n return response.data.results[0];\n }\n return null;\n }\n\n async createPage(params: CreatePageParams): Promise<ConfluencePageResponse> {\n const data: any = {\n type: 'page',\n title: params.title,\n space: { key: params.spaceKey },\n body: {\n storage: {\n value: params.body,\n representation: 'storage'\n }\n }\n };\n\n if (params.parentId) {\n data.ancestors = [{ id: params.parentId }];\n }\n\n const response = await this.client.post('/rest/api/content', data);\n\n // add labels if provided\n if (params.labels && params.labels.length > 0) {\n await this.addLabels(response.data.id, params.labels);\n // refetch to include labels in response if needed, \n // but simpler to just return the create response.\n // Or we can construct the object.\n }\n\n return response.data;\n }\n\n async updatePage(params: UpdatePageParams): Promise<ConfluencePageResponse> {\n const data = {\n version: { number: params.version + 1 },\n title: params.title,\n type: 'page',\n body: {\n storage: {\n value: params.body,\n representation: 'storage'\n }\n }\n };\n\n const response = await this.client.put(`/rest/api/content/${params.id}`, data);\n return response.data;\n }\n\n async deletePage(id: string): Promise<void> {\n await this.client.delete(`/rest/api/content/${id}`);\n }\n\n async getChildPages(id: string, start = 0, limit = 25): Promise<ConfluencePageResponse[]> {\n const response = await this.client.get(`/rest/api/content/${id}/child/page`, {\n params: { start, limit }\n });\n return response.data.results;\n }\n\n // Label helper inside content api or separate? \n // Let's implement basic label addition here since it's used in create.\n // Actually, label logic is in label.ts, but due to circular dependency or convenience...\n // Let's implement it here privately or import it.\n // Better to keep it separate as per plan, but `this.client` is available here.\n // I'll implement a simple one here or use the separate class later. \n // For now, simple implementation to support createPage.\n private async addLabels(id: string, labels: string[]): Promise<void> {\n const data = labels.map(name => ({ prefix: 'global', name }));\n await this.client.post(`/rest/api/content/${id}/label`, data);\n }\n\n // Attachment 관련 메서드\n async getAttachments(pageId: string, filename?: string): Promise<ConfluenceAttachmentResponse[]> {\n const response = await this.client.get(`/rest/api/content/${pageId}/child/attachment`, {\n params: {\n filename,\n expand: 'version'\n }\n });\n return response.data.results;\n }\n\n async downloadAttachment(downloadUrl: string): Promise<Buffer> {\n const response = await this.client.get(downloadUrl, {\n responseType: 'arraybuffer'\n });\n return Buffer.from(response.data);\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { ConfluenceSpaceResponse } from '../types.js';\n\nexport class ConfluenceSpaceApi {\n constructor(private client: AxiosInstance) { }\n\n async getSpaces(type: string = 'global', start = 0, limit = 25): Promise<ConfluenceSpaceResponse[]> {\n const response = await this.client.get('/rest/api/space', {\n params: { type, start, limit }\n });\n return response.data.results;\n }\n\n async getSpace(spaceKey: string): Promise<ConfluenceSpaceResponse> {\n const response = await this.client.get(`/rest/api/space/${spaceKey}`);\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { ConfluenceSearchResponse } from '../types.js';\n\nexport class ConfluenceSearchApi {\n constructor(private client: AxiosInstance) { }\n\n async searchByCql(cql: string, start = 0, limit = 25, expand?: string[]): Promise<ConfluenceSearchResponse> {\n const expandParam = expand ? expand.join(',') : 'body.storage,version,space,metadata.labels';\n const response = await this.client.get('/rest/api/content/search', {\n params: {\n cql,\n start,\n limit,\n expand: expandParam\n }\n });\n\n return response.data;\n }\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';\nimport { ApiError, AuthError, NotFoundError, ConflictError } from './errors.js';\nimport { logger } from './logger.js';\nimport { ServiceConfig } from './types.js';\n\nexport function createHttpClient(config: ServiceConfig): AxiosInstance {\n const client = axios.create({\n baseURL: config.baseUrl,\n timeout: 30000, // 30초 타임아웃\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n // 요청 인터셉터: 인증 헤더 주입\n client.interceptors.request.use((reqConfig) => {\n // Basic 인증 (사용자명 + 토큰)\n if (config.auth.username && config.auth.token) {\n const token = Buffer.from(`${config.auth.username}:${config.auth.token}`).toString('base64');\n reqConfig.headers.Authorization = `Basic ${token}`;\n }\n // 토큰 기반 인증 (GitLab 등)\n else if (config.auth.token) {\n // GitLab 등은 PRIVATE-TOKEN 헤더를 사용하기도 하나,\n // 여기서는 표준 Authorization Bearer 헤더를 기본으로 사용.\n // 서비스별 특수 헤더는 필요 시 호출자나 별도 로직에서 처리.\n if (!reqConfig.headers.Authorization && !reqConfig.headers['PRIVATE-TOKEN']) {\n reqConfig.headers.Authorization = `Bearer ${config.auth.token}`;\n }\n }\n return reqConfig;\n });\n\n // 응답 인터셉터: 에러 핸들링 및 로깅\n client.interceptors.response.use(\n (response: AxiosResponse) => {\n logger.debug(`[HTTP] ${response.status} ${response.config.method?.toUpperCase()} ${response.config.url}`);\n return response;\n },\n (error: AxiosError) => {\n if (error.response) {\n const status = error.response.status;\n const method = error.config?.method?.toUpperCase();\n const url = error.config?.url;\n const message = (error.response.data as any)?.message || error.message;\n\n logger.error(`[HTTP] ${status} ${method} ${url} - ${message}`);\n\n // 상태 코드별 커스텀 에러 매핑\n if (status === 401 || status === 403) {\n throw new AuthError(`인증 실패: ${message}`);\n }\n if (status === 404) {\n throw new NotFoundError('리소스', url || 'unknown');\n }\n if (status === 409) {\n throw new ConflictError(`충돌 발생: ${message}`);\n }\n\n throw new ApiError(status, message, error.response.data);\n } else if (error.request) {\n logger.error(`[HTTP] No Response: ${error.message}`);\n throw new ApiError(0, `서버로부터 응답이 없습니다: ${error.message}`);\n } else {\n logger.error(`[HTTP] Request Error: ${error.message}`);\n throw new ApiError(0, `요청 설정 중 오류 발생: ${error.message}`);\n }\n }\n );\n\n return client;\n}\n","// TDE Collab 기본 에러 클래스\nexport class TdeCollabError extends Error {\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n// API 요청 실패 에러\nexport class ApiError extends TdeCollabError {\n constructor(\n public statusCode: number,\n message: string,\n public data?: any\n ) {\n super(`API 요청 실패 (${statusCode}): ${message}`);\n }\n}\n\n// 인증 실패 에러\nexport class AuthError extends TdeCollabError {\n constructor(message: string = '인증에 실패했습니다') {\n super(message);\n }\n}\n\n// 리소스 미발견 에러\nexport class NotFoundError extends TdeCollabError {\n constructor(resource: string, id: string) {\n super(`${resource} '${id}'를 찾을 수 없습니다`);\n }\n}\n\n// 리소스 충돌 에러\nexport class ConflictError extends TdeCollabError {\n constructor(message: string) {\n super(message);\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { ConfluenceConfig } from '../../common/types.js';\nimport { createHttpClient } from '../../common/http-client.js';\n\nexport function createConfluenceClient(config: ConfluenceConfig): AxiosInstance {\n // Confluence API base context path handling\n // If user provides 'https://example.atlassian.net/wiki', we should use that.\n // API path usually appends '/rest/api/content' etc.\n\n // Ensure config.baseUrl includes '/wiki' if it's a cloud instance, usually users put it in env.\n // But standard is commonly base domain.\n // We'll trust the config for now, but client consumers should append specific endpoints.\n // Typically, Confluence API is at /wiki/rest/api if cloud, or /rest/api if server.\n // Let's assume baseUrl in config points to the root of the instance, e.g. https://site.atlassian.net/wiki\n\n return createHttpClient(config);\n}\n","import MarkdownIt from 'markdown-it';\n\nexport class MarkdownToStorageConverter {\n private md: MarkdownIt;\n\n constructor() {\n this.md = new MarkdownIt({\n html: true,\n linkify: true,\n breaks: true\n });\n\n // Custom renderer for code blocks to Confluence Code Macro\n this.md.renderer.rules.fence = (tokens, idx) => {\n const token = tokens[idx];\n const code = token.content.trim();\n const lang = token.info.trim();\n\n return `<ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\">\n <ac:parameter ac:name=\"language\">${lang || 'text'}</ac:parameter>\n <ac:plain-text-body><![CDATA[${code}]]></ac:plain-text-body>\n</ac:structured-macro>`;\n };\n }\n\n convert(markdown: string): string {\n return this.md.render(markdown);\n }\n}\n","export class StorageToMarkdownConverter {\n convert(storageHtml: string, imageUrlMap?: Map<string, string>): string {\n // Simple implementation for now.\n // In a real scenario, we would use a proper HTML parser like cheerio or jsdom, \n // or TurndownService.\n // For this phase, let's do basic replacements to demonstrate structure.\n\n let md = storageHtml;\n\n // Remove storage specific wrapper if any (usually not needed if just fragment)\n\n // 이미지 변환 (imageUrlMap이 제공된 경우 로컬 경로로 변환)\n if (imageUrlMap && imageUrlMap.size > 0) {\n imageUrlMap.forEach((localPath, originalTag) => {\n // 파일명에서 alt text 생성\n const filename = localPath.split('/').pop() || 'image';\n const altText = filename.replace(/\\.[^.]+$/, ''); // 확장자 제거\n const markdownImage = `![${altText}](${localPath})`;\n md = md.replace(originalTag, markdownImage);\n });\n }\n\n // 남은 이미지 태그 처리 (다운로드하지 않은 경우)\n // ac:image with attachment\n md = md.replace(\n /<ac:image[^>]*>[\\s\\S]*?<ri:attachment\\s+ri:filename=\"([^\"]+)\"[\\s\\S]*?<\\/ac:image>/g,\n (match, filename) => {\n return `![${filename}](attachment:${filename})`;\n }\n );\n\n // ac:image with URL\n md = md.replace(\n /<ac:image[^>]*>[\\s\\S]*?<ri:url\\s+ri:value=\"([^\"]+)\"[\\s\\S]*?<\\/ac:image>/g,\n (match, url) => {\n const filename = url.split('/').pop() || 'image';\n return `![${filename}](${url})`;\n }\n );\n\n // 일반 img 태그\n md = md.replace(\n /<img\\s+[^>]*\\/?>/g,\n (match) => {\n const srcMatch = /src=\"([^\"]+)\"/.exec(match);\n const altMatch = /alt=\"([^\"]*)\"/.exec(match);\n\n if (srcMatch) {\n const src = srcMatch[1];\n const altText = altMatch ? altMatch[1] : (src.split('/').pop() || 'image');\n return `![${altText}](${src})`;\n }\n return match;\n }\n );\n\n // Code Macro -> Markdown Code Block\n // Structure: <ac:structured-macro ac:name=\"code\">...<ac:parameter ac:name=\"language\">lang</ac:parameter>...<ac:plain-text-body><![CDATA[code]]></ac:plain-text-body></ac:structured-macro>\n\n // Regex based parsing is fragile but sufficient for controlled inputs/MVP.\n // 1. Extract Code Blocks\n md = md.replace(/<ac:structured-macro[^>]*ac:name=\"code\"[^>]*>[\\s\\S]*?<ac:parameter[^>]*ac:name=\"language\">([^<]*)<\\/ac:parameter>[\\s\\S]*?<ac:plain-text-body><!\\[CDATA\\[([\\s\\S]*?)\\]\\]><\\/ac:plain-text-body>[\\s\\S]*?<\\/ac:structured-macro>/g, (match, lang, code) => {\n return `\\`\\`\\`${lang}\\n${code}\\n\\`\\`\\``;\n });\n\n // Fallback for code macro without language param (if possible) - simplifying regex for now.\n\n // Basic HTML to MD mapping\n md = md.replace(/<h1>(.*?)<\\/h1>/g, '# $1\\n');\n md = md.replace(/<h2>(.*?)<\\/h2>/g, '## $1\\n');\n md = md.replace(/<h3>(.*?)<\\/h3>/g, '### $1\\n');\n md = md.replace(/<p>(.*?)<\\/p>/g, '$1\\n\\n');\n md = md.replace(/<strong>(.*?)<\\/strong>/g, '**$1**');\n md = md.replace(/<b>(.*?)<\\/b>/g, '**$1**');\n md = md.replace(/<em>(.*?)<\\/em>/g, '*$1*');\n md = md.replace(/<i>(.*?)<\\/i>/g, '*$1*');\n\n // Lists\n md = md.replace(/<ul>([\\s\\S]*?)<\\/ul>/g, (match, content) => {\n return content.replace(/<li>(.*?)<\\/li>/g, '- $1\\n');\n });\n md = md.replace(/<ol>([\\s\\S]*?)<\\/ol>/g, (match, content) => {\n let i = 1;\n return content.replace(/<li>(.*?)<\\/li>/g, () => `${i++}. $1\\n`);\n });\n\n // Decode HTML entities (basic ones)\n md = md.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/&quot;/g, '\"');\n\n return md.trim();\n }\n}\n","import dotenv from 'dotenv';\nimport { ConfluenceConfig, GitlabConfig, JiraConfig } from './types.js';\nimport { logger } from './logger.js';\n\ndotenv.config();\n\n// 환경변수 조회 및 미설정 시 에러 발생\nfunction getEnvOrThrow(key: string, description: string): string {\n const value = process.env[key];\n if (!value) {\n const errorMsg = `환경변수 '${key}'가 설정되지 않았습니다. (${description})`;\n logger.error(errorMsg);\n throw new Error(errorMsg);\n }\n return value;\n}\n\n// Confluence 설정 로드\nexport function loadConfluenceConfig(): ConfluenceConfig {\n const baseUrl = getEnvOrThrow('CONFLUENCE_BASE_URL', 'Confluence 기본 URL');\n // Username은 선택값 (Bearer Token 사용 시 불필요)\n const username = process.env.CONFLUENCE_USERNAME;\n const token = getEnvOrThrow('CONFLUENCE_API_TOKEN', 'Confluence API 토큰');\n\n return {\n baseUrl,\n auth: {\n username,\n token, // API 토큰은 일반적으로 패스워드 필드에 사용되지만, 여기서는 token으로 저장하여 범용성 확보\n },\n };\n}\n\n// JIRA 설정 로드\nexport function loadJiraConfig(): JiraConfig {\n const baseUrl = getEnvOrThrow('JIRA_BASE_URL', 'JIRA 기본 URL');\n // Username은 선택값 (PAT 사용 시 불필요)\n const username = process.env.JIRA_USERNAME;\n const token = getEnvOrThrow('JIRA_API_TOKEN', 'JIRA API 토큰');\n\n return {\n baseUrl,\n auth: {\n username,\n token,\n },\n };\n}\n\n// GitLab 설정 로드\nexport function loadGitlabConfig(): GitlabConfig {\n const baseUrl = process.env.GITLAB_BASE_URL || 'https://gitlab.com';\n const token = getEnvOrThrow('GITLAB_PRIVATE_TOKEN', 'GitLab Private Token');\n\n return {\n baseUrl,\n auth: {\n token,\n },\n };\n}\n","import { AxiosInstance } from 'axios';\nimport { JiraIssueResponse, CreateIssueParams, UpdateIssueParams } from '../types.js';\n\nexport class JiraIssueApi {\n constructor(private client: AxiosInstance) {}\n\n async getIssue(issueKey: string, fields?: string[], expand?: string[]): Promise<JiraIssueResponse> {\n const params: Record<string, string> = {};\n if (fields && fields.length > 0) {\n params.fields = fields.join(',');\n }\n if (expand && expand.length > 0) {\n params.expand = expand.join(',');\n }\n const response = await this.client.get(`/rest/api/2/issue/${issueKey}`, { params });\n return response.data;\n }\n\n async createIssue(params: CreateIssueParams): Promise<JiraIssueResponse> {\n const fields: Record<string, unknown> = {\n project: { key: params.projectKey },\n summary: params.summary,\n issuetype: { name: params.issueType },\n };\n\n if (params.description) fields.description = params.description;\n if (params.assignee) fields.assignee = { name: params.assignee };\n if (params.priority) fields.priority = { name: params.priority };\n if (params.labels) fields.labels = params.labels;\n if (params.components) {\n fields.components = params.components.map((name) => ({ name }));\n }\n if (params.parentKey) {\n fields.parent = { key: params.parentKey };\n }\n if (params.customFields) {\n Object.assign(fields, params.customFields);\n }\n\n const response = await this.client.post('/rest/api/2/issue', { fields });\n return response.data;\n }\n\n async updateIssue(issueKey: string, params: UpdateIssueParams): Promise<void> {\n const fields: Record<string, unknown> = {};\n\n if (params.summary) fields.summary = params.summary;\n if (params.description !== undefined) fields.description = params.description;\n if (params.assignee !== undefined) fields.assignee = params.assignee ? { name: params.assignee } : null;\n if (params.priority) fields.priority = { name: params.priority };\n if (params.labels) fields.labels = params.labels;\n if (params.components) {\n fields.components = params.components.map((name) => ({ name }));\n }\n if (params.customFields) {\n Object.assign(fields, params.customFields);\n }\n\n await this.client.put(`/rest/api/2/issue/${issueKey}`, { fields });\n }\n\n async deleteIssue(issueKey: string, deleteSubtasks = false): Promise<void> {\n await this.client.delete(`/rest/api/2/issue/${issueKey}`, {\n params: { deleteSubtasks },\n });\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { JiraSearchResponse } from '../types.js';\n\nexport class JiraSearchApi {\n constructor(private client: AxiosInstance) {}\n\n async searchByJql(\n jql: string,\n startAt = 0,\n maxResults = 50,\n fields?: string[],\n ): Promise<JiraSearchResponse> {\n const params: Record<string, unknown> = {\n jql,\n startAt,\n maxResults,\n };\n if (fields && fields.length > 0) {\n params.fields = fields.join(',');\n }\n const response = await this.client.get('/rest/api/2/search', { params });\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { JiraTransition } from '../types.js';\n\nexport class JiraTransitionApi {\n constructor(private client: AxiosInstance) {}\n\n async getTransitions(issueKey: string): Promise<JiraTransition[]> {\n const response = await this.client.get(`/rest/api/2/issue/${issueKey}/transitions`);\n return response.data.transitions;\n }\n\n async doTransition(\n issueKey: string,\n transitionId: string,\n fields?: Record<string, unknown>,\n ): Promise<void> {\n const data: Record<string, unknown> = {\n transition: { id: transitionId },\n };\n if (fields) {\n data.fields = fields;\n }\n await this.client.post(`/rest/api/2/issue/${issueKey}/transitions`, data);\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { JiraComment } from '../types.js';\n\nexport class JiraCommentApi {\n constructor(private client: AxiosInstance) {}\n\n async getComments(\n issueKey: string,\n startAt = 0,\n maxResults = 50,\n ): Promise<{ comments: JiraComment[]; total: number; startAt: number; maxResults: number }> {\n const response = await this.client.get(`/rest/api/2/issue/${issueKey}/comment`, {\n params: { startAt, maxResults },\n });\n return response.data;\n }\n\n async addComment(issueKey: string, body: string): Promise<JiraComment> {\n const response = await this.client.post(`/rest/api/2/issue/${issueKey}/comment`, { body });\n return response.data;\n }\n\n async updateComment(issueKey: string, commentId: string, body: string): Promise<JiraComment> {\n const response = await this.client.put(\n `/rest/api/2/issue/${issueKey}/comment/${commentId}`,\n { body },\n );\n return response.data;\n }\n\n async deleteComment(issueKey: string, commentId: string): Promise<void> {\n await this.client.delete(`/rest/api/2/issue/${issueKey}/comment/${commentId}`);\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { JiraProject, JiraBoard, JiraSprint } from '../types.js';\n\nexport class JiraProjectApi {\n constructor(private client: AxiosInstance) {}\n\n async getProjects(): Promise<JiraProject[]> {\n const response = await this.client.get('/rest/api/2/project');\n return response.data;\n }\n\n async getProject(projectKey: string): Promise<JiraProject> {\n const response = await this.client.get(`/rest/api/2/project/${projectKey}`);\n return response.data;\n }\n\n async getBoards(\n projectKeyOrId?: string,\n type?: string,\n ): Promise<{ values: JiraBoard[]; total: number }> {\n const params: Record<string, string> = {};\n if (projectKeyOrId) params.projectKeyOrId = projectKeyOrId;\n if (type) params.type = type;\n const response = await this.client.get('/rest/agile/1.0/board', { params });\n return response.data;\n }\n\n async getSprints(\n boardId: number,\n state?: string,\n ): Promise<{ values: JiraSprint[]; total: number }> {\n const params: Record<string, string> = {};\n if (state) params.state = state;\n const response = await this.client.get(`/rest/agile/1.0/board/${boardId}/sprint`, {\n params,\n });\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { JiraConfig } from '../../common/types.js';\nimport { createHttpClient } from '../../common/http-client.js';\n\nexport function createJiraClient(config: JiraConfig): AxiosInstance {\n return createHttpClient(config);\n}\n","import { AxiosInstance } from 'axios';\nimport { GitlabProject } from '../types.js';\n\nexport class GitlabProjectApi {\n constructor(private client: AxiosInstance) {}\n\n async getProjects(params?: {\n search?: string;\n owned?: boolean;\n membership?: boolean;\n perPage?: number;\n }): Promise<GitlabProject[]> {\n const response = await this.client.get('/projects', {\n params: {\n search: params?.search,\n owned: params?.owned,\n membership: params?.membership,\n per_page: params?.perPage || 20,\n },\n });\n return response.data;\n }\n\n async getProject(projectId: number | string): Promise<GitlabProject> {\n const response = await this.client.get(`/projects/${encodeURIComponent(projectId)}`);\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { GitlabMergeRequest, GitlabNote } from '../types.js';\n\nexport class GitlabMergeRequestApi {\n constructor(private client: AxiosInstance) {}\n\n async getMergeRequests(\n projectId: number,\n params?: { state?: string; scope?: string; labels?: string; perPage?: number },\n ): Promise<GitlabMergeRequest[]> {\n const response = await this.client.get(`/projects/${projectId}/merge_requests`, {\n params: {\n state: params?.state || 'opened',\n scope: params?.scope,\n labels: params?.labels,\n per_page: params?.perPage || 20,\n },\n });\n return response.data;\n }\n\n async getMergeRequest(projectId: number, mrIid: number): Promise<GitlabMergeRequest> {\n const response = await this.client.get(\n `/projects/${projectId}/merge_requests/${mrIid}`,\n );\n return response.data;\n }\n\n async getMergeRequestChanges(projectId: number, mrIid: number): Promise<GitlabMergeRequest> {\n const response = await this.client.get(\n `/projects/${projectId}/merge_requests/${mrIid}/changes`,\n );\n return response.data;\n }\n\n async createMergeRequest(\n projectId: number,\n data: {\n source_branch: string;\n target_branch: string;\n title: string;\n description?: string;\n assignee_id?: number;\n reviewer_ids?: number[];\n labels?: string;\n },\n ): Promise<GitlabMergeRequest> {\n const response = await this.client.post(`/projects/${projectId}/merge_requests`, data);\n return response.data;\n }\n\n async updateMergeRequest(\n projectId: number,\n mrIid: number,\n data: {\n title?: string;\n description?: string;\n assignee_id?: number;\n reviewer_ids?: number[];\n labels?: string;\n state_event?: 'close' | 'reopen';\n },\n ): Promise<GitlabMergeRequest> {\n const response = await this.client.put(\n `/projects/${projectId}/merge_requests/${mrIid}`,\n data,\n );\n return response.data;\n }\n\n async mergeMergeRequest(\n projectId: number,\n mrIid: number,\n params?: {\n merge_commit_message?: string;\n squash?: boolean;\n should_remove_source_branch?: boolean;\n },\n ): Promise<GitlabMergeRequest> {\n const response = await this.client.put(\n `/projects/${projectId}/merge_requests/${mrIid}/merge`,\n params,\n );\n return response.data;\n }\n\n async getMergeRequestNotes(projectId: number, mrIid: number): Promise<GitlabNote[]> {\n const response = await this.client.get(\n `/projects/${projectId}/merge_requests/${mrIid}/notes`,\n );\n return response.data;\n }\n\n async addMergeRequestNote(\n projectId: number,\n mrIid: number,\n body: string,\n ): Promise<GitlabNote> {\n const response = await this.client.post(\n `/projects/${projectId}/merge_requests/${mrIid}/notes`,\n { body },\n );\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { GitlabPipeline, GitlabJob } from '../types.js';\n\nexport class GitlabPipelineApi {\n constructor(private client: AxiosInstance) {}\n\n async getPipelines(\n projectId: number,\n params?: { status?: string; ref?: string; perPage?: number },\n ): Promise<GitlabPipeline[]> {\n const response = await this.client.get(`/projects/${projectId}/pipelines`, {\n params: {\n status: params?.status,\n ref: params?.ref,\n per_page: params?.perPage || 20,\n },\n });\n return response.data;\n }\n\n async getPipeline(projectId: number, pipelineId: number): Promise<GitlabPipeline> {\n const response = await this.client.get(\n `/projects/${projectId}/pipelines/${pipelineId}`,\n );\n return response.data;\n }\n\n async getPipelineJobs(projectId: number, pipelineId: number): Promise<GitlabJob[]> {\n const response = await this.client.get(\n `/projects/${projectId}/pipelines/${pipelineId}/jobs`,\n );\n return response.data;\n }\n\n async getMergeRequestPipelines(\n projectId: number,\n mrIid: number,\n ): Promise<GitlabPipeline[]> {\n const response = await this.client.get(\n `/projects/${projectId}/merge_requests/${mrIid}/pipelines`,\n );\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { GitlabBranch } from '../types.js';\n\nexport class GitlabBranchApi {\n constructor(private client: AxiosInstance) {}\n\n async getBranches(\n projectId: number,\n params?: { search?: string; perPage?: number },\n ): Promise<GitlabBranch[]> {\n const response = await this.client.get(`/projects/${projectId}/repository/branches`, {\n params: {\n search: params?.search,\n per_page: params?.perPage || 20,\n },\n });\n return response.data;\n }\n\n async getBranch(projectId: number, branchName: string): Promise<GitlabBranch> {\n const response = await this.client.get(\n `/projects/${projectId}/repository/branches/${encodeURIComponent(branchName)}`,\n );\n return response.data;\n }\n\n async createBranch(\n projectId: number,\n branchName: string,\n ref: string,\n ): Promise<GitlabBranch> {\n const response = await this.client.post(`/projects/${projectId}/repository/branches`, {\n branch: branchName,\n ref,\n });\n return response.data;\n }\n\n async deleteBranch(projectId: number, branchName: string): Promise<void> {\n await this.client.delete(\n `/projects/${projectId}/repository/branches/${encodeURIComponent(branchName)}`,\n );\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { GitlabRepositoryFile, GitlabTreeEntry } from '../types.js';\n\nexport class GitlabRepositoryApi {\n constructor(private client: AxiosInstance) {}\n\n async getFile(\n projectId: number,\n filePath: string,\n ref?: string,\n ): Promise<GitlabRepositoryFile> {\n const encodedPath = encodeURIComponent(filePath);\n const response = await this.client.get(\n `/projects/${projectId}/repository/files/${encodedPath}`,\n { params: { ref: ref || 'HEAD' } },\n );\n const file: GitlabRepositoryFile = response.data;\n // Base64 디코딩\n if (file.encoding === 'base64') {\n file.content = Buffer.from(file.content, 'base64').toString('utf-8');\n }\n return file;\n }\n\n async getTree(\n projectId: number,\n params?: { path?: string; ref?: string; recursive?: boolean; perPage?: number },\n ): Promise<GitlabTreeEntry[]> {\n const response = await this.client.get(`/projects/${projectId}/repository/tree`, {\n params: {\n path: params?.path,\n ref: params?.ref,\n recursive: params?.recursive,\n per_page: params?.perPage || 100,\n },\n });\n return response.data;\n }\n}\n","import { AxiosInstance } from 'axios';\nimport { GitlabConfig } from '../../common/types.js';\nimport { createHttpClient } from '../../common/http-client.js';\n\nexport function createGitlabClient(config: GitlabConfig): AxiosInstance {\n const client = createHttpClient({\n ...config,\n baseUrl: `${config.baseUrl}/api/v4`,\n });\n\n // GitLab Self-hosted는 PRIVATE-TOKEN 헤더 사용\n client.defaults.headers.common['PRIVATE-TOKEN'] = config.auth.token!;\n\n return client;\n}\n"],"mappings":"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","names":[]}