krx-cli 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/client/rate-limit.ts","../src/cli/index.ts","../src/client/auth.ts","../src/client/endpoints.ts","../src/client/client.ts","../src/output/formatter.ts","../src/cli/commands/auth.ts","../src/validator/index.ts","../src/cli/error-handler.ts","../src/cli/commands/index-cmd.ts","../src/cli/commands/stock.ts","../src/cli/commands/etp.ts","../src/cli/commands/bond.ts","../src/cli/commands/derivative.ts","../src/cli/commands/commodity.ts","../src/cli/commands/esg.ts","../src/cli/commands/schema.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\n\nconst CONFIG_DIR = path.join(os.homedir(), \".krx-cli\");\nconst RATE_FILE = path.join(CONFIG_DIR, \"rate-limit.json\");\nconst DAILY_LIMIT = 10_000;\nconst WARNING_THRESHOLD = 0.8;\n\ninterface RateData {\n readonly date: string;\n readonly count: number;\n}\n\nfunction today(): string {\n const now = new Date();\n const yyyy = now.getFullYear().toString();\n const mm = (now.getMonth() + 1).toString().padStart(2, \"0\");\n const dd = now.getDate().toString().padStart(2, \"0\");\n return `${yyyy}${mm}${dd}`;\n}\n\nfunction readRateData(): RateData {\n try {\n const raw = fs.readFileSync(RATE_FILE, \"utf-8\");\n return JSON.parse(raw) as RateData;\n } catch {\n return { date: today(), count: 0 };\n }\n}\n\nfunction writeRateData(data: RateData): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(RATE_FILE, JSON.stringify(data, null, 2), \"utf-8\");\n}\n\nexport function incrementCallCount(): { count: number; limit: number } {\n const data = readRateData();\n const currentDate = today();\n\n const newData: RateData =\n data.date === currentDate\n ? { date: currentDate, count: data.count + 1 }\n : { date: currentDate, count: 1 };\n\n writeRateData(newData);\n return { count: newData.count, limit: DAILY_LIMIT };\n}\n\nexport function checkRateLimit(): {\n allowed: boolean;\n count: number;\n limit: number;\n warning: boolean;\n} {\n const data = readRateData();\n const currentDate = today();\n\n const count = data.date === currentDate ? data.count : 0;\n const allowed = count < DAILY_LIMIT;\n const warning = count >= DAILY_LIMIT * WARNING_THRESHOLD;\n\n return { allowed, count, limit: DAILY_LIMIT, warning };\n}\n\nexport function getRateLimitStatus(): {\n date: string;\n count: number;\n limit: number;\n remaining: number;\n} {\n const data = readRateData();\n const currentDate = today();\n const count = data.date === currentDate ? data.count : 0;\n\n return {\n date: currentDate,\n count,\n limit: DAILY_LIMIT,\n remaining: DAILY_LIMIT - count,\n };\n}\n","import { Command } from \"commander\";\nimport { registerAuthCommand } from \"./commands/auth.js\";\nimport { registerIndexCommand } from \"./commands/index-cmd.js\";\nimport { registerStockCommand } from \"./commands/stock.js\";\nimport { registerEtpCommand } from \"./commands/etp.js\";\nimport { registerBondCommand } from \"./commands/bond.js\";\nimport { registerDerivativeCommand } from \"./commands/derivative.js\";\nimport { registerCommodityCommand } from \"./commands/commodity.js\";\nimport { registerEsgCommand } from \"./commands/esg.js\";\nimport { registerSchemaCommand } from \"./commands/schema.js\";\nimport { writeError } from \"../output/formatter.js\";\n\nconst EXIT_CODES = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n USAGE_ERROR: 2,\n NO_DATA: 3,\n AUTH_FAILURE: 4,\n RATE_LIMIT: 5,\n SERVICE_NOT_APPROVED: 6,\n} as const;\n\nexport { EXIT_CODES };\n\nconst program = new Command();\n\nprogram\n .name(\"krx\")\n .description(\"Agent-native CLI for KRX (Korea Exchange) Open API\")\n .version(\"0.1.0\")\n .option(\"-o, --output <format>\", \"output format: json, table, ndjson\")\n .option(\"-f, --fields <fields>\", \"comma-separated fields to include\")\n .option(\"--dry-run\", \"show request without calling API\")\n .option(\"-v, --verbose\", \"verbose output to stderr\");\n\nregisterAuthCommand(program);\nregisterIndexCommand(program);\nregisterStockCommand(program);\nregisterEtpCommand(program);\nregisterBondCommand(program);\nregisterDerivativeCommand(program);\nregisterCommodityCommand(program);\nregisterEsgCommand(program);\nregisterSchemaCommand(program);\n\nprogram.exitOverride();\n\ntry {\n await program.parseAsync(process.argv);\n} catch (err) {\n if (err instanceof Error && \"exitCode\" in err) {\n const exitCode = (err as Error & { exitCode: number }).exitCode;\n process.exit(exitCode);\n }\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.GENERAL_ERROR);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { CATEGORIES, type CategoryId } from \"./endpoints.js\";\nimport { krxFetch } from \"./client.js\";\n\nconst CONFIG_DIR = path.join(os.homedir(), \".krx-cli\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\n\ninterface Config {\n readonly apiKey?: string;\n readonly serviceStatus?: Record<\n string,\n { approved: boolean; checkedAt: string }\n >;\n}\n\nfunction readConfig(): Config {\n try {\n const raw = fs.readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as Config;\n } catch {\n return {};\n }\n}\n\nfunction writeConfig(config: Config): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\nexport function getApiKey(): string | undefined {\n return process.env[\"KRX_API_KEY\"] ?? readConfig().apiKey;\n}\n\nexport function saveApiKey(apiKey: string): void {\n const config = readConfig();\n writeConfig({ ...config, apiKey });\n}\n\nfunction getRecentTradingDate(): string {\n const now = new Date();\n const day = now.getDay();\n const daysBack = day === 0 ? 2 : day === 6 ? 1 : day === 1 ? 3 : 1;\n const target = new Date(now.getTime() - daysBack * 24 * 60 * 60 * 1000);\n\n const yyyy = target.getFullYear().toString();\n const mm = (target.getMonth() + 1).toString().padStart(2, \"0\");\n const dd = target.getDate().toString().padStart(2, \"0\");\n return `${yyyy}${mm}${dd}`;\n}\n\nexport interface ServiceStatus {\n readonly approved: boolean;\n readonly checkedAt: string;\n readonly error?: string;\n}\n\nexport async function checkCategoryApproval(\n apiKey: string,\n categoryId: CategoryId,\n): Promise<ServiceStatus> {\n const category = CATEGORIES.find((c) => c.id === categoryId);\n if (!category) {\n return { approved: false, checkedAt: new Date().toISOString() };\n }\n\n const basDd = getRecentTradingDate();\n\n try {\n const result = await krxFetch({\n endpoint: category.probeEndpoint,\n params: { basDd },\n apiKey,\n });\n\n const status: ServiceStatus = {\n approved: result.success,\n checkedAt: new Date().toISOString(),\n ...(result.error ? { error: result.error } : {}),\n };\n\n const config = readConfig();\n const serviceStatus = { ...config.serviceStatus, [categoryId]: status };\n writeConfig({ ...config, serviceStatus });\n\n return status;\n } catch {\n return { approved: false, checkedAt: new Date().toISOString() };\n }\n}\n\nexport async function checkAllCategories(\n apiKey: string,\n): Promise<Record<CategoryId, ServiceStatus>> {\n const results = await Promise.all(\n CATEGORIES.map(async (cat) => {\n const status = await checkCategoryApproval(apiKey, cat.id);\n return [cat.id, status] as const;\n }),\n );\n\n return Object.fromEntries(results) as Record<CategoryId, ServiceStatus>;\n}\n\nexport function getCachedServiceStatus(): Record<string, ServiceStatus> {\n return readConfig().serviceStatus ?? {};\n}\n","export interface EndpointDef {\n readonly path: string;\n readonly description: string;\n readonly descriptionKo: string;\n readonly category: CategoryId;\n}\n\nexport type CategoryId =\n | \"index\"\n | \"stock\"\n | \"etp\"\n | \"bond\"\n | \"derivative\"\n | \"commodity\"\n | \"esg\";\n\nexport interface CategoryDef {\n readonly id: CategoryId;\n readonly code: string;\n readonly name: string;\n readonly nameKo: string;\n readonly probeEndpoint: string;\n}\n\nexport const CATEGORIES: readonly CategoryDef[] = [\n {\n id: \"index\",\n code: \"idx\",\n name: \"Index\",\n nameKo: \"지수\",\n probeEndpoint: \"/svc/apis/idx/kospi_dd_trd\",\n },\n {\n id: \"stock\",\n code: \"sto\",\n name: \"Stock\",\n nameKo: \"주식\",\n probeEndpoint: \"/svc/apis/sto/stk_bydd_trd\",\n },\n {\n id: \"etp\",\n code: \"etp\",\n name: \"ETP\",\n nameKo: \"증권상품\",\n probeEndpoint: \"/svc/apis/etp/etf_bydd_trd\",\n },\n {\n id: \"bond\",\n code: \"bon\",\n name: \"Bond\",\n nameKo: \"채권\",\n probeEndpoint: \"/svc/apis/bon/bnd_bydd_trd\",\n },\n {\n id: \"derivative\",\n code: \"drv\",\n name: \"Derivative\",\n nameKo: \"파생상품\",\n probeEndpoint: \"/svc/apis/drv/fut_bydd_trd\",\n },\n {\n id: \"commodity\",\n code: \"gen\",\n name: \"Commodity\",\n nameKo: \"일반상품\",\n probeEndpoint: \"/svc/apis/gen/gold_bydd_trd\",\n },\n {\n id: \"esg\",\n code: \"esg\",\n name: \"ESG\",\n nameKo: \"ESG\",\n probeEndpoint: \"/svc/apis/esg/esg_index_info\",\n },\n] as const;\n\nexport const ENDPOINTS: readonly EndpointDef[] = [\n // Index (idx)\n {\n path: \"/svc/apis/idx/krx_dd_trd\",\n description: \"KRX series index daily trading\",\n descriptionKo: \"KRX 시리즈 지수 일별시세\",\n category: \"index\",\n },\n {\n path: \"/svc/apis/idx/kospi_dd_trd\",\n description: \"KOSPI series index daily trading\",\n descriptionKo: \"KOSPI 시리즈 지수 일별시세\",\n category: \"index\",\n },\n {\n path: \"/svc/apis/idx/kosdaq_dd_trd\",\n description: \"KOSDAQ series index daily trading\",\n descriptionKo: \"KOSDAQ 시리즈 지수 일별시세\",\n category: \"index\",\n },\n {\n path: \"/svc/apis/idx/bon_dd_trd\",\n description: \"Bond index daily trading\",\n descriptionKo: \"채권지수 일별시세\",\n category: \"index\",\n },\n {\n path: \"/svc/apis/idx/drvprod_dd_trd\",\n description: \"Derivatives index daily trading\",\n descriptionKo: \"파생상품지수 일별시세\",\n category: \"index\",\n },\n\n // Stock (sto)\n {\n path: \"/svc/apis/sto/stk_bydd_trd\",\n description: \"KOSPI stock daily trading\",\n descriptionKo: \"유가증권(KOSPI) 주식 일별매매정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/ksq_bydd_trd\",\n description: \"KOSDAQ stock daily trading\",\n descriptionKo: \"코스닥(KOSDAQ) 주식 일별매매정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/knx_bydd_trd\",\n description: \"KONEX stock daily trading\",\n descriptionKo: \"코넥스(KONEX) 주식 일별매매정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/sw_bydd_trd\",\n description: \"Subscription warrant daily trading\",\n descriptionKo: \"신주인수권증권 일별매매정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/sr_bydd_trd\",\n description: \"Subscription right daily trading\",\n descriptionKo: \"신주인수권증서 일별매매정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/stk_isu_base_info\",\n description: \"KOSPI stock base info\",\n descriptionKo: \"유가증권 종목 기본정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/ksq_isu_base_info\",\n description: \"KOSDAQ stock base info\",\n descriptionKo: \"코스닥 종목 기본정보\",\n category: \"stock\",\n },\n {\n path: \"/svc/apis/sto/knx_isu_base_info\",\n description: \"KONEX stock base info\",\n descriptionKo: \"코넥스 종목 기본정보\",\n category: \"stock\",\n },\n\n // ETP\n {\n path: \"/svc/apis/etp/etf_bydd_trd\",\n description: \"ETF daily trading\",\n descriptionKo: \"ETF 일별매매정보\",\n category: \"etp\",\n },\n {\n path: \"/svc/apis/etp/etn_bydd_trd\",\n description: \"ETN daily trading\",\n descriptionKo: \"ETN 일별매매정보\",\n category: \"etp\",\n },\n {\n path: \"/svc/apis/etp/elw_bydd_trd\",\n description: \"ELW daily trading\",\n descriptionKo: \"ELW 일별매매정보\",\n category: \"etp\",\n },\n\n // Bond (bon)\n {\n path: \"/svc/apis/bon/kts_bydd_trd\",\n description: \"KTS government bond daily trading\",\n descriptionKo: \"국채전문유통시장 일별매매정보\",\n category: \"bond\",\n },\n {\n path: \"/svc/apis/bon/bnd_bydd_trd\",\n description: \"General bond daily trading\",\n descriptionKo: \"일반채권시장 일별매매정보\",\n category: \"bond\",\n },\n {\n path: \"/svc/apis/bon/smb_bydd_trd\",\n description: \"Small bond daily trading\",\n descriptionKo: \"소액채권시장 일별매매정보\",\n category: \"bond\",\n },\n\n // Derivatives (drv)\n {\n path: \"/svc/apis/drv/fut_bydd_trd\",\n description: \"Futures daily trading\",\n descriptionKo: \"선물 일별매매정보\",\n category: \"derivative\",\n },\n {\n path: \"/svc/apis/drv/eqsfu_stk_bydd_trd\",\n description: \"KOSPI stock futures daily trading\",\n descriptionKo: \"유가증권 주식선물 일별매매정보\",\n category: \"derivative\",\n },\n {\n path: \"/svc/apis/drv/eqkfu_ksq_bydd_trd\",\n description: \"KOSDAQ stock futures daily trading\",\n descriptionKo: \"코스닥 주식선물 일별매매정보\",\n category: \"derivative\",\n },\n {\n path: \"/svc/apis/drv/opt_bydd_trd\",\n description: \"Options daily trading\",\n descriptionKo: \"옵션 일별매매정보\",\n category: \"derivative\",\n },\n {\n path: \"/svc/apis/drv/eqsop_bydd_trd\",\n description: \"KOSPI stock options daily trading\",\n descriptionKo: \"유가증권 주식옵션 일별매매정보\",\n category: \"derivative\",\n },\n {\n path: \"/svc/apis/drv/eqkop_bydd_trd\",\n description: \"KOSDAQ stock options daily trading\",\n descriptionKo: \"코스닥 주식옵션 일별매매정보\",\n category: \"derivative\",\n },\n\n // Commodities (gen)\n {\n path: \"/svc/apis/gen/oil_bydd_trd\",\n description: \"Oil market daily trading\",\n descriptionKo: \"석유시장 일별매매정보\",\n category: \"commodity\",\n },\n {\n path: \"/svc/apis/gen/gold_bydd_trd\",\n description: \"Gold market daily trading\",\n descriptionKo: \"금시장 일별매매정보\",\n category: \"commodity\",\n },\n {\n path: \"/svc/apis/gen/ets_bydd_trd\",\n description: \"Emission trading daily\",\n descriptionKo: \"배출권시장 일별매매정보\",\n category: \"commodity\",\n },\n\n // ESG\n {\n path: \"/svc/apis/esg/sri_bond_info\",\n description: \"SRI bond info\",\n descriptionKo: \"사회책임투자채권 종목정보\",\n category: \"esg\",\n },\n {\n path: \"/svc/apis/esg/esg_etp_info\",\n description: \"ESG ETP info\",\n descriptionKo: \"ESG 증권상품 정보\",\n category: \"esg\",\n },\n {\n path: \"/svc/apis/esg/esg_index_info\",\n description: \"ESG index info\",\n descriptionKo: \"ESG 지수 정보\",\n category: \"esg\",\n },\n] as const;\n\nexport function getEndpointsByCategory(\n category: CategoryId,\n): readonly EndpointDef[] {\n return ENDPOINTS.filter((e) => e.category === category);\n}\n\nexport function getCategoryById(id: CategoryId): CategoryDef | undefined {\n return CATEGORIES.find((c) => c.id === id);\n}\n","export const BASE_URL = \"https://data-dbg.krx.co.kr\";\n\nexport interface KrxRequestOptions {\n readonly endpoint: string;\n readonly params: Record<string, string>;\n readonly apiKey: string;\n}\n\nexport interface KrxResponse<T = Record<string, string>> {\n readonly success: boolean;\n readonly data: readonly T[];\n readonly error?: string;\n readonly errorCode?: string;\n}\n\ninterface KrxErrorBody {\n readonly respMsg?: string;\n readonly respCode?: string;\n}\n\nexport async function krxFetch<T = Record<string, string>>(\n options: KrxRequestOptions,\n): Promise<KrxResponse<T>> {\n const { checkRateLimit, incrementCallCount } =\n await import(\"./rate-limit.js\");\n const rateStatus = checkRateLimit();\n\n if (!rateStatus.allowed) {\n return {\n success: false,\n data: [],\n error: `Daily rate limit exceeded (${rateStatus.count}/${rateStatus.limit})`,\n errorCode: \"RATE_LIMIT\",\n };\n }\n\n if (rateStatus.warning) {\n process.stderr.write(\n `Warning: ${rateStatus.count}/${rateStatus.limit} API calls used today\\n`,\n );\n }\n\n const url = `${BASE_URL}${options.endpoint}`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n AUTH_KEY: options.apiKey,\n \"Content-Type\": \"application/json; charset=utf-8\",\n },\n body: JSON.stringify(options.params),\n });\n\n incrementCallCount();\n\n if (!response.ok) {\n let errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n let errorCode: string | undefined;\n\n try {\n const errorBody = (await response.json()) as KrxErrorBody;\n if (errorBody.respMsg) {\n errorMsg = errorBody.respMsg;\n }\n errorCode = errorBody.respCode;\n } catch {\n // response body is not JSON, use default error message\n }\n\n return {\n success: false,\n data: [],\n error: errorMsg,\n errorCode,\n };\n }\n\n const body = (await response.json()) as Record<string, unknown>;\n\n const outBlock = body[\"OutBlock_1\"];\n if (!Array.isArray(outBlock)) {\n return {\n success: false,\n data: [],\n error: \"Unexpected response format: missing OutBlock_1\",\n };\n }\n\n return {\n success: true,\n data: outBlock as T[],\n };\n}\n","export type OutputFormat = \"json\" | \"table\" | \"ndjson\";\n\nexport function detectOutputFormat(explicit?: string): OutputFormat {\n if (explicit) {\n return explicit as OutputFormat;\n }\n return process.stdout.isTTY ? \"table\" : \"json\";\n}\n\nexport function formatOutput(\n data: readonly Record<string, unknown>[],\n format: OutputFormat,\n fields?: readonly string[],\n): string {\n const filtered = fields ? filterFields(data, fields) : data;\n\n switch (format) {\n case \"json\":\n return JSON.stringify(filtered, null, 2);\n case \"ndjson\":\n return filtered.map((row) => JSON.stringify(row)).join(\"\\n\");\n case \"table\":\n return formatTable(filtered);\n }\n}\n\nfunction filterFields(\n data: readonly Record<string, unknown>[],\n fields: readonly string[],\n): readonly Record<string, unknown>[] {\n return data.map((row) => {\n const filtered: Record<string, unknown> = {};\n for (const field of fields) {\n if (field in row) {\n filtered[field] = row[field];\n }\n }\n return filtered;\n });\n}\n\nfunction formatTable(data: readonly Record<string, unknown>[]): string {\n if (data.length === 0) return \"(no data)\";\n\n const firstRow = data[0];\n if (!firstRow) return \"(no data)\";\n\n const keys = Object.keys(firstRow);\n const widths = keys.map((key) => {\n const values = data.map((row) => String(row[key] ?? \"\"));\n return Math.max(key.length, ...values.map((v) => v.length));\n });\n\n const header = keys.map((k, i) => k.padEnd(widths[i] ?? 0)).join(\" \");\n const separator = widths.map((w) => \"-\".repeat(w)).join(\" \");\n const rows = data.map((row) =>\n keys\n .map((k, i) => String(row[k] ?? \"\").padEnd(widths[i] ?? 0))\n .join(\" \"),\n );\n\n return [header, separator, ...rows].join(\"\\n\");\n}\n\nexport function writeOutput(output: string): void {\n process.stdout.write(output + \"\\n\");\n}\n\nexport function writeError(message: string): void {\n process.stderr.write(`Error: ${message}\\n`);\n}\n","import { Command } from \"commander\";\nimport {\n saveApiKey,\n getApiKey,\n checkAllCategories,\n checkCategoryApproval,\n} from \"../../client/auth.js\";\nimport type { CategoryId } from \"../../client/endpoints.js\";\nimport { CATEGORIES } from \"../../client/endpoints.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\n\nexport function registerAuthCommand(program: Command): void {\n const auth = program\n .command(\"auth\")\n .description(\"Manage API key and service approvals\");\n\n auth\n .command(\"set <api-key>\")\n .description(\"Save KRX API key\")\n .action((apiKey: string) => {\n saveApiKey(apiKey);\n writeOutput(JSON.stringify({ success: true, message: \"API key saved\" }));\n });\n\n auth\n .command(\"status\")\n .description(\"Check API key and service approval status\")\n .action(async () => {\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n writeError(\"Checking service approvals...\");\n const statuses = await checkAllCategories(apiKey);\n\n const format = detectOutputFormat(\n program.parent?.opts().output ?? program.opts().output,\n );\n\n const result = {\n api_key_set: true,\n services: statuses,\n };\n\n if (format === \"json\" || format === \"ndjson\") {\n writeOutput(JSON.stringify(result, null, 2));\n } else {\n const rows = CATEGORIES.map((cat) => {\n const status = statuses[cat.id];\n return {\n category: cat.id,\n name: cat.nameKo,\n approved: status?.approved ? \"YES\" : \"NO\",\n checked_at: status?.checkedAt ?? \"-\",\n };\n });\n writeOutput(\n formatOutput(\n rows as unknown as Record<string, unknown>[],\n \"table\",\n ),\n );\n }\n });\n\n auth\n .command(\"check <category>\")\n .description(\"Check approval for a specific category\")\n .action(async (category: string) => {\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const validCategories = CATEGORIES.map((c) => c.id);\n if (!validCategories.includes(category as CategoryId)) {\n writeError(\n `Invalid category: ${category}. Must be one of: ${validCategories.join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const status = await checkCategoryApproval(\n apiKey,\n category as CategoryId,\n );\n writeOutput(JSON.stringify({ category, ...status }, null, 2));\n });\n}\n","import { z } from \"zod/v4\";\n\nconst DATE_PATTERN = /^\\d{8}$/;\n\nexport const dateSchema = z\n .string()\n .regex(DATE_PATTERN, \"Date must be YYYYMMDD format (8 digits)\")\n .refine(\n (val) => {\n const year = parseInt(val.slice(0, 4), 10);\n const month = parseInt(val.slice(4, 6), 10);\n const day = parseInt(val.slice(6, 8), 10);\n if (year < 2010 || year > 2100) return false;\n if (month < 1 || month > 12) return false;\n if (day < 1 || day > 31) return false;\n const date = new Date(year, month - 1, day);\n return (\n date.getFullYear() === year &&\n date.getMonth() === month - 1 &&\n date.getDate() === day\n );\n },\n { message: \"Invalid date. Must be a valid date from 2010 onwards.\" },\n );\n\nexport const marketSchema = z.enum([\"kospi\", \"kosdaq\", \"konex\", \"krx\"]);\n\nexport type Market = z.infer<typeof marketSchema>;\n\n// eslint-disable-next-line no-control-regex\nconst CONTROL_CHAR_PATTERN = /[\\x00-\\x1f\\x7f]/;\nconst PATH_TRAVERSAL_PATTERN = /\\.\\.[/\\\\]/;\n\nexport function validateNoInjection(input: string): string | null {\n if (CONTROL_CHAR_PATTERN.test(input)) {\n return \"Input contains control characters\";\n }\n if (PATH_TRAVERSAL_PATTERN.test(input)) {\n return \"Input contains path traversal\";\n }\n return null;\n}\n\nexport function validateDate(value: string): string {\n const result = dateSchema.safeParse(value);\n if (!result.success) {\n throw new Error(result.error.issues[0]?.message ?? \"Invalid date\");\n }\n return result.data;\n}\n\nexport function validateMarket(value: string): Market {\n const result = marketSchema.safeParse(value.toLowerCase());\n if (!result.success) {\n throw new Error(\n `Invalid market: ${value}. Must be one of: kospi, kosdaq, konex, krx`,\n );\n }\n return result.data;\n}\n","import type { KrxResponse } from \"../client/client.js\";\nimport { writeError } from \"../output/formatter.js\";\nimport { EXIT_CODES } from \"./index.js\";\n\nexport function handleKrxError(result: KrxResponse): never {\n const exitCode =\n result.errorCode === \"RATE_LIMIT\"\n ? EXIT_CODES.RATE_LIMIT\n : result.errorCode === \"401\"\n ? EXIT_CODES.SERVICE_NOT_APPROVED\n : EXIT_CODES.GENERAL_ERROR;\n\n writeError(result.error ?? \"Unknown error\");\n process.exit(exitCode);\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst MARKET_ENDPOINTS: Record<string, string> = {\n kospi: \"/svc/apis/idx/kospi_dd_trd\",\n kosdaq: \"/svc/apis/idx/kosdaq_dd_trd\",\n krx: \"/svc/apis/idx/krx_dd_trd\",\n bond: \"/svc/apis/idx/bon_dd_trd\",\n derivative: \"/svc/apis/idx/drvprod_dd_trd\",\n};\n\nexport function registerIndexCommand(program: Command): void {\n const index = program.command(\"index\").description(\"Query KRX index data\");\n\n index\n .command(\"list\")\n .description(\"List index daily trading data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\n \"--market <market>\",\n \"market: kospi, kosdaq, krx, bond, derivative\",\n \"kospi\",\n )\n .action(async (opts: { date: string; market: string }) => {\n try {\n const date = validateDate(opts.date);\n const market = opts.market.toLowerCase();\n\n const endpoint = MARKET_ENDPOINTS[market];\n if (!endpoint) {\n writeError(\n `Invalid market: ${market}. Must be one of: ${Object.keys(MARKET_ENDPOINTS).join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate, validateMarket } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst TRADING_ENDPOINTS: Record<string, string> = {\n kospi: \"/svc/apis/sto/stk_bydd_trd\",\n kosdaq: \"/svc/apis/sto/ksq_bydd_trd\",\n konex: \"/svc/apis/sto/knx_bydd_trd\",\n};\n\nconst INFO_ENDPOINTS: Record<string, string> = {\n kospi: \"/svc/apis/sto/stk_isu_base_info\",\n kosdaq: \"/svc/apis/sto/ksq_isu_base_info\",\n konex: \"/svc/apis/sto/knx_isu_base_info\",\n};\n\nexport function registerStockCommand(program: Command): void {\n const stock = program.command(\"stock\").description(\"Query KRX stock data\");\n\n stock\n .command(\"list\")\n .description(\"List stock daily trading data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\"--market <market>\", \"market: kospi, kosdaq, konex\", \"kospi\")\n .action(async (opts: { date: string; market: string }) => {\n try {\n const date = validateDate(opts.date);\n const market = validateMarket(opts.market);\n\n const endpoint = TRADING_ENDPOINTS[market];\n if (!endpoint) {\n writeError(`Invalid market for stock list: ${market}`);\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n\n stock\n .command(\"info\")\n .description(\"List stock base information\")\n .option(\"--market <market>\", \"market: kospi, kosdaq, konex\", \"kospi\")\n .action(async (opts: { market: string }) => {\n try {\n const market = validateMarket(opts.market);\n\n const endpoint = INFO_ENDPOINTS[market];\n if (!endpoint) {\n writeError(`Invalid market for stock info: ${market}`);\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: {},\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: {},\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(\"No data\");\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst TYPE_ENDPOINTS: Record<string, string> = {\n etf: \"/svc/apis/etp/etf_bydd_trd\",\n etn: \"/svc/apis/etp/etn_bydd_trd\",\n elw: \"/svc/apis/etp/elw_bydd_trd\",\n};\n\nexport function registerEtpCommand(program: Command): void {\n const etp = program\n .command(\"etp\")\n .description(\"Query KRX ETP data (ETF/ETN/ELW)\");\n\n etp\n .command(\"list\")\n .description(\"List ETP daily trading data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\"--type <type>\", \"type: etf, etn, elw\", \"etf\")\n .action(async (opts: { date: string; type: string }) => {\n try {\n const date = validateDate(opts.date);\n const type = opts.type.toLowerCase();\n\n const endpoint = TYPE_ENDPOINTS[type];\n if (!endpoint) {\n writeError(\n `Invalid type: ${type}. Must be one of: ${Object.keys(TYPE_ENDPOINTS).join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst MARKET_ENDPOINTS: Record<string, string> = {\n kts: \"/svc/apis/bon/kts_bydd_trd\",\n general: \"/svc/apis/bon/bnd_bydd_trd\",\n small: \"/svc/apis/bon/smb_bydd_trd\",\n};\n\nexport function registerBondCommand(program: Command): void {\n const bond = program\n .command(\"bond\")\n .description(\"Query KRX bond data\");\n\n bond\n .command(\"list\")\n .description(\"List bond daily trading data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\"--market <market>\", \"market: kts, general, small\", \"general\")\n .action(async (opts: { date: string; market: string }) => {\n try {\n const date = validateDate(opts.date);\n const market = opts.market.toLowerCase();\n\n const endpoint = MARKET_ENDPOINTS[market];\n if (!endpoint) {\n writeError(\n `Invalid market: ${market}. Must be one of: ${Object.keys(MARKET_ENDPOINTS).join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst TYPE_ENDPOINTS: Record<string, string> = {\n futures: \"/svc/apis/drv/fut_bydd_trd\",\n \"futures-kospi\": \"/svc/apis/drv/eqsfu_stk_bydd_trd\",\n \"futures-kosdaq\": \"/svc/apis/drv/eqkfu_ksq_bydd_trd\",\n options: \"/svc/apis/drv/opt_bydd_trd\",\n \"options-kospi\": \"/svc/apis/drv/eqsop_bydd_trd\",\n \"options-kosdaq\": \"/svc/apis/drv/eqkop_bydd_trd\",\n};\n\nexport function registerDerivativeCommand(program: Command): void {\n const derivative = program\n .command(\"derivative\")\n .description(\"Query KRX derivative data\");\n\n derivative\n .command(\"list\")\n .description(\"List derivative daily trading data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\n \"--type <type>\",\n \"type: futures, futures-kospi, futures-kosdaq, options, options-kospi, options-kosdaq\",\n \"futures\",\n )\n .action(async (opts: { date: string; type: string }) => {\n try {\n const date = validateDate(opts.date);\n const type = opts.type.toLowerCase();\n\n const endpoint = TYPE_ENDPOINTS[type];\n if (!endpoint) {\n writeError(\n `Invalid type: ${type}. Must be one of: ${Object.keys(TYPE_ENDPOINTS).join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst TYPE_ENDPOINTS: Record<string, string> = {\n oil: \"/svc/apis/gen/oil_bydd_trd\",\n gold: \"/svc/apis/gen/gold_bydd_trd\",\n emission: \"/svc/apis/gen/ets_bydd_trd\",\n};\n\nexport function registerCommodityCommand(program: Command): void {\n const commodity = program\n .command(\"commodity\")\n .description(\"Query KRX commodity data (oil/gold/emission)\");\n\n commodity\n .command(\"list\")\n .description(\"List commodity daily trading data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\"--type <type>\", \"type: oil, gold, emission\", \"gold\")\n .action(async (opts: { date: string; type: string }) => {\n try {\n const date = validateDate(opts.date);\n const type = opts.type.toLowerCase();\n\n const endpoint = TYPE_ENDPOINTS[type];\n if (!endpoint) {\n writeError(\n `Invalid type: ${type}. Must be one of: ${Object.keys(TYPE_ENDPOINTS).join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { getApiKey } from \"../../client/auth.js\";\nimport { krxFetch } from \"../../client/client.js\";\nimport { validateDate } from \"../../validator/index.js\";\nimport {\n writeOutput,\n writeError,\n formatOutput,\n detectOutputFormat,\n} from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\nimport { handleKrxError } from \"../error-handler.js\";\n\nconst TYPE_ENDPOINTS: Record<string, string> = {\n \"sri-bond\": \"/svc/apis/esg/sri_bond_info\",\n etp: \"/svc/apis/esg/esg_etp_info\",\n index: \"/svc/apis/esg/esg_index_info\",\n};\n\nexport function registerEsgCommand(program: Command): void {\n const esg = program\n .command(\"esg\")\n .description(\"Query KRX ESG data\");\n\n esg\n .command(\"list\")\n .description(\"List ESG data\")\n .requiredOption(\"--date <date>\", \"trading date (YYYYMMDD)\")\n .option(\"--type <type>\", \"type: sri-bond, etp, index\", \"index\")\n .action(async (opts: { date: string; type: string }) => {\n try {\n const date = validateDate(opts.date);\n const type = opts.type.toLowerCase();\n\n const endpoint = TYPE_ENDPOINTS[type];\n if (!endpoint) {\n writeError(\n `Invalid type: ${type}. Must be one of: ${Object.keys(TYPE_ENDPOINTS).join(\", \")}`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n const apiKey = getApiKey();\n if (!apiKey) {\n writeError(\n \"No API key configured. Use 'krx auth set <key>' or set KRX_API_KEY env var.\",\n );\n process.exit(EXIT_CODES.AUTH_FAILURE);\n }\n\n const parentOpts = program.opts();\n if (parentOpts.dryRun) {\n writeOutput(\n JSON.stringify(\n {\n method: \"POST\",\n endpoint,\n params: { basDd: date },\n headers: { AUTH_KEY: \"***\" },\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const result = await krxFetch({\n endpoint,\n params: { basDd: date },\n apiKey,\n });\n\n if (!result.success) {\n handleKrxError(result);\n }\n\n if (result.data.length === 0) {\n writeError(`No data for date ${date}`);\n process.exit(EXIT_CODES.NO_DATA);\n }\n\n const format = detectOutputFormat(parentOpts.output);\n const fields = parentOpts.fields?.split(\",\");\n writeOutput(\n formatOutput(\n result.data as unknown as Record<string, unknown>[],\n format,\n fields,\n ),\n );\n } catch (err) {\n writeError(err instanceof Error ? err.message : String(err));\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { ENDPOINTS, CATEGORIES } from \"../../client/endpoints.js\";\nimport { writeOutput, writeError } from \"../../output/formatter.js\";\nimport { EXIT_CODES } from \"../index.js\";\n\ninterface SchemaEntry {\n readonly command: string;\n readonly endpoint: string;\n readonly description: string;\n readonly descriptionKo: string;\n readonly category: string;\n readonly params: readonly ParamDef[];\n}\n\ninterface ParamDef {\n readonly name: string;\n readonly type: string;\n readonly required: boolean;\n readonly description: string;\n}\n\nconst COMMON_PARAMS: readonly ParamDef[] = [\n {\n name: \"basDd\",\n type: \"string\",\n required: true,\n description: \"Trading date in YYYYMMDD format\",\n },\n];\n\nfunction buildCommandName(endpoint: string): string {\n const parts = endpoint.replace(\"/svc/apis/\", \"\").split(\"/\");\n const categoryCode = parts[0];\n const apiName = parts[1];\n\n const category = CATEGORIES.find((c) => c.code === categoryCode);\n return `${category?.id ?? categoryCode}.${apiName}`;\n}\n\nfunction getAllSchemas(): readonly SchemaEntry[] {\n return ENDPOINTS.map((ep) => ({\n command: buildCommandName(ep.path),\n endpoint: ep.path,\n description: ep.description,\n descriptionKo: ep.descriptionKo,\n category: ep.category,\n params: [...COMMON_PARAMS],\n }));\n}\n\nexport function registerSchemaCommand(program: Command): void {\n program\n .command(\"schema [command]\")\n .description(\"Show API schema for agent introspection\")\n .option(\"--all\", \"show all schemas\")\n .action((command: string | undefined, opts: { all?: boolean }) => {\n if (opts.all || !command) {\n const schemas = getAllSchemas();\n writeOutput(JSON.stringify(schemas, null, 2));\n return;\n }\n\n const schemas = getAllSchemas();\n const match = schemas.find(\n (s) =>\n s.command === command ||\n s.command.toLowerCase() === command.toLowerCase(),\n );\n\n if (!match) {\n writeError(\n `Unknown command: ${command}. Use 'krx schema --all' to list all.`,\n );\n process.exit(EXIT_CODES.USAGE_ERROR);\n }\n\n writeOutput(JSON.stringify(match, null, 2));\n });\n}\n"],"mappings":"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","names":["fs","path","os","checkRateLimit","incrementCallCount","CONFIG_DIR","program","program","program","program","MARKET_ENDPOINTS","program","TYPE_ENDPOINTS","program","TYPE_ENDPOINTS","program","TYPE_ENDPOINTS","program","program","schemas"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "krx-cli",
3
+ "version": "0.1.0",
4
+ "description": "Agent-native CLI for KRX (Korea Exchange) Open API",
5
+ "type": "module",
6
+ "bin": {
7
+ "krx": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "SKILL.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "dev": "tsup --watch",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "test:coverage": "vitest run --coverage",
19
+ "lint": "eslint src/",
20
+ "format": "prettier --write 'src/**/*.ts' 'tests/**/*.ts'",
21
+ "typecheck": "tsc --noEmit",
22
+ "check": "pnpm lint && pnpm typecheck && pnpm test"
23
+ },
24
+ "keywords": [
25
+ "krx",
26
+ "korea-exchange",
27
+ "stock",
28
+ "finance",
29
+ "cli",
30
+ "agent",
31
+ "ai"
32
+ ],
33
+ "author": "",
34
+ "license": "MIT",
35
+ "packageManager": "pnpm@10.28.0",
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "dependencies": {
40
+ "commander": "^14.0.3",
41
+ "zod": "^4.3.6"
42
+ },
43
+ "devDependencies": {
44
+ "@eslint/js": "^10.0.1",
45
+ "@types/node": "^25.4.0",
46
+ "eslint": "^10.0.3",
47
+ "prettier": "^3.8.1",
48
+ "tsup": "^8.5.1",
49
+ "typescript": "^5.9.3",
50
+ "typescript-eslint": "^8.57.0",
51
+ "vitest": "^4.0.18"
52
+ },
53
+ "pnpm": {
54
+ "onlyBuiltDependencies": [
55
+ "esbuild"
56
+ ]
57
+ }
58
+ }