gongdata 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/error.ts","../src/core/parser.ts","../src/core/http.ts","../src/core/response.ts","../src/services/base.ts","../src/services/qualification/transformers.ts","../src/services/qualification/response.ts","../src/services/qualification/service.ts","../src/services/qualification/constants.ts","../src/client.ts"],"names":["XMLParser"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * 공공데이터포털 API 응답 코드\n * @see https://www.data.go.kr\n */\nexport const ResultCode = {\n /** 정상 */\n SUCCESS: '00',\n\n // === 공공데이터포털 공통 에러 ===\n /** 어플리케이션 에러 */\n APPLICATION_ERROR: '1',\n /** 잘못된 요청 파라미터 */\n INVALID_REQUEST_PARAMETER: '10',\n /** 해당 오픈API 서비스 없음 또는 폐기 */\n NO_OPENAPI_SERVICE: '12',\n /** 서비스 접근 거부 */\n SERVICE_ACCESS_DENIED: '20',\n /** 서비스 요청 제한 횟수 초과 */\n REQUEST_LIMIT_EXCEEDED: '22',\n /** 등록되지 않은 서비스키 */\n UNREGISTERED_SERVICE_KEY: '30',\n /** 서비스키 기한 만료 */\n EXPIRED_SERVICE_KEY: '31',\n /** 등록되지 않은 IP */\n UNREGISTERED_IP: '32',\n /** 기타 에러 */\n UNKNOWN_ERROR: '99',\n\n // === SDK 내부 에러 ===\n /** HTTP 에러 */\n HTTP_ERROR: 'HTTP_ERROR',\n /** 서비스 타임아웃 */\n SERVICE_TIMEOUT: 'SERVICE_TIMEOUT',\n\n // === HRDK(한국산업인력공단) 자체 에러 ===\n /** 게이트웨이 인증 오류 */\n GATEWAY_AUTH_ERROR: '900',\n /** 필수 파라미터 누락 */\n MISSING_REQUIRED_PARAMETER: '910',\n /** 잘못된 dataFormat (json/xml만 가능) */\n INVALID_DATA_FORMAT: '920',\n /** 최대 목록 수 초과 */\n MAX_ROWS_EXCEEDED: '930',\n /** 잘못된 토큰 파라미터 */\n INVALID_TOKEN: '940',\n /** 토큰 유효기한 만료 (1시간) */\n TOKEN_EXPIRED: '941',\n /** 파일을 찾을 수 없음 */\n FILE_NOT_FOUND: '950',\n /** HRDK 서버 에러 */\n HRDK_SERVER_ERROR: '990',\n} as const;\n\nexport type ResultCodeType = (typeof ResultCode)[keyof typeof ResultCode];\n\nconst RESULT_MESSAGES: Readonly<Record<ResultCodeType, string>> = {\n [ResultCode.SUCCESS]: '정상',\n [ResultCode.APPLICATION_ERROR]: '어플리케이션 에러',\n [ResultCode.INVALID_REQUEST_PARAMETER]: '잘못된 요청 파라미터',\n [ResultCode.NO_OPENAPI_SERVICE]: '해당 오픈API 서비스 없음',\n [ResultCode.SERVICE_ACCESS_DENIED]: '서비스 접근 거부',\n [ResultCode.REQUEST_LIMIT_EXCEEDED]: '서비스 요청 제한 횟수 초과',\n [ResultCode.UNREGISTERED_SERVICE_KEY]: '등록되지 않은 서비스키',\n [ResultCode.EXPIRED_SERVICE_KEY]: '서비스키 기한 만료',\n [ResultCode.UNREGISTERED_IP]: '등록되지 않은 IP',\n [ResultCode.UNKNOWN_ERROR]: '기타 에러',\n [ResultCode.HTTP_ERROR]: 'HTTP 에러',\n [ResultCode.SERVICE_TIMEOUT]: '서비스 타임아웃',\n [ResultCode.GATEWAY_AUTH_ERROR]: '게이트웨이 인증 오류',\n [ResultCode.MISSING_REQUIRED_PARAMETER]: '필수 파라미터 누락',\n [ResultCode.INVALID_DATA_FORMAT]: '잘못된 dataFormat (json/xml만 가능)',\n [ResultCode.MAX_ROWS_EXCEEDED]: '최대 목록 수 초과',\n [ResultCode.INVALID_TOKEN]: '잘못된 토큰 파라미터',\n [ResultCode.TOKEN_EXPIRED]: '토큰 유효기한 만료',\n [ResultCode.FILE_NOT_FOUND]: '파일을 찾을 수 없음',\n [ResultCode.HRDK_SERVER_ERROR]: 'HRDK 서버 에러',\n};\n\nexport class GongdataError extends Error {\n readonly code: ResultCodeType | string;\n readonly originalResponse?: unknown;\n\n constructor(code: ResultCodeType | string, message?: string, originalResponse?: unknown) {\n const errorMessage =\n message ?? RESULT_MESSAGES[code as ResultCodeType] ?? `Unknown error: ${code}`;\n super(errorMessage);\n this.name = 'GongdataError';\n this.code = code;\n this.originalResponse = originalResponse;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, GongdataError);\n }\n }\n\n static isGongdataError(error: unknown): error is GongdataError {\n return error instanceof GongdataError;\n }\n\n static fromResponse(\n header: { readonly resultCode: string; readonly resultMsg: string },\n originalResponse?: unknown\n ): GongdataError {\n return new GongdataError(header.resultCode, header.resultMsg, originalResponse);\n }\n}\n","import { XMLParser } from 'fast-xml-parser';\nimport type { DataGoKrResponse, DataGoKrXmlResponse, XmlItemsWrapper } from './types.js';\nimport { ResultCode, GongdataError } from './error.js';\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: '@_',\n textNodeName: '#text',\n parseTagValue: false, // '00' 같은 값을 숫자로 변환하지 않음\n trimValues: true,\n});\n\n/**\n * XML 문자열을 JSON으로 파싱\n */\nexport function parseXml<T>(xml: string): T {\n return xmlParser.parse(xml) as T;\n}\n\n/**\n * API 응답이 JSON인지 확인\n */\nexport function isJsonResponse(contentType: string | null): boolean {\n return contentType?.includes('application/json') ?? false;\n}\n\n/**\n * API 응답이 XML인지 확인\n */\nexport function isXmlResponse(contentType: string | null): boolean {\n return contentType?.includes('application/xml') ?? contentType?.includes('text/xml') ?? false;\n}\n\n/**\n * 응답 헤더 검증 및 에러 처리\n */\nexport function validateResponse(header: { resultCode: string; resultMsg: string }): void {\n const { resultCode, resultMsg } = header;\n\n if (resultCode !== ResultCode.SUCCESS) {\n throw GongdataError.fromResponse({ resultCode, resultMsg });\n }\n}\n\n/**\n * XML items.item을 배열로 정규화\n */\nexport function normalizeXmlItems<T>(items: XmlItemsWrapper<T> | ''): readonly T[] {\n if (items === '' || items === null || items === undefined) {\n return [];\n }\n\n const { item } = items;\n\n if (item === null || item === undefined) {\n return [];\n }\n\n if (Array.isArray(item)) {\n return item as readonly T[];\n }\n\n return [item as T];\n}\n\n/**\n * JSON items를 배열로 정규화\n */\nexport function normalizeJsonItems<T>(items: readonly T[] | ''): readonly T[] {\n if (items === '' || items === null || items === undefined) {\n return [];\n }\n\n if (Array.isArray(items)) {\n return items;\n }\n\n return [];\n}\n\n/**\n * API 응답을 파싱하고 정규화된 데이터 반환\n */\nexport function parseResponse<T>(\n data: unknown,\n contentType: string | null\n): {\n header: { resultCode: string; resultMsg: string };\n body: { items: readonly T[]; numOfRows: number; pageNo: number; totalCount: number };\n} {\n if (typeof data === 'string') {\n if (isXmlResponse(contentType)) {\n // XML 응답 처리\n const parsed = parseXml<DataGoKrXmlResponse<T>>(data);\n validateResponse(parsed.response.header);\n\n return {\n header: parsed.response.header,\n body: {\n items: normalizeXmlItems(parsed.response.body.items),\n numOfRows: Number(parsed.response.body.numOfRows),\n pageNo: Number(parsed.response.body.pageNo),\n totalCount: Number(parsed.response.body.totalCount),\n },\n };\n } else {\n // JSON 문자열 처리\n const parsed = JSON.parse(data) as DataGoKrResponse<T>;\n validateResponse(parsed.header);\n\n return {\n header: parsed.header,\n body: {\n items: normalizeJsonItems(parsed.body.items),\n numOfRows: parsed.body.numOfRows,\n pageNo: parsed.body.pageNo,\n totalCount: parsed.body.totalCount,\n },\n };\n }\n } else {\n // 이미 파싱된 JSON 객체\n const parsed = data as DataGoKrResponse<T>;\n validateResponse(parsed.header);\n\n return {\n header: parsed.header,\n body: {\n items: normalizeJsonItems(parsed.body.items),\n numOfRows: parsed.body.numOfRows,\n pageNo: parsed.body.pageNo,\n totalCount: parsed.body.totalCount,\n },\n };\n }\n}\n","import type { GongdataConfig, RequestOptions, RawApiResult } from './types.js';\nimport { parseResponse } from './parser.js';\nimport { GongdataError, ResultCode } from './error.js';\n\nconst DEFAULT_TIMEOUT = 10000;\nconst DEFAULT_NUM_OF_ROWS = 100;\n\nexport class HttpClient {\n private readonly serviceKey: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly retryDelay: number;\n\n constructor(config: GongdataConfig) {\n this.serviceKey = config.serviceKey;\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT;\n this.maxRetries = config.retry?.maxRetries ?? 3;\n this.retryDelay = config.retry?.delay ?? 1000;\n }\n\n /**\n * 서비스 키 반환 (일부 API에서 직접 URL 구성 시 필요)\n */\n getServiceKey(): string {\n return this.serviceKey;\n }\n\n /**\n * URL 파라미터 빌드\n */\n private buildParams(params: Record<string, string | number | undefined>): URLSearchParams {\n const searchParams = new URLSearchParams();\n searchParams.set('serviceKey', this.serviceKey);\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, String(value));\n }\n }\n\n return searchParams;\n }\n\n /**\n * 단일 요청 실행 (재시도 포함)\n */\n async request<T>(baseUrl: string, options: RequestOptions): Promise<RawApiResult<T>> {\n const { path, params = {}, pageNo = 1, numOfRows = DEFAULT_NUM_OF_ROWS } = options;\n const url = `${baseUrl}${path}`;\n const searchParams = this.buildParams({\n ...params,\n pageNo,\n numOfRows,\n dataFormat: 'json', // 필수 파라미터\n });\n\n const fullUrl = `${url}?${searchParams.toString()}`;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(fullUrl, {\n method: 'GET',\n signal: controller.signal,\n headers: {\n Accept: 'application/json, application/xml',\n },\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new GongdataError(\n ResultCode.HTTP_ERROR,\n `HTTP ${response.status}: ${response.statusText}`\n );\n }\n\n const contentType = response.headers.get('content-type');\n const text = await response.text();\n const parsed = parseResponse<T>(text, contentType);\n\n const { body } = parsed;\n\n return {\n data: body.items,\n pagination: {\n pageNo: body.pageNo,\n numOfRows: body.numOfRows,\n totalCount: body.totalCount,\n },\n };\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // AbortError는 타임아웃\n if (lastError.name === 'AbortError') {\n lastError = new GongdataError(ResultCode.SERVICE_TIMEOUT, 'Request timeout');\n }\n\n // 재시도 불가능한 에러\n if (GongdataError.isGongdataError(lastError)) {\n const nonRetryableCodes = [\n ResultCode.UNREGISTERED_SERVICE_KEY,\n ResultCode.EXPIRED_SERVICE_KEY,\n ResultCode.SERVICE_ACCESS_DENIED,\n ResultCode.INVALID_REQUEST_PARAMETER,\n ResultCode.UNREGISTERED_IP,\n ResultCode.MISSING_REQUIRED_PARAMETER,\n ResultCode.INVALID_DATA_FORMAT,\n ];\n\n if (nonRetryableCodes.includes(lastError.code as (typeof nonRetryableCodes)[number])) {\n throw lastError;\n }\n }\n\n // 마지막 시도가 아니면 대기 후 재시도\n if (attempt < this.maxRetries) {\n await this.sleep(this.retryDelay * (attempt + 1));\n }\n }\n }\n\n throw lastError ?? new GongdataError(ResultCode.APPLICATION_ERROR, 'Unknown error');\n }\n\n /**\n * 전체 페이지 데이터 수집\n */\n async requestAll<T>(\n baseUrl: string,\n options: RequestOptions,\n numOfRows: number = DEFAULT_NUM_OF_ROWS\n ): Promise<readonly T[]> {\n const allItems: T[] = [];\n let pageNo = 1;\n let totalCount = 0;\n\n do {\n const result = await this.request<T>(baseUrl, {\n ...options,\n pageNo,\n numOfRows,\n });\n\n allItems.push(...result.data);\n totalCount = result.pagination.totalCount;\n pageNo++;\n } while (allItems.length < totalCount);\n\n return allItems;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import type { PaginationInfo } from './types.js';\n\n/**\n * API 응답 기본 추상 클래스\n * @template TRaw - 공공 API 원본 타입\n * @template T - SDK 정규화 타입\n */\nexport abstract class DataResponse<TRaw, T> {\n /**\n * 정규화된 데이터 (SDK 보장 인터페이스)\n * @description 버전 업그레이드 시에도 인터페이스 호환성 보장\n */\n abstract getData(): readonly T[];\n\n /**\n * 원본 데이터 (공공 API 응답 그대로)\n * @description 공공 API 스펙 변경 시 같이 변경될 수 있음\n */\n abstract getRawData(): readonly TRaw[];\n\n /** 정규화된 데이터 (getter) */\n get data(): readonly T[] {\n return this.getData();\n }\n\n /** 원본 데이터 (getter) */\n get rawData(): readonly TRaw[] {\n return this.getRawData();\n }\n\n /**\n * 데이터가 비어있는지 확인\n */\n isEmpty(): boolean {\n return this.data.length === 0;\n }\n\n /**\n * 데이터 개수\n */\n count(): number {\n return this.data.length;\n }\n}\n\n/**\n * 페이지네이션이 있는 API 응답 추상 클래스\n */\nexport abstract class PaginatedResponse<TRaw, T> extends DataResponse<TRaw, T> {\n /**\n * 페이지네이션 정보\n */\n abstract getPagination(): PaginationInfo;\n\n /** 페이지네이션 정보 (getter) */\n get pagination(): PaginationInfo {\n return this.getPagination();\n }\n\n /** 전체 데이터 개수 */\n get totalCount(): number {\n return this.pagination.totalCount;\n }\n\n /** 현재 페이지 번호 */\n get pageNo(): number {\n return this.pagination.pageNo;\n }\n\n /** 페이지 당 항목 수 */\n get numOfRows(): number {\n return this.pagination.numOfRows;\n }\n\n /**\n * 다음 페이지 존재 여부\n */\n hasNextPage(): boolean {\n const { pageNo, numOfRows, totalCount } = this.pagination;\n return pageNo * numOfRows < totalCount;\n }\n}\n","import type { HttpClient, RequestOptions, RawApiResult } from '../core/index.js';\n\n/**\n * 모든 서비스의 기본 추상 클래스\n * 새 서비스 추가 시 이 클래스를 상속받아 구현\n */\nexport abstract class BaseService {\n protected readonly http: HttpClient;\n\n /** 서비스 기본 URL */\n protected abstract readonly baseUrl: string;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n /**\n * 단일 페이지 요청\n */\n protected async request<T>(options: RequestOptions): Promise<RawApiResult<T>> {\n return this.http.request<T>(this.baseUrl, options);\n }\n\n /**\n * 전체 페이지 자동 수집\n */\n protected async requestAll<T>(\n options: RequestOptions,\n numOfRows?: number\n ): Promise<readonly T[]> {\n return this.http.requestAll<T>(this.baseUrl, options, numOfRows);\n }\n}\n","import type { RawExamSchedule, ExamSchedule, RawSubject, Subject, ExamPeriod } from './types.js';\n\n/**\n * YYYYMMDD → YYYY-MM-DD 변환\n */\nfunction formatDate(yyyymmdd: string): string {\n if (!yyyymmdd || yyyymmdd.length !== 8) return yyyymmdd;\n return `${yyyymmdd.slice(0, 4)}-${yyyymmdd.slice(4, 6)}-${yyyymmdd.slice(6, 8)}`;\n}\n\n/**\n * Raw 시험일정 → 정규화된 시험일정\n */\nexport function transformExamSchedule(raw: RawExamSchedule): ExamSchedule {\n const writtenExam: ExamPeriod = {\n registrationStart: formatDate(raw.docRegStartDt),\n registrationEnd: formatDate(raw.docRegEndDt),\n examStart: formatDate(raw.docExamStartDt),\n examEnd: formatDate(raw.docExamEndDt),\n resultDate: formatDate(raw.docPassDt),\n };\n\n const practicalExam: ExamPeriod = {\n registrationStart: formatDate(raw.pracRegStartDt),\n registrationEnd: formatDate(raw.pracRegEndDt),\n examStart: formatDate(raw.pracExamStartDt),\n examEnd: formatDate(raw.pracExamEndDt),\n resultDate: formatDate(raw.pracPassDt),\n };\n\n return {\n year: Number(raw.implYy),\n round: raw.implSeq,\n category: {\n code: raw.qualgbCd,\n name: raw.qualgbNm,\n },\n description: raw.description,\n writtenExam,\n practicalExam,\n };\n}\n\n/**\n * Raw 시험일정 배열 → 정규화된 시험일정 배열\n */\nexport function transformExamSchedules(\n rawList: readonly RawExamSchedule[]\n): readonly ExamSchedule[] {\n return rawList.map(transformExamSchedule);\n}\n\n/**\n * Raw 종목 → 정규화된 종목\n */\nexport function transformSubject(raw: RawSubject): Subject {\n return {\n code: raw.jmcd,\n name: raw.jmfldnm,\n category: {\n code: raw.qualgbcd,\n name: raw.qualgbnm,\n },\n series: {\n code: raw.seriescd,\n name: raw.seriesnm,\n },\n majorJobField: {\n code: raw.obligfldcd,\n name: raw.obligfldnm,\n },\n minorJobField: {\n code: raw.mdobligfldcd,\n name: raw.mdobligfldnm,\n },\n };\n}\n\n/**\n * Raw 종목 배열 → 정규화된 종목 배열\n */\nexport function transformSubjects(rawList: readonly RawSubject[]): readonly Subject[] {\n return rawList.map(transformSubject);\n}\n","import { DataResponse, PaginatedResponse } from '../../core/response.js';\nimport type { PaginationInfo } from '../../core/types.js';\nimport type { RawExamSchedule, ExamSchedule, RawSubject, Subject } from './types.js';\n\n/**\n * 시험일정 조회 결과\n */\nexport class ScheduleResponse extends PaginatedResponse<RawExamSchedule, ExamSchedule> {\n private readonly _raw: readonly RawExamSchedule[];\n private readonly _data: readonly ExamSchedule[];\n private readonly _pagination: PaginationInfo;\n\n constructor(\n raw: readonly RawExamSchedule[],\n data: readonly ExamSchedule[],\n pagination: PaginationInfo\n ) {\n super();\n this._raw = raw;\n this._data = data;\n this._pagination = pagination;\n }\n\n getData(): readonly ExamSchedule[] {\n return this._data;\n }\n\n getRawData(): readonly RawExamSchedule[] {\n return this._raw;\n }\n\n getPagination(): PaginationInfo {\n return this._pagination;\n }\n}\n\n/**\n * 시험일정 전체 조회 결과 (페이지네이션 없음)\n */\nexport class AllSchedulesResponse extends DataResponse<RawExamSchedule, ExamSchedule> {\n private readonly _raw: readonly RawExamSchedule[];\n private readonly _data: readonly ExamSchedule[];\n\n constructor(raw: readonly RawExamSchedule[], data: readonly ExamSchedule[]) {\n super();\n this._raw = raw;\n this._data = data;\n }\n\n getData(): readonly ExamSchedule[] {\n return this._data;\n }\n\n getRawData(): readonly RawExamSchedule[] {\n return this._raw;\n }\n}\n\n/**\n * 종목 목록 조회 결과\n */\nexport class SubjectResponse extends DataResponse<RawSubject, Subject> {\n private readonly _raw: readonly RawSubject[];\n private readonly _data: readonly Subject[];\n\n constructor(raw: readonly RawSubject[], data: readonly Subject[]) {\n super();\n this._raw = raw;\n this._data = data;\n }\n\n getData(): readonly Subject[] {\n return this._data;\n }\n\n getRawData(): readonly RawSubject[] {\n return this._raw;\n }\n\n /**\n * 종목코드로 찾기\n */\n findByCode(code: string): Subject | undefined {\n return this._data.find((s) => s.code === code);\n }\n\n /**\n * 종목명으로 찾기\n */\n findByName(name: string): Subject | undefined {\n return this._data.find((s) => s.name === name);\n }\n\n /**\n * 자격구분으로 필터링\n */\n filterByCategory(categoryCode: string): readonly Subject[] {\n return this._data.filter((s) => s.category.code === categoryCode);\n }\n}\n","import { BaseService } from '../base.js';\nimport { parseXml, validateResponse, normalizeXmlItems } from '../../core/parser.js';\nimport type { RawExamSchedule, RawSubject, GetSchedulesParams } from './types.js';\nimport { transformExamSchedules, transformSubjects } from './transformers.js';\nimport { ScheduleResponse, AllSchedulesResponse, SubjectResponse } from './response.js';\n\n/** 시험일정 API 베이스 URL */\nconst SCHEDULE_API_BASE_URL = 'http://apis.data.go.kr/B490007/qualExamSchd';\n\n/** 종목 목록 API 베이스 URL */\nconst SUBJECT_API_BASE_URL =\n 'http://openapi.q-net.or.kr/api/service/rest/InquiryListNationalQualifcationSVC';\n\n/** 종목 목록 API XML 응답 구조 */\ninterface SubjectXmlResponse {\n readonly response: {\n readonly header: { readonly resultCode: string; readonly resultMsg: string };\n readonly body: {\n readonly items: { readonly item: RawSubject | readonly RawSubject[] } | '';\n };\n };\n}\n\n/**\n * 자격증 시험일정 서비스\n * @see https://www.data.go.kr/data/15074408/openapi.do\n */\nexport class QualificationService extends BaseService {\n protected readonly baseUrl = SCHEDULE_API_BASE_URL;\n\n /**\n * 시험일정 목록 조회 (단일 페이지)\n *\n * @example\n * ```typescript\n * const result = await client.qualification.getSchedules({ year: 2026 });\n *\n * // 정규화된 데이터 (SDK 보장)\n * result.getData()[0].writtenExam.registrationStart // '2026-01-24'\n *\n * // 원본 데이터 (공공 API 그대로)\n * result.getRawData()[0].docRegStartDt // '20260124'\n * ```\n */\n async getSchedules(\n params: GetSchedulesParams,\n options?: { readonly pageNo?: number; readonly numOfRows?: number }\n ): Promise<ScheduleResponse> {\n const result = await this.request<RawExamSchedule>({\n path: '/getQualExamSchdList',\n params: {\n implYy: params.year,\n qualgbCd: params.category,\n jmCd: params.jmCode,\n },\n pageNo: options?.pageNo,\n numOfRows: options?.numOfRows,\n });\n\n return new ScheduleResponse(\n result.data,\n transformExamSchedules(result.data),\n result.pagination\n );\n }\n\n /**\n * 시험일정 전체 조회 (모든 페이지 자동 수집)\n */\n async getAllSchedules(params: GetSchedulesParams): Promise<AllSchedulesResponse> {\n const raw = await this.requestAll<RawExamSchedule>({\n path: '/getQualExamSchdList',\n params: {\n implYy: params.year,\n qualgbCd: params.category,\n jmCd: params.jmCode,\n },\n });\n\n return new AllSchedulesResponse(raw, transformExamSchedules(raw));\n }\n\n /**\n * 국가자격 종목 전체 목록 조회\n *\n * @example\n * ```typescript\n * const result = await client.qualification.getSubjects();\n *\n * // 정규화된 데이터\n * result.getData()[0].name // '정보처리기사'\n *\n * // 편의 메서드\n * result.findByName('정보처리기사') // Subject\n * result.filterByCategory('T') // 국가기술자격만\n * ```\n */\n async getSubjects(): Promise<SubjectResponse> {\n const url = `${SUBJECT_API_BASE_URL}/getList?serviceKey=${this.http.getServiceKey()}`;\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { Accept: 'application/xml' },\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const xml = await response.text();\n const parsed = parseXml<SubjectXmlResponse>(xml);\n\n validateResponse(parsed.response.header);\n\n const raw = normalizeXmlItems(parsed.response.body.items) as readonly RawSubject[];\n\n return new SubjectResponse(raw, transformSubjects(raw));\n }\n}\n","/**\n * 자격구분 코드\n * @see https://www.data.go.kr/data/15074408/openapi.do\n */\nexport const QualificationCategory = {\n /** 국가기술자격 */\n NATIONAL_TECHNICAL: 'T',\n /** 과정평가형자격 */\n COURSE_EVALUATION: 'C',\n /** 일학습병행자격 */\n WORK_LEARNING: 'W',\n /** 국가전문자격 */\n NATIONAL_PROFESSIONAL: 'S',\n} as const;\n\nexport type QualificationCategoryType =\n (typeof QualificationCategory)[keyof typeof QualificationCategory];\n\n/**\n * 주요 종목코드 (자주 사용되는 자격증)\n * @see https://www.data.go.kr/data/15003024/openapi.do\n * @description getSubjects()로 전체 목록 조회 가능\n */\nexport const JmCode = {\n // === 정보통신 ===\n /** 정보처리기사 */\n INFORMATION_PROCESSING_ENGINEER: '1320',\n /** 정보처리산업기사 */\n INFORMATION_PROCESSING_INDUSTRIAL_ENGINEER: '2290',\n /** 정보관리기술사 */\n INFORMATION_MANAGEMENT_PROFESSIONAL_ENGINEER: '0601',\n /** 컴퓨터시스템응용기술사 */\n COMPUTER_SYSTEM_APPLICATION_PROFESSIONAL_ENGINEER: '0622',\n\n // === 전기/전자 ===\n /** 전기기사 */\n ELECTRICAL_ENGINEER: '1150',\n /** 전기기능사 */\n ELECTRICAL_TECHNICIAN: '7780',\n /** 전기공사기사 */\n ELECTRICAL_CONSTRUCTION_ENGINEER: '1160',\n /** 전자기사 */\n ELECTRONICS_ENGINEER: '1230',\n\n // === 기계 ===\n /** 기계기사 */\n MECHANICAL_ENGINEER: '1431',\n /** 용접기사 */\n WELDING_ENGINEER: '1022',\n /** 지게차운전기능사 */\n FORKLIFT_DRIVER_TECHNICIAN: '7875',\n\n // === 건설 ===\n /** 건축기사 */\n ARCHITECTURE_ENGINEER: '1190',\n /** 토목기사 */\n CIVIL_ENGINEERING_ENGINEER: '1080',\n\n // === 조리/서비스 ===\n /** 한식조리기능사 */\n KOREAN_CUISINE_TECHNICIAN: '7910',\n /** 양식조리기능사 */\n WESTERN_CUISINE_TECHNICIAN: '7911',\n /** 미용사(일반) */\n BEAUTICIAN_GENERAL: '7937',\n} as const;\n\nexport type JmCodeType = (typeof JmCode)[keyof typeof JmCode];\n","import { HttpClient, type GongdataConfig } from './core/index.js';\nimport { QualificationService } from './services/qualification/index.js';\n\n/**\n * Gongdata 클라이언트 인터페이스\n */\nexport interface GongdataClient {\n /** 자격증 시험일정 서비스 */\n readonly qualification: QualificationService;\n}\n\n/**\n * Gongdata 클라이언트 생성\n *\n * @example\n * ```typescript\n * const client = createClient({\n * serviceKey: process.env.DATA_GO_KR_KEY!,\n * });\n *\n * const schedules = await client.qualification.getSchedules({ year: 2026 });\n * ```\n */\nexport function createClient(config: GongdataConfig): GongdataClient {\n const http = new HttpClient(config);\n\n return {\n qualification: new QualificationService(http),\n };\n}\n"]}
@@ -0,0 +1,509 @@
1
+ /**
2
+ * SDK Configuration
3
+ */
4
+ interface GongdataConfig {
5
+ /** 공공데이터포털 API 서비스 키 */
6
+ readonly serviceKey: string;
7
+ /** 요청 타임아웃 (ms), 기본값: 10000 */
8
+ readonly timeout?: number;
9
+ /** 재시도 설정 */
10
+ readonly retry?: RetryConfig;
11
+ }
12
+ interface RetryConfig {
13
+ /** 최대 재시도 횟수, 기본값: 3 */
14
+ readonly maxRetries: number;
15
+ /** 재시도 간격 (ms), 기본값: 1000 */
16
+ readonly delay: number;
17
+ }
18
+ /**
19
+ * HTTP 요청 옵션
20
+ */
21
+ interface RequestOptions {
22
+ readonly path: string;
23
+ readonly params?: Record<string, string | number | undefined>;
24
+ readonly pageNo?: number | undefined;
25
+ readonly numOfRows?: number | undefined;
26
+ }
27
+ /**
28
+ * 페이지네이션 정보
29
+ */
30
+ interface PaginationInfo {
31
+ readonly pageNo: number;
32
+ readonly numOfRows: number;
33
+ readonly totalCount: number;
34
+ }
35
+ /**
36
+ * 내부 API 응답 결과 (원본 데이터만)
37
+ * @internal
38
+ */
39
+ interface RawApiResult<T> {
40
+ readonly data: readonly T[];
41
+ readonly pagination: PaginationInfo;
42
+ }
43
+
44
+ declare class HttpClient {
45
+ private readonly serviceKey;
46
+ private readonly timeout;
47
+ private readonly maxRetries;
48
+ private readonly retryDelay;
49
+ constructor(config: GongdataConfig);
50
+ /**
51
+ * 서비스 키 반환 (일부 API에서 직접 URL 구성 시 필요)
52
+ */
53
+ getServiceKey(): string;
54
+ /**
55
+ * URL 파라미터 빌드
56
+ */
57
+ private buildParams;
58
+ /**
59
+ * 단일 요청 실행 (재시도 포함)
60
+ */
61
+ request<T>(baseUrl: string, options: RequestOptions): Promise<RawApiResult<T>>;
62
+ /**
63
+ * 전체 페이지 데이터 수집
64
+ */
65
+ requestAll<T>(baseUrl: string, options: RequestOptions, numOfRows?: number): Promise<readonly T[]>;
66
+ private sleep;
67
+ }
68
+
69
+ /**
70
+ * 공공데이터포털 API 응답 코드
71
+ * @see https://www.data.go.kr
72
+ */
73
+ declare const ResultCode: {
74
+ /** 정상 */
75
+ readonly SUCCESS: "00";
76
+ /** 어플리케이션 에러 */
77
+ readonly APPLICATION_ERROR: "1";
78
+ /** 잘못된 요청 파라미터 */
79
+ readonly INVALID_REQUEST_PARAMETER: "10";
80
+ /** 해당 오픈API 서비스 없음 또는 폐기 */
81
+ readonly NO_OPENAPI_SERVICE: "12";
82
+ /** 서비스 접근 거부 */
83
+ readonly SERVICE_ACCESS_DENIED: "20";
84
+ /** 서비스 요청 제한 횟수 초과 */
85
+ readonly REQUEST_LIMIT_EXCEEDED: "22";
86
+ /** 등록되지 않은 서비스키 */
87
+ readonly UNREGISTERED_SERVICE_KEY: "30";
88
+ /** 서비스키 기한 만료 */
89
+ readonly EXPIRED_SERVICE_KEY: "31";
90
+ /** 등록되지 않은 IP */
91
+ readonly UNREGISTERED_IP: "32";
92
+ /** 기타 에러 */
93
+ readonly UNKNOWN_ERROR: "99";
94
+ /** HTTP 에러 */
95
+ readonly HTTP_ERROR: "HTTP_ERROR";
96
+ /** 서비스 타임아웃 */
97
+ readonly SERVICE_TIMEOUT: "SERVICE_TIMEOUT";
98
+ /** 게이트웨이 인증 오류 */
99
+ readonly GATEWAY_AUTH_ERROR: "900";
100
+ /** 필수 파라미터 누락 */
101
+ readonly MISSING_REQUIRED_PARAMETER: "910";
102
+ /** 잘못된 dataFormat (json/xml만 가능) */
103
+ readonly INVALID_DATA_FORMAT: "920";
104
+ /** 최대 목록 수 초과 */
105
+ readonly MAX_ROWS_EXCEEDED: "930";
106
+ /** 잘못된 토큰 파라미터 */
107
+ readonly INVALID_TOKEN: "940";
108
+ /** 토큰 유효기한 만료 (1시간) */
109
+ readonly TOKEN_EXPIRED: "941";
110
+ /** 파일을 찾을 수 없음 */
111
+ readonly FILE_NOT_FOUND: "950";
112
+ /** HRDK 서버 에러 */
113
+ readonly HRDK_SERVER_ERROR: "990";
114
+ };
115
+ type ResultCodeType = (typeof ResultCode)[keyof typeof ResultCode];
116
+ declare class GongdataError extends Error {
117
+ readonly code: ResultCodeType | string;
118
+ readonly originalResponse?: unknown;
119
+ constructor(code: ResultCodeType | string, message?: string, originalResponse?: unknown);
120
+ static isGongdataError(error: unknown): error is GongdataError;
121
+ static fromResponse(header: {
122
+ readonly resultCode: string;
123
+ readonly resultMsg: string;
124
+ }, originalResponse?: unknown): GongdataError;
125
+ }
126
+
127
+ /**
128
+ * API 응답 기본 추상 클래스
129
+ * @template TRaw - 공공 API 원본 타입
130
+ * @template T - SDK 정규화 타입
131
+ */
132
+ declare abstract class DataResponse<TRaw, T> {
133
+ /**
134
+ * 정규화된 데이터 (SDK 보장 인터페이스)
135
+ * @description 버전 업그레이드 시에도 인터페이스 호환성 보장
136
+ */
137
+ abstract getData(): readonly T[];
138
+ /**
139
+ * 원본 데이터 (공공 API 응답 그대로)
140
+ * @description 공공 API 스펙 변경 시 같이 변경될 수 있음
141
+ */
142
+ abstract getRawData(): readonly TRaw[];
143
+ /** 정규화된 데이터 (getter) */
144
+ get data(): readonly T[];
145
+ /** 원본 데이터 (getter) */
146
+ get rawData(): readonly TRaw[];
147
+ /**
148
+ * 데이터가 비어있는지 확인
149
+ */
150
+ isEmpty(): boolean;
151
+ /**
152
+ * 데이터 개수
153
+ */
154
+ count(): number;
155
+ }
156
+ /**
157
+ * 페이지네이션이 있는 API 응답 추상 클래스
158
+ */
159
+ declare abstract class PaginatedResponse<TRaw, T> extends DataResponse<TRaw, T> {
160
+ /**
161
+ * 페이지네이션 정보
162
+ */
163
+ abstract getPagination(): PaginationInfo;
164
+ /** 페이지네이션 정보 (getter) */
165
+ get pagination(): PaginationInfo;
166
+ /** 전체 데이터 개수 */
167
+ get totalCount(): number;
168
+ /** 현재 페이지 번호 */
169
+ get pageNo(): number;
170
+ /** 페이지 당 항목 수 */
171
+ get numOfRows(): number;
172
+ /**
173
+ * 다음 페이지 존재 여부
174
+ */
175
+ hasNextPage(): boolean;
176
+ }
177
+
178
+ /**
179
+ * 모든 서비스의 기본 추상 클래스
180
+ * 새 서비스 추가 시 이 클래스를 상속받아 구현
181
+ */
182
+ declare abstract class BaseService {
183
+ protected readonly http: HttpClient;
184
+ /** 서비스 기본 URL */
185
+ protected abstract readonly baseUrl: string;
186
+ constructor(http: HttpClient);
187
+ /**
188
+ * 단일 페이지 요청
189
+ */
190
+ protected request<T>(options: RequestOptions): Promise<RawApiResult<T>>;
191
+ /**
192
+ * 전체 페이지 자동 수집
193
+ */
194
+ protected requestAll<T>(options: RequestOptions, numOfRows?: number): Promise<readonly T[]>;
195
+ }
196
+
197
+ /**
198
+ * 시험일정 조회 파라미터
199
+ */
200
+ interface GetSchedulesParams {
201
+ /** 시행년도 (YYYY) */
202
+ readonly year: number;
203
+ /** 자격구분코드 (T: 국가기술자격, C: 과정평가형, W: 일학습병행, S: 국가전문자격) */
204
+ readonly category?: string;
205
+ /** 종목코드 */
206
+ readonly jmCode?: string;
207
+ }
208
+ /**
209
+ * 시험일정 원본 데이터 (공공 API 응답 그대로)
210
+ * @see https://www.data.go.kr/data/15074408/openapi.do
211
+ */
212
+ interface RawExamSchedule {
213
+ /** 시행년도 */
214
+ readonly implYy: string;
215
+ /** 시행회차 */
216
+ readonly implSeq: number;
217
+ /** 자격구분코드 (T/C/W/S) */
218
+ readonly qualgbCd: string;
219
+ /** 자격구분명 */
220
+ readonly qualgbNm: string;
221
+ /** 시행계획 설명 */
222
+ readonly description: string;
223
+ /** 필기시험 원서접수 시작일자 (YYYYMMDD) */
224
+ readonly docRegStartDt: string;
225
+ /** 필기시험 원서접수 종료일자 (YYYYMMDD) */
226
+ readonly docRegEndDt: string;
227
+ /** 필기시험 시작일자 (YYYYMMDD) */
228
+ readonly docExamStartDt: string;
229
+ /** 필기시험 종료일자 (YYYYMMDD) */
230
+ readonly docExamEndDt: string;
231
+ /** 필기시험 합격(예정)자 발표일자 (YYYYMMDD) */
232
+ readonly docPassDt: string;
233
+ /** 실기(작업)/면접 시험 원서접수 시작일자 (YYYYMMDD) */
234
+ readonly pracRegStartDt: string;
235
+ /** 실기(작업)/면접 시험 원서접수 종료일자 (YYYYMMDD) */
236
+ readonly pracRegEndDt: string;
237
+ /** 실기(작업)/면접 시험 시작일자 (YYYYMMDD) */
238
+ readonly pracExamStartDt: string;
239
+ /** 실기(작업)/면접 시험 종료일자 (YYYYMMDD) */
240
+ readonly pracExamEndDt: string;
241
+ /** 실기(작업)/면접 합격자 발표일자 (YYYYMMDD) */
242
+ readonly pracPassDt: string;
243
+ }
244
+ /**
245
+ * 시험 기간 정보
246
+ */
247
+ interface ExamPeriod {
248
+ /** 원서접수 시작일 (YYYY-MM-DD) */
249
+ readonly registrationStart: string;
250
+ /** 원서접수 종료일 (YYYY-MM-DD) */
251
+ readonly registrationEnd: string;
252
+ /** 시험 시작일 (YYYY-MM-DD) */
253
+ readonly examStart: string;
254
+ /** 시험 종료일 (YYYY-MM-DD) */
255
+ readonly examEnd: string;
256
+ /** 합격자 발표일 (YYYY-MM-DD) */
257
+ readonly resultDate: string;
258
+ }
259
+ /**
260
+ * 자격 구분 정보
261
+ */
262
+ interface QualificationCategoryInfo {
263
+ /** 자격구분 코드 (T/C/W/S) */
264
+ readonly code: string;
265
+ /** 자격구분명 (국가기술자격, 과정평가형자격 등) */
266
+ readonly name: string;
267
+ }
268
+ /**
269
+ * 시험일정 정규화 데이터 (SDK 보장 인터페이스)
270
+ */
271
+ interface ExamSchedule {
272
+ /** 시행년도 */
273
+ readonly year: number;
274
+ /** 시행회차 (1회, 2회, 3회 등) */
275
+ readonly round: number;
276
+ /** 자격구분 */
277
+ readonly category: QualificationCategoryInfo;
278
+ /** 시행계획 설명 */
279
+ readonly description: string;
280
+ /** 필기시험 일정 */
281
+ readonly writtenExam: ExamPeriod;
282
+ /** 실기시험 일정 */
283
+ readonly practicalExam: ExamPeriod;
284
+ }
285
+ /**
286
+ * 종목 원본 데이터 (공공 API 응답 그대로)
287
+ * @see https://www.data.go.kr/data/15003024/openapi.do
288
+ */
289
+ interface RawSubject {
290
+ /** 종목코드 */
291
+ readonly jmcd: string;
292
+ /** 종목명 */
293
+ readonly jmfldnm: string;
294
+ /** 자격구분코드 (T/C/W/S) */
295
+ readonly qualgbcd: string;
296
+ /** 자격구분명 */
297
+ readonly qualgbnm: string;
298
+ /** 계열코드 */
299
+ readonly seriescd: string;
300
+ /** 계열명 */
301
+ readonly seriesnm: string;
302
+ /** 대직무분야코드 */
303
+ readonly obligfldcd: string;
304
+ /** 대직무분야명 */
305
+ readonly obligfldnm: string;
306
+ /** 중직무분야코드 */
307
+ readonly mdobligfldcd: string;
308
+ /** 중직무분야명 */
309
+ readonly mdobligfldnm: string;
310
+ }
311
+ /**
312
+ * 직무분야 정보
313
+ */
314
+ interface JobField {
315
+ /** 직무분야 코드 */
316
+ readonly code: string;
317
+ /** 직무분야명 */
318
+ readonly name: string;
319
+ }
320
+ /**
321
+ * 종목 정규화 데이터 (SDK 보장 인터페이스)
322
+ */
323
+ interface Subject {
324
+ /** 종목코드 */
325
+ readonly code: string;
326
+ /** 종목명 */
327
+ readonly name: string;
328
+ /** 자격구분 */
329
+ readonly category: QualificationCategoryInfo;
330
+ /** 계열 (기술사, 기사, 기능사 등) */
331
+ readonly series: {
332
+ readonly code: string;
333
+ readonly name: string;
334
+ };
335
+ /** 대직무분야 */
336
+ readonly majorJobField: JobField;
337
+ /** 중직무분야 */
338
+ readonly minorJobField: JobField;
339
+ }
340
+
341
+ /**
342
+ * 시험일정 조회 결과
343
+ */
344
+ declare class ScheduleResponse extends PaginatedResponse<RawExamSchedule, ExamSchedule> {
345
+ private readonly _raw;
346
+ private readonly _data;
347
+ private readonly _pagination;
348
+ constructor(raw: readonly RawExamSchedule[], data: readonly ExamSchedule[], pagination: PaginationInfo);
349
+ getData(): readonly ExamSchedule[];
350
+ getRawData(): readonly RawExamSchedule[];
351
+ getPagination(): PaginationInfo;
352
+ }
353
+ /**
354
+ * 시험일정 전체 조회 결과 (페이지네이션 없음)
355
+ */
356
+ declare class AllSchedulesResponse extends DataResponse<RawExamSchedule, ExamSchedule> {
357
+ private readonly _raw;
358
+ private readonly _data;
359
+ constructor(raw: readonly RawExamSchedule[], data: readonly ExamSchedule[]);
360
+ getData(): readonly ExamSchedule[];
361
+ getRawData(): readonly RawExamSchedule[];
362
+ }
363
+ /**
364
+ * 종목 목록 조회 결과
365
+ */
366
+ declare class SubjectResponse extends DataResponse<RawSubject, Subject> {
367
+ private readonly _raw;
368
+ private readonly _data;
369
+ constructor(raw: readonly RawSubject[], data: readonly Subject[]);
370
+ getData(): readonly Subject[];
371
+ getRawData(): readonly RawSubject[];
372
+ /**
373
+ * 종목코드로 찾기
374
+ */
375
+ findByCode(code: string): Subject | undefined;
376
+ /**
377
+ * 종목명으로 찾기
378
+ */
379
+ findByName(name: string): Subject | undefined;
380
+ /**
381
+ * 자격구분으로 필터링
382
+ */
383
+ filterByCategory(categoryCode: string): readonly Subject[];
384
+ }
385
+
386
+ /**
387
+ * 자격증 시험일정 서비스
388
+ * @see https://www.data.go.kr/data/15074408/openapi.do
389
+ */
390
+ declare class QualificationService extends BaseService {
391
+ protected readonly baseUrl = "http://apis.data.go.kr/B490007/qualExamSchd";
392
+ /**
393
+ * 시험일정 목록 조회 (단일 페이지)
394
+ *
395
+ * @example
396
+ * ```typescript
397
+ * const result = await client.qualification.getSchedules({ year: 2026 });
398
+ *
399
+ * // 정규화된 데이터 (SDK 보장)
400
+ * result.getData()[0].writtenExam.registrationStart // '2026-01-24'
401
+ *
402
+ * // 원본 데이터 (공공 API 그대로)
403
+ * result.getRawData()[0].docRegStartDt // '20260124'
404
+ * ```
405
+ */
406
+ getSchedules(params: GetSchedulesParams, options?: {
407
+ readonly pageNo?: number;
408
+ readonly numOfRows?: number;
409
+ }): Promise<ScheduleResponse>;
410
+ /**
411
+ * 시험일정 전체 조회 (모든 페이지 자동 수집)
412
+ */
413
+ getAllSchedules(params: GetSchedulesParams): Promise<AllSchedulesResponse>;
414
+ /**
415
+ * 국가자격 종목 전체 목록 조회
416
+ *
417
+ * @example
418
+ * ```typescript
419
+ * const result = await client.qualification.getSubjects();
420
+ *
421
+ * // 정규화된 데이터
422
+ * result.getData()[0].name // '정보처리기사'
423
+ *
424
+ * // 편의 메서드
425
+ * result.findByName('정보처리기사') // Subject
426
+ * result.filterByCategory('T') // 국가기술자격만
427
+ * ```
428
+ */
429
+ getSubjects(): Promise<SubjectResponse>;
430
+ }
431
+
432
+ /**
433
+ * 자격구분 코드
434
+ * @see https://www.data.go.kr/data/15074408/openapi.do
435
+ */
436
+ declare const QualificationCategory: {
437
+ /** 국가기술자격 */
438
+ readonly NATIONAL_TECHNICAL: "T";
439
+ /** 과정평가형자격 */
440
+ readonly COURSE_EVALUATION: "C";
441
+ /** 일학습병행자격 */
442
+ readonly WORK_LEARNING: "W";
443
+ /** 국가전문자격 */
444
+ readonly NATIONAL_PROFESSIONAL: "S";
445
+ };
446
+ type QualificationCategoryType = (typeof QualificationCategory)[keyof typeof QualificationCategory];
447
+ /**
448
+ * 주요 종목코드 (자주 사용되는 자격증)
449
+ * @see https://www.data.go.kr/data/15003024/openapi.do
450
+ * @description getSubjects()로 전체 목록 조회 가능
451
+ */
452
+ declare const JmCode: {
453
+ /** 정보처리기사 */
454
+ readonly INFORMATION_PROCESSING_ENGINEER: "1320";
455
+ /** 정보처리산업기사 */
456
+ readonly INFORMATION_PROCESSING_INDUSTRIAL_ENGINEER: "2290";
457
+ /** 정보관리기술사 */
458
+ readonly INFORMATION_MANAGEMENT_PROFESSIONAL_ENGINEER: "0601";
459
+ /** 컴퓨터시스템응용기술사 */
460
+ readonly COMPUTER_SYSTEM_APPLICATION_PROFESSIONAL_ENGINEER: "0622";
461
+ /** 전기기사 */
462
+ readonly ELECTRICAL_ENGINEER: "1150";
463
+ /** 전기기능사 */
464
+ readonly ELECTRICAL_TECHNICIAN: "7780";
465
+ /** 전기공사기사 */
466
+ readonly ELECTRICAL_CONSTRUCTION_ENGINEER: "1160";
467
+ /** 전자기사 */
468
+ readonly ELECTRONICS_ENGINEER: "1230";
469
+ /** 기계기사 */
470
+ readonly MECHANICAL_ENGINEER: "1431";
471
+ /** 용접기사 */
472
+ readonly WELDING_ENGINEER: "1022";
473
+ /** 지게차운전기능사 */
474
+ readonly FORKLIFT_DRIVER_TECHNICIAN: "7875";
475
+ /** 건축기사 */
476
+ readonly ARCHITECTURE_ENGINEER: "1190";
477
+ /** 토목기사 */
478
+ readonly CIVIL_ENGINEERING_ENGINEER: "1080";
479
+ /** 한식조리기능사 */
480
+ readonly KOREAN_CUISINE_TECHNICIAN: "7910";
481
+ /** 양식조리기능사 */
482
+ readonly WESTERN_CUISINE_TECHNICIAN: "7911";
483
+ /** 미용사(일반) */
484
+ readonly BEAUTICIAN_GENERAL: "7937";
485
+ };
486
+ type JmCodeType = (typeof JmCode)[keyof typeof JmCode];
487
+
488
+ /**
489
+ * Gongdata 클라이언트 인터페이스
490
+ */
491
+ interface GongdataClient {
492
+ /** 자격증 시험일정 서비스 */
493
+ readonly qualification: QualificationService;
494
+ }
495
+ /**
496
+ * Gongdata 클라이언트 생성
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * const client = createClient({
501
+ * serviceKey: process.env.DATA_GO_KR_KEY!,
502
+ * });
503
+ *
504
+ * const schedules = await client.qualification.getSchedules({ year: 2026 });
505
+ * ```
506
+ */
507
+ declare function createClient(config: GongdataConfig): GongdataClient;
508
+
509
+ export { AllSchedulesResponse, BaseService, DataResponse, type ExamSchedule, type GetSchedulesParams, type GongdataClient, type GongdataConfig, GongdataError, JmCode, type JmCodeType, PaginatedResponse, type PaginationInfo, QualificationCategory, type QualificationCategoryType, QualificationService, type RawExamSchedule, type RawSubject, ResultCode, type ResultCodeType, type RetryConfig, ScheduleResponse, type Subject, SubjectResponse, createClient };