@bolta-io/cli 0.1.1 → 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.
- package/CHANGELOG.md +6 -0
- package/CLAUDE.md +16 -22
- package/README.md +13 -19
- package/dist/bin/bolta.js +14 -29
- package/dist/bin/bolta.js.map +1 -1
- package/dist/src/client/bolta-client.d.ts +19 -21
- package/dist/src/client/bolta-client.d.ts.map +1 -1
- package/dist/src/client/bolta-client.js +47 -50
- package/dist/src/client/bolta-client.js.map +1 -1
- package/dist/src/commands/cash-receipt/cancel.js +3 -3
- package/dist/src/commands/cash-receipt/cancel.js.map +1 -1
- package/dist/src/commands/cash-receipt/issue.js +3 -3
- package/dist/src/commands/cash-receipt/issue.js.map +1 -1
- package/dist/src/commands/cash-receipt/status.d.ts.map +1 -1
- package/dist/src/commands/cash-receipt/status.js +3 -8
- package/dist/src/commands/cash-receipt/status.js.map +1 -1
- package/dist/src/commands/certificate/index.d.ts.map +1 -1
- package/dist/src/commands/certificate/index.js +19 -42
- package/dist/src/commands/certificate/index.js.map +1 -1
- package/dist/src/commands/config/index.d.ts.map +1 -1
- package/dist/src/commands/config/index.js +17 -54
- package/dist/src/commands/config/index.js.map +1 -1
- package/dist/src/commands/examples/index.d.ts.map +1 -1
- package/dist/src/commands/examples/index.js +8 -9
- package/dist/src/commands/examples/index.js.map +1 -1
- package/dist/src/commands/guide/index.d.ts.map +1 -1
- package/dist/src/commands/guide/index.js +28 -30
- package/dist/src/commands/guide/index.js.map +1 -1
- package/dist/src/commands/invoice/amend.d.ts.map +1 -1
- package/dist/src/commands/invoice/amend.js +9 -30
- package/dist/src/commands/invoice/amend.js.map +1 -1
- package/dist/src/commands/invoice/get.d.ts.map +1 -1
- package/dist/src/commands/invoice/get.js +2 -7
- package/dist/src/commands/invoice/get.js.map +1 -1
- package/dist/src/commands/invoice/index.js +1 -1
- package/dist/src/commands/invoice/issue-request.d.ts.map +1 -1
- package/dist/src/commands/invoice/issue-request.js +3 -15
- package/dist/src/commands/invoice/issue-request.js.map +1 -1
- package/dist/src/commands/invoice/issue.d.ts.map +1 -1
- package/dist/src/commands/invoice/issue.js +3 -15
- package/dist/src/commands/invoice/issue.js.map +1 -1
- package/dist/src/commands/invoice/status.d.ts.map +1 -1
- package/dist/src/commands/invoice/status.js +2 -7
- package/dist/src/commands/invoice/status.js.map +1 -1
- package/dist/src/commands/issuer/create.d.ts +4 -0
- package/dist/src/commands/issuer/create.d.ts.map +1 -0
- package/dist/src/commands/issuer/create.js +24 -0
- package/dist/src/commands/issuer/create.js.map +1 -0
- package/dist/src/commands/issuer/get.d.ts +3 -0
- package/dist/src/commands/issuer/get.d.ts.map +1 -0
- package/dist/src/commands/issuer/get.js +14 -0
- package/dist/src/commands/issuer/get.js.map +1 -0
- package/dist/src/commands/issuer/index.d.ts +3 -0
- package/dist/src/commands/issuer/index.d.ts.map +1 -0
- package/dist/src/commands/issuer/index.js +31 -0
- package/dist/src/commands/issuer/index.js.map +1 -0
- package/dist/src/commands/schema/index.d.ts.map +1 -1
- package/dist/src/commands/schema/index.js +3 -4
- package/dist/src/commands/schema/index.js.map +1 -1
- package/dist/src/commands/supplier/legacy.d.ts +3 -0
- package/dist/src/commands/supplier/legacy.d.ts.map +1 -0
- package/dist/src/commands/supplier/legacy.js +75 -0
- package/dist/src/commands/supplier/legacy.js.map +1 -0
- package/dist/src/config/config-manager.d.ts +7 -9
- package/dist/src/config/config-manager.d.ts.map +1 -1
- package/dist/src/config/config-manager.js +28 -48
- package/dist/src/config/config-manager.js.map +1 -1
- package/dist/src/types/api.d.ts +40 -7
- package/dist/src/types/api.d.ts.map +1 -1
- package/dist/src/utils/client.d.ts +10 -15
- package/dist/src/utils/client.d.ts.map +1 -1
- package/dist/src/utils/client.js +26 -8
- package/dist/src/utils/client.js.map +1 -1
- package/dist/src/utils/legacy-issuer.d.ts +28 -0
- package/dist/src/utils/legacy-issuer.d.ts.map +1 -0
- package/dist/src/utils/legacy-issuer.js +45 -0
- package/dist/src/utils/legacy-issuer.js.map +1 -0
- package/dist/src/utils/output.d.ts +7 -3
- package/dist/src/utils/output.d.ts.map +1 -1
- package/dist/src/utils/output.js +14 -4
- package/dist/src/utils/output.js.map +1 -1
- package/dist/src/{commands/cash-receipt/validation.d.ts → validators/parse.d.ts} +1 -1
- package/dist/src/validators/parse.d.ts.map +1 -0
- package/dist/src/{commands/cash-receipt/validation.js → validators/parse.js} +2 -2
- package/dist/src/validators/parse.js.map +1 -0
- package/dist/src/validators/schemas.d.ts +1 -1
- package/dist/src/validators/schemas.d.ts.map +1 -1
- package/dist/src/validators/schemas.js +21 -11
- package/dist/src/validators/schemas.js.map +1 -1
- package/llms.txt +26 -33
- package/package.json +1 -1
- package/dist/src/commands/cash-receipt/validation.d.ts.map +0 -1
- package/dist/src/commands/cash-receipt/validation.js.map +0 -1
- package/dist/src/commands/supplier/create.d.ts +0 -4
- package/dist/src/commands/supplier/create.d.ts.map +0 -1
- package/dist/src/commands/supplier/create.js +0 -40
- package/dist/src/commands/supplier/create.js.map +0 -1
- package/dist/src/commands/supplier/get.d.ts +0 -3
- package/dist/src/commands/supplier/get.d.ts.map +0 -1
- package/dist/src/commands/supplier/get.js +0 -19
- package/dist/src/commands/supplier/get.js.map +0 -1
- package/dist/src/commands/supplier/index.d.ts +0 -3
- package/dist/src/commands/supplier/index.d.ts.map +0 -1
- package/dist/src/commands/supplier/index.js +0 -56
- package/dist/src/commands/supplier/index.js.map +0 -1
- package/dist/src/commands/supplier/legacy-customer.d.ts +0 -5
- package/dist/src/commands/supplier/legacy-customer.d.ts.map +0 -1
- package/dist/src/commands/supplier/legacy-customer.js +0 -56
- package/dist/src/commands/supplier/legacy-customer.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @bolta-io/cli
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1570031: 발급자 관리와 인증서 API를 issuer 계약으로 전환하고 발행 기본 인증에서 별도 발급자 키를 제거합니다. 기존 supplier/customer 명령과 키 설정은 2026-12-31까지 숨김 호환으로 유지하며, 레거시 키로 403이 발생하면 설정 출처에 맞는 해제 방법을 안내합니다. `bolta guide issuer`는 CLI가 실제 지원하는 발행 흐름만 안내합니다.
|
|
8
|
+
|
|
3
9
|
## 0.1.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/CLAUDE.md
CHANGED
|
@@ -7,24 +7,20 @@
|
|
|
7
7
|
```bash
|
|
8
8
|
# 인증 설정 (환경변수)
|
|
9
9
|
export BOLTA_API_KEY="test_your_key"
|
|
10
|
-
export BOLTA_SUPPLIER_KEY="SupplierKey_abc123"
|
|
11
10
|
|
|
12
11
|
# 또는 config 명령어로 설정
|
|
13
12
|
bolta config set api-key test_your_key
|
|
14
|
-
bolta config set supplier-key SupplierKey_abc123
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
## 핵심 개념:
|
|
15
|
+
## 핵심 개념: 발급자
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
발급자는 세금계산서나 현금영수증 발행에 사용하는 인증서의 소유자입니다.
|
|
20
18
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- API
|
|
19
|
+
- 등록: `bolta issuer create` 호출 → 응답의 `issuerId`
|
|
20
|
+
- 관리: `issuerId`는 발급자 조회와 인증서 등록·조회·해제에만 사용
|
|
21
|
+
- 발행: API 키로 인증하고 요청 본문의 사업자등록번호로 발급자를 선택
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
> 구 명칭 `customer`(명령어·`--customer-key`·`BOLTA_CUSTOMER_KEY`·`config set customer-key`)는 deprecated이며 당분간 동작합니다(경고 출력).
|
|
23
|
+
일반 정발행과 역발행은 `supplier.identificationNumber`, 현금영수증은 `issuer.businessRegistrationNumber`를 사용합니다.
|
|
28
24
|
|
|
29
25
|
## 요금 안내
|
|
30
26
|
|
|
@@ -38,14 +34,14 @@ Bolta API는 **사전 충전 포인트 차감 방식** 유료 서비스입니다
|
|
|
38
34
|
|
|
39
35
|
### 세금계산서 발행 (가장 일반적인 업무)
|
|
40
36
|
|
|
41
|
-
1.
|
|
37
|
+
1. **발급자 등록** (최초 1회):
|
|
42
38
|
```bash
|
|
43
|
-
bolta
|
|
39
|
+
bolta issuer create --data '{"identificationNumber":"1234567890","organizationName":"주식회사 테스트","representativeName":"홍길동"}'
|
|
44
40
|
```
|
|
45
41
|
|
|
46
42
|
2. **인증서 확인** (정발행 시 공급자 인증서 필요):
|
|
47
43
|
```bash
|
|
48
|
-
bolta certificate status
|
|
44
|
+
bolta certificate status <issuerId>
|
|
49
45
|
```
|
|
50
46
|
|
|
51
47
|
3. **세금계산서 정발행**:
|
|
@@ -58,7 +54,7 @@ bolta invoice issue --data '{
|
|
|
58
54
|
"identificationNumber": "1234567890",
|
|
59
55
|
"organizationName": "공급자",
|
|
60
56
|
"representativeName": "김공급",
|
|
61
|
-
"manager": {"email": "
|
|
57
|
+
"manager": {"email": "seller@example.com"}
|
|
62
58
|
},
|
|
63
59
|
"supplied": {
|
|
64
60
|
"identificationNumber": "0987654321",
|
|
@@ -106,11 +102,11 @@ bolta cash-receipt status --reference-id cash-2026-001
|
|
|
106
102
|
|
|
107
103
|
| 커맨드 | 설명 | 데이터 필요 |
|
|
108
104
|
|--------|------|------------|
|
|
109
|
-
| `bolta
|
|
110
|
-
| `bolta
|
|
111
|
-
| `bolta certificate url <
|
|
112
|
-
| `bolta certificate status <
|
|
113
|
-
| `bolta certificate deregister <
|
|
105
|
+
| `bolta issuer create` | 발급자 등록 | --data |
|
|
106
|
+
| `bolta issuer get <issuerId>` | 발급자 조회 | - |
|
|
107
|
+
| `bolta certificate url <issuerId>` | 인증서 등록 URL | - |
|
|
108
|
+
| `bolta certificate status <issuerId>` | 인증서 상태 | - |
|
|
109
|
+
| `bolta certificate deregister <issuerId>` | 인증서 해제 | - |
|
|
114
110
|
| `bolta invoice issue` | 세금계산서 정발행 | --data |
|
|
115
111
|
| `bolta invoice issue-request` | 역발행 요청 | --data |
|
|
116
112
|
| `bolta invoice get <issuanceKey>` | 세금계산서 조회 | - |
|
|
@@ -128,8 +124,6 @@ bolta cash-receipt status --reference-id cash-2026-001
|
|
|
128
124
|
| `bolta schema [command]` | 입력 스키마 | - |
|
|
129
125
|
| `bolta guide [topic]` | 주요 개념 안내 | - |
|
|
130
126
|
|
|
131
|
-
> 인증서 명령의 `<key>`에는 신규 supplierKey를 쓰세요. deprecated `CustomerKey_` 키도 당분간 동작합니다.
|
|
132
|
-
|
|
133
127
|
## 입력 방법
|
|
134
128
|
|
|
135
129
|
데이터가 필요한 커맨드에서 3가지 방식 지원:
|
|
@@ -154,7 +148,7 @@ bolta cash-receipt status --reference-id cash-2026-001
|
|
|
154
148
|
| `INPUT_ERROR` | 명령어·옵션·입력 방식 오류 | `bolta --help` 또는 하위 명령의 `--help`로 사용법 확인 |
|
|
155
149
|
| `HTTP_402` | 포인트 잔액 부족 | https://developers.bolta.io 에서 포인트 충전 |
|
|
156
150
|
| `HTTP_400` | 잘못된 요청 | error.message 확인, 필수 필드 누락 체크 |
|
|
157
|
-
| `HTTP_404` | 리소스 없음 | issuanceKey/
|
|
151
|
+
| `HTTP_404` | 리소스 없음 | issuanceKey/issuerId 확인 |
|
|
158
152
|
| `HTTP_429` | 요청 제한 초과 | 자동 재시도 (최대 3회) |
|
|
159
153
|
| `NETWORK_ERROR` | 네트워크 오류 | 인터넷 연결 확인 |
|
|
160
154
|
|
package/README.md
CHANGED
|
@@ -35,11 +35,9 @@ Bolta API를 사용하려면 API 키가 필요합니다. 환경변수 또는 CLI
|
|
|
35
35
|
```bash
|
|
36
36
|
# 방법 1: 환경변수 (권장)
|
|
37
37
|
export BOLTA_API_KEY="test_your_key"
|
|
38
|
-
export BOLTA_SUPPLIER_KEY="SupplierKey_abc123"
|
|
39
38
|
|
|
40
39
|
# 방법 2: CLI 명령 (영구 저장 - ~/.bolta/config.json)
|
|
41
40
|
bolta config set api-key test_your_key
|
|
42
|
-
bolta config set supplier-key SupplierKey_abc123
|
|
43
41
|
|
|
44
42
|
# 연결 테스트
|
|
45
43
|
bolta config test
|
|
@@ -49,36 +47,34 @@ bolta config test
|
|
|
49
47
|
|
|
50
48
|
### 커맨드 전체 목록
|
|
51
49
|
|
|
52
|
-
####
|
|
50
|
+
#### 발급자 관리
|
|
53
51
|
|
|
54
52
|
```bash
|
|
55
|
-
#
|
|
56
|
-
bolta
|
|
53
|
+
# 발급자 등록
|
|
54
|
+
bolta issuer create --data '{
|
|
57
55
|
"identificationNumber": "1234567890",
|
|
58
56
|
"organizationName": "주식회사 테스트",
|
|
59
57
|
"representativeName": "홍길동"
|
|
60
58
|
}'
|
|
61
59
|
|
|
62
|
-
#
|
|
63
|
-
bolta
|
|
60
|
+
# 발급자 조회
|
|
61
|
+
bolta issuer get <issuerId>
|
|
64
62
|
```
|
|
65
63
|
|
|
66
|
-
> 구 `customer` 명령(`bolta customer ...`)은 deprecated이며 당분간 동작합니다(경고 출력).
|
|
67
|
-
|
|
68
64
|
#### 인증서 관리
|
|
69
65
|
|
|
70
66
|
```bash
|
|
71
67
|
# 인증서 등록 URL 조회
|
|
72
|
-
bolta certificate url <
|
|
68
|
+
bolta certificate url <issuerId>
|
|
73
69
|
|
|
74
70
|
# 인증서 등록 상태 조회
|
|
75
|
-
bolta certificate status <
|
|
71
|
+
bolta certificate status <issuerId>
|
|
76
72
|
|
|
77
73
|
# 인증서 해제
|
|
78
|
-
bolta certificate deregister <
|
|
74
|
+
bolta certificate deregister <issuerId>
|
|
79
75
|
```
|
|
80
76
|
|
|
81
|
-
|
|
77
|
+
`issuerId`는 발급자와 인증서 관리에만 사용합니다. 발행 요청은 본문의 사업자등록번호로 발급자를 찾습니다.
|
|
82
78
|
|
|
83
79
|
#### 세금계산서 발행/조회
|
|
84
80
|
|
|
@@ -92,7 +88,7 @@ bolta invoice issue --data '{
|
|
|
92
88
|
"identificationNumber": "1234567890",
|
|
93
89
|
"organizationName": "공급자 주식회사",
|
|
94
90
|
"representativeName": "김공급",
|
|
95
|
-
"manager": { "email": "
|
|
91
|
+
"manager": { "email": "seller@example.com" }
|
|
96
92
|
},
|
|
97
93
|
"supplied": {
|
|
98
94
|
"identificationNumber": "0987654321",
|
|
@@ -185,7 +181,7 @@ bolta cash-receipt status --reference-id cash-2026-001-cancel
|
|
|
185
181
|
#### 설정
|
|
186
182
|
|
|
187
183
|
```bash
|
|
188
|
-
bolta config set <key> <value> # api-key,
|
|
184
|
+
bolta config set <key> <value> # api-key, base-url, update-check
|
|
189
185
|
bolta config show # 현재 설정 확인
|
|
190
186
|
bolta config test # API 연결 테스트
|
|
191
187
|
```
|
|
@@ -193,7 +189,7 @@ bolta config test # API 연결 테스트
|
|
|
193
189
|
#### 도움말
|
|
194
190
|
|
|
195
191
|
```bash
|
|
196
|
-
# 주요 개념 안내 (
|
|
192
|
+
# 주요 개념 안내 (issuer, payment, workflow, cash-receipt, glossary)
|
|
197
193
|
bolta guide [topic]
|
|
198
194
|
|
|
199
195
|
# 바로 쓸 수 있는 샘플 JSON
|
|
@@ -237,8 +233,6 @@ cat invoice.json | bolta invoice issue --stdin
|
|
|
237
233
|
| 옵션 | 설명 |
|
|
238
234
|
|------|------|
|
|
239
235
|
| `--api-key <key>` | API 키 오버라이드 |
|
|
240
|
-
| `--supplier-key <key>` | Supplier Key 오버라이드 |
|
|
241
|
-
| `--customer-key <key>` | (deprecated) `--supplier-key`를 사용하세요 |
|
|
242
236
|
| `--verbose` | 상세 로그 출력 (stderr) |
|
|
243
237
|
| `--dry-run` | API 호출 없이 요청 데이터만 출력 |
|
|
244
238
|
|
|
@@ -263,7 +257,7 @@ cat invoice.json | bolta invoice issue --stdin
|
|
|
263
257
|
| `INPUT_ERROR` | 명령어·옵션·입력 방식 오류 | `bolta --help` 또는 하위 명령의 `--help`로 사용법 확인 |
|
|
264
258
|
| `HTTP_402` | 포인트 잔액 부족 | https://developers.bolta.io 에서 포인트 충전 |
|
|
265
259
|
| `HTTP_400` | 잘못된 요청 | error.message 확인 |
|
|
266
|
-
| `HTTP_404` | 리소스 없음 | issuanceKey/
|
|
260
|
+
| `HTTP_404` | 리소스 없음 | issuanceKey/issuerId 확인 |
|
|
267
261
|
| `HTTP_429` | 요청 제한 초과 | 자동 재시도 (최대 3회) |
|
|
268
262
|
| `NETWORK_ERROR` | 네트워크 오류 | 인터넷 연결 확인 |
|
|
269
263
|
|
package/dist/bin/bolta.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command, CommanderError } from 'commander';
|
|
3
|
-
import {
|
|
2
|
+
import { Command, CommanderError, Option } from 'commander';
|
|
3
|
+
import { registerIssuerCommands } from '../src/commands/issuer/index.js';
|
|
4
|
+
import { registerLegacyIssuerCommands } from '../src/commands/supplier/legacy.js';
|
|
4
5
|
import { registerCertificateCommands } from '../src/commands/certificate/index.js';
|
|
5
6
|
import { registerInvoiceCommands } from '../src/commands/invoice/index.js';
|
|
6
7
|
import { registerConfigCommands } from '../src/commands/config/index.js';
|
|
@@ -10,7 +11,7 @@ import { registerUpdateCommands } from '../src/commands/update/index.js';
|
|
|
10
11
|
import { maybeNudgeUpdate, refreshUpdateCache, UPDATE_CACHE_COMMAND, } from '../src/commands/update/nudge.js';
|
|
11
12
|
import { registerGuideCommand } from '../src/commands/guide/index.js';
|
|
12
13
|
import { registerCashReceiptCommands } from '../src/commands/cash-receipt/index.js';
|
|
13
|
-
import {
|
|
14
|
+
import { legacyIssuerWarning, outputError } from '../src/utils/output.js';
|
|
14
15
|
import { BoltaInputError } from '../src/utils/errors.js';
|
|
15
16
|
import { getCurrentVersion } from '../src/utils/version.js';
|
|
16
17
|
import { loadConfig, saveConfig } from '../src/config/config-manager.js';
|
|
@@ -25,24 +26,30 @@ program
|
|
|
25
26
|
.description('Bolta API CLI - 전자세금계산서·현금영수증 발행/조회/관리 도구 (AI 에이전트 최적화)')
|
|
26
27
|
.version(getCurrentVersion())
|
|
27
28
|
.option('--api-key <key>', 'Bolta API 키 (환경변수 BOLTA_API_KEY 대체)')
|
|
28
|
-
.
|
|
29
|
-
.
|
|
29
|
+
.addOption(new Option('--supplier-key <key>').hideHelp())
|
|
30
|
+
.addOption(new Option('--customer-key <key>').hideHelp())
|
|
30
31
|
.option('--verbose', '상세 로그 출력 (stderr)', false)
|
|
31
32
|
.option('--dry-run', 'API 호출 없이 요청 데이터만 출력', false)
|
|
32
33
|
.hook('preAction', (thisCommand, actionCommand) => {
|
|
33
34
|
const opts = thisCommand.optsWithGlobals();
|
|
35
|
+
if (opts.supplierKey) {
|
|
36
|
+
legacyIssuerWarning("'--supplier-key' 플래그");
|
|
37
|
+
}
|
|
38
|
+
else if (opts.customerKey) {
|
|
39
|
+
legacyIssuerWarning("'--customer-key' 플래그");
|
|
40
|
+
}
|
|
34
41
|
if (opts.verbose) {
|
|
35
42
|
process.env.BOLTA_VERBOSE = '1';
|
|
36
43
|
}
|
|
37
44
|
// 백그라운드 캐시 갱신 자식 프로세스: 힌트/넛지 없이 본연의 작업만 (재귀 spawn 방지)
|
|
38
45
|
if (actionCommand.name() === UPDATE_CACHE_COMMAND)
|
|
39
46
|
return;
|
|
40
|
-
warnDeprecatedUsage();
|
|
41
47
|
const config = loadConfig();
|
|
42
48
|
checkFirstRun(actionCommand, config);
|
|
43
49
|
checkForUpdate(actionCommand, config);
|
|
44
50
|
});
|
|
45
|
-
|
|
51
|
+
registerIssuerCommands(program);
|
|
52
|
+
registerLegacyIssuerCommands(program);
|
|
46
53
|
registerCertificateCommands(program);
|
|
47
54
|
registerInvoiceCommands(program);
|
|
48
55
|
registerCashReceiptCommands(program);
|
|
@@ -51,28 +58,6 @@ registerExamplesCommand(program);
|
|
|
51
58
|
registerSchemaCommand(program);
|
|
52
59
|
registerUpdateCommands(program);
|
|
53
60
|
registerGuideCommand(program);
|
|
54
|
-
// 값을 받는 전역 옵션(공백 구분 형태일 때 다음 토큰을 값으로 소비)
|
|
55
|
-
const GLOBAL_VALUE_OPTIONS = new Set(['--api-key', '--supplier-key', '--customer-key']);
|
|
56
|
-
function warnDeprecatedUsage() {
|
|
57
|
-
// 구 명령어 'customer'를 alias로 사용한 경우 경고.
|
|
58
|
-
// 첫 번째 위치 인자(=명령어)만 검사해 데이터 값에 'customer'가 들어가도 오탐하지 않는다.
|
|
59
|
-
// (--customer-key 플래그/BOLTA_CUSTOMER_KEY/config customer-key는 resolveSupplierKey에서 경고)
|
|
60
|
-
const argv = process.argv.slice(2);
|
|
61
|
-
for (let i = 0; i < argv.length; i++) {
|
|
62
|
-
const token = argv[i];
|
|
63
|
-
if (GLOBAL_VALUE_OPTIONS.has(token)) {
|
|
64
|
-
i++; // 옵션 값 건너뛰기
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (token.startsWith('-'))
|
|
68
|
-
continue; // boolean 플래그(--verbose 등)
|
|
69
|
-
// 첫 위치 인자 = 명령어
|
|
70
|
-
if (token === 'customer') {
|
|
71
|
-
deprecationWarning("'customer' 명령어는 'supplier'로 변경되었습니다. 'bolta supplier ...'를 사용하세요.");
|
|
72
|
-
}
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
61
|
function checkFirstRun(actionCommand, config) {
|
|
77
62
|
const commandName = actionCommand.name();
|
|
78
63
|
const parentName = actionCommand.parent?.name();
|
package/dist/bin/bolta.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bolta.js","sourceRoot":"","sources":["../../bin/bolta.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"bolta.js","sourceRoot":"","sources":["../../bin/bolta.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,53 +1,51 @@
|
|
|
1
|
-
import type { CreateTaxInvoiceRequest, IssuanceResponse, TaxInvoiceDetail, StatusResponse, AmendTerminationRequest, AmendChangeSupplyCostRequest, CreateSupplierRequest,
|
|
1
|
+
import type { CreateTaxInvoiceRequest, IssuanceResponse, TaxInvoiceDetail, StatusResponse, AmendTerminationRequest, AmendChangeSupplyCostRequest, CreateIssuerRequest, IssuerResponse, CreateSupplierRequest, LegacySupplierResponse, CreateCustomerRequest, LegacyCustomerResponse, CertificateUrlResponse, CertificateStatusResponse, CreateCashReceiptRequest, CashReceiptCancellationResponse, CashReceiptStatusResponse } from '../types/api.js';
|
|
2
|
+
import { type LegacyIssuerHeader } from '../utils/legacy-issuer.js';
|
|
2
3
|
interface ClientConfig {
|
|
3
4
|
apiKey: string;
|
|
4
5
|
baseUrl: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
supplierKeySource?: string;
|
|
6
|
+
/** 구 설정이 남아 있을 때만 지정한다. 지정하면 Supplier-Key 헤더를 싣는다. */
|
|
7
|
+
legacyIssuer?: LegacyIssuerHeader;
|
|
8
8
|
timeout?: number;
|
|
9
9
|
maxRetries?: number;
|
|
10
10
|
}
|
|
11
11
|
export declare class BoltaClient {
|
|
12
12
|
private readonly baseUrl;
|
|
13
13
|
private readonly encodedApiKey;
|
|
14
|
-
private readonly
|
|
15
|
-
private readonly supplierKeySource;
|
|
14
|
+
private readonly legacyIssuer?;
|
|
16
15
|
private readonly timeout;
|
|
17
16
|
private readonly maxRetries;
|
|
18
17
|
constructor(config: ClientConfig);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/** @deprecated
|
|
18
|
+
createIssuer(data: CreateIssuerRequest): Promise<IssuerResponse>;
|
|
19
|
+
getIssuer(issuerId: string): Promise<IssuerResponse>;
|
|
20
|
+
/** @deprecated 2026-12-31까지 숨김 `supplier` CLI 호환용입니다. */
|
|
21
|
+
createSupplier(data: CreateSupplierRequest): Promise<LegacySupplierResponse>;
|
|
22
|
+
/** @deprecated 2026-12-31까지 숨김 `supplier` CLI 호환용입니다. */
|
|
23
|
+
getSupplier(supplierKey: string): Promise<LegacySupplierResponse>;
|
|
24
|
+
/** @deprecated 2026-12-31까지 숨김 `customer` CLI 호환용입니다. */
|
|
22
25
|
createCustomer(data: CreateCustomerRequest): Promise<LegacyCustomerResponse>;
|
|
23
|
-
/** @deprecated
|
|
26
|
+
/** @deprecated 2026-12-31까지 숨김 `customer` CLI 호환용입니다. */
|
|
24
27
|
getCustomer(customerKey: string): Promise<LegacyCustomerResponse>;
|
|
25
|
-
getCertificateUrl(
|
|
26
|
-
getCertificateStatus(
|
|
27
|
-
deregisterCertificate(
|
|
28
|
+
getCertificateUrl(issuerId: string): Promise<CertificateUrlResponse>;
|
|
29
|
+
getCertificateStatus(issuerId: string): Promise<CertificateStatusResponse>;
|
|
30
|
+
deregisterCertificate(issuerId: string): Promise<unknown>;
|
|
28
31
|
issueTaxInvoice(data: CreateTaxInvoiceRequest, options?: {
|
|
29
|
-
supplierKey?: string;
|
|
30
32
|
referenceId?: string;
|
|
31
33
|
}): Promise<IssuanceResponse>;
|
|
32
34
|
issueRequestTaxInvoice(data: CreateTaxInvoiceRequest, options?: {
|
|
33
|
-
supplierKey?: string;
|
|
34
35
|
referenceId?: string;
|
|
35
36
|
}): Promise<IssuanceResponse>;
|
|
36
37
|
getTaxInvoice(issuanceKey: string): Promise<TaxInvoiceDetail>;
|
|
37
38
|
getTaxInvoiceStatus(clientReferenceId: string): Promise<StatusResponse>;
|
|
38
|
-
amendTermination(issuanceKey: string, data: AmendTerminationRequest
|
|
39
|
-
amendChangeSupplyCost(issuanceKey: string, data: AmendChangeSupplyCostRequest
|
|
40
|
-
amendDoubleIssuance(issuanceKey: string
|
|
39
|
+
amendTermination(issuanceKey: string, data: AmendTerminationRequest): Promise<IssuanceResponse>;
|
|
40
|
+
amendChangeSupplyCost(issuanceKey: string, data: AmendChangeSupplyCostRequest): Promise<IssuanceResponse>;
|
|
41
|
+
amendDoubleIssuance(issuanceKey: string): Promise<IssuanceResponse>;
|
|
41
42
|
issueCashReceipt(data: CreateCashReceiptRequest, options: {
|
|
42
|
-
supplierKey: string;
|
|
43
43
|
referenceId: string;
|
|
44
44
|
}): Promise<IssuanceResponse>;
|
|
45
45
|
getCashReceiptStatus(clientReferenceId: string): Promise<CashReceiptStatusResponse>;
|
|
46
46
|
cancelCashReceipt(issuanceKey: string, options: {
|
|
47
|
-
supplierKey: string;
|
|
48
47
|
referenceId: string;
|
|
49
48
|
}): Promise<CashReceiptCancellationResponse>;
|
|
50
|
-
private certificatePath;
|
|
51
49
|
private request;
|
|
52
50
|
}
|
|
53
51
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bolta-client.d.ts","sourceRoot":"","sources":["../../../src/client/bolta-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,4BAA4B,EAC5B,qBAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"bolta-client.d.ts","sourceRoot":"","sources":["../../../src/client/bolta-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,4BAA4B,EAC5B,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,+BAA+B,EAC/B,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,MAAM,EAAE,YAAY;IAgB1B,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAIhE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAQ1D,yDAAyD;IACnD,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAIlF,yDAAyD;IACnD,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAOvE,yDAAyD;IACnD,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAIlF,yDAAyD;IACnD,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAWjE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAOpE,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAO1E,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWzD,eAAe,CACnB,IAAI,EAAE,uBAAuB,EAC7B,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACjC,OAAO,CAAC,gBAAgB,CAAC;IAStB,sBAAsB,CAC1B,IAAI,EAAE,uBAAuB,EAC7B,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACjC,OAAO,CAAC,gBAAgB,CAAC;IAStB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO7D,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOvE,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,gBAAgB,CAAC;IAQtB,qBAAqB,CACzB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,gBAAgB,CAAC;IAQtB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWnE,gBAAgB,CACpB,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAC/B,OAAO,CAAC,gBAAgB,CAAC;IAStB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAOnF,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAC/B,OAAO,CAAC,+BAA+B,CAAC;YAY7B,OAAO;CA2HtB"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { BoltaApiError, BoltaAuthError, BoltaNetworkError } from '../utils/errors.js';
|
|
2
|
-
import {
|
|
2
|
+
import { verbose, maskSecret } from '../utils/output.js';
|
|
3
3
|
import { getCurrentVersion } from '../utils/version.js';
|
|
4
|
-
|
|
4
|
+
import { describeLegacyIssuerKeySource, } from '../utils/legacy-issuer.js';
|
|
5
5
|
export class BoltaClient {
|
|
6
6
|
baseUrl;
|
|
7
7
|
encodedApiKey;
|
|
8
|
-
|
|
9
|
-
supplierKeySource;
|
|
8
|
+
legacyIssuer;
|
|
10
9
|
timeout;
|
|
11
10
|
maxRetries;
|
|
12
11
|
constructor(config) {
|
|
@@ -15,28 +14,38 @@ export class BoltaClient {
|
|
|
15
14
|
}
|
|
16
15
|
this.baseUrl = config.baseUrl.replace(/\/+$/, '');
|
|
17
16
|
this.encodedApiKey = Buffer.from(`${config.apiKey}:`).toString('base64');
|
|
18
|
-
this.
|
|
19
|
-
this.supplierKeySource = config.supplierKeySource ?? 'unknown';
|
|
17
|
+
this.legacyIssuer = config.legacyIssuer;
|
|
20
18
|
this.timeout = config.timeout ?? 30_000;
|
|
21
19
|
this.maxRetries = config.maxRetries ?? 3;
|
|
22
20
|
}
|
|
23
21
|
// ========================
|
|
24
|
-
//
|
|
22
|
+
// Issuer Methods
|
|
25
23
|
// ========================
|
|
24
|
+
async createIssuer(data) {
|
|
25
|
+
return this.request({ method: 'POST', path: '/issuers', body: data });
|
|
26
|
+
}
|
|
27
|
+
async getIssuer(issuerId) {
|
|
28
|
+
return this.request({ method: 'GET', path: `/issuers/${encodeURIComponent(issuerId)}` });
|
|
29
|
+
}
|
|
30
|
+
// ========================
|
|
31
|
+
// Legacy Issuer Methods
|
|
32
|
+
// ========================
|
|
33
|
+
/** @deprecated 2026-12-31까지 숨김 `supplier` CLI 호환용입니다. */
|
|
26
34
|
async createSupplier(data) {
|
|
27
35
|
return this.request({ method: 'POST', path: '/suppliers', body: data });
|
|
28
36
|
}
|
|
37
|
+
/** @deprecated 2026-12-31까지 숨김 `supplier` CLI 호환용입니다. */
|
|
29
38
|
async getSupplier(supplierKey) {
|
|
30
|
-
return this.request({
|
|
39
|
+
return this.request({
|
|
40
|
+
method: 'GET',
|
|
41
|
+
path: `/suppliers/${encodeURIComponent(supplierKey)}`,
|
|
42
|
+
});
|
|
31
43
|
}
|
|
32
|
-
|
|
33
|
-
// Legacy Customer Methods
|
|
34
|
-
// ========================
|
|
35
|
-
/** @deprecated 신규 코드에서는 createSupplier를 사용하세요. */
|
|
44
|
+
/** @deprecated 2026-12-31까지 숨김 `customer` CLI 호환용입니다. */
|
|
36
45
|
async createCustomer(data) {
|
|
37
46
|
return this.request({ method: 'POST', path: '/customers', body: data });
|
|
38
47
|
}
|
|
39
|
-
/** @deprecated
|
|
48
|
+
/** @deprecated 2026-12-31까지 숨김 `customer` CLI 호환용입니다. */
|
|
40
49
|
async getCustomer(customerKey) {
|
|
41
50
|
return this.request({
|
|
42
51
|
method: 'GET',
|
|
@@ -46,22 +55,22 @@ export class BoltaClient {
|
|
|
46
55
|
// ========================
|
|
47
56
|
// Certificate Methods
|
|
48
57
|
// ========================
|
|
49
|
-
async getCertificateUrl(
|
|
58
|
+
async getCertificateUrl(issuerId) {
|
|
50
59
|
return this.request({
|
|
51
60
|
method: 'GET',
|
|
52
|
-
path:
|
|
61
|
+
path: `/issuers/${encodeURIComponent(issuerId)}/certificates/url`,
|
|
53
62
|
});
|
|
54
63
|
}
|
|
55
|
-
async getCertificateStatus(
|
|
64
|
+
async getCertificateStatus(issuerId) {
|
|
56
65
|
return this.request({
|
|
57
66
|
method: 'GET',
|
|
58
|
-
path:
|
|
67
|
+
path: `/issuers/${encodeURIComponent(issuerId)}/certificates/latestHistory`,
|
|
59
68
|
});
|
|
60
69
|
}
|
|
61
|
-
async deregisterCertificate(
|
|
70
|
+
async deregisterCertificate(issuerId) {
|
|
62
71
|
return this.request({
|
|
63
72
|
method: 'DELETE',
|
|
64
|
-
path:
|
|
73
|
+
path: `/issuers/${encodeURIComponent(issuerId)}/certificates`,
|
|
65
74
|
});
|
|
66
75
|
}
|
|
67
76
|
// ========================
|
|
@@ -72,7 +81,6 @@ export class BoltaClient {
|
|
|
72
81
|
method: 'POST',
|
|
73
82
|
path: '/taxInvoices/issue',
|
|
74
83
|
body: data,
|
|
75
|
-
supplierKey: options?.supplierKey,
|
|
76
84
|
referenceId: options?.referenceId,
|
|
77
85
|
});
|
|
78
86
|
}
|
|
@@ -81,7 +89,6 @@ export class BoltaClient {
|
|
|
81
89
|
method: 'POST',
|
|
82
90
|
path: '/taxInvoices/issueRequest',
|
|
83
91
|
body: data,
|
|
84
|
-
supplierKey: options?.supplierKey,
|
|
85
92
|
referenceId: options?.referenceId,
|
|
86
93
|
});
|
|
87
94
|
}
|
|
@@ -97,27 +104,24 @@ export class BoltaClient {
|
|
|
97
104
|
path: `/taxInvoices/issue/status?clientReferenceId=${encodeURIComponent(clientReferenceId)}`,
|
|
98
105
|
});
|
|
99
106
|
}
|
|
100
|
-
async amendTermination(issuanceKey, data
|
|
107
|
+
async amendTermination(issuanceKey, data) {
|
|
101
108
|
return this.request({
|
|
102
109
|
method: 'POST',
|
|
103
110
|
path: `/taxInvoices/${encodeURIComponent(issuanceKey)}/amend/termination`,
|
|
104
111
|
body: data,
|
|
105
|
-
supplierKey,
|
|
106
112
|
});
|
|
107
113
|
}
|
|
108
|
-
async amendChangeSupplyCost(issuanceKey, data
|
|
114
|
+
async amendChangeSupplyCost(issuanceKey, data) {
|
|
109
115
|
return this.request({
|
|
110
116
|
method: 'POST',
|
|
111
117
|
path: `/taxInvoices/${encodeURIComponent(issuanceKey)}/amend/changeSupplyCost`,
|
|
112
118
|
body: data,
|
|
113
|
-
supplierKey,
|
|
114
119
|
});
|
|
115
120
|
}
|
|
116
|
-
async amendDoubleIssuance(issuanceKey
|
|
121
|
+
async amendDoubleIssuance(issuanceKey) {
|
|
117
122
|
return this.request({
|
|
118
123
|
method: 'POST',
|
|
119
124
|
path: `/taxInvoices/${encodeURIComponent(issuanceKey)}/amend/doubleIssuance`,
|
|
120
|
-
supplierKey,
|
|
121
125
|
});
|
|
122
126
|
}
|
|
123
127
|
// ========================
|
|
@@ -128,7 +132,6 @@ export class BoltaClient {
|
|
|
128
132
|
method: 'POST',
|
|
129
133
|
path: '/cashReceipts',
|
|
130
134
|
body: data,
|
|
131
|
-
supplierKey: options.supplierKey,
|
|
132
135
|
referenceId: options.referenceId,
|
|
133
136
|
});
|
|
134
137
|
}
|
|
@@ -142,19 +145,12 @@ export class BoltaClient {
|
|
|
142
145
|
return this.request({
|
|
143
146
|
method: 'POST',
|
|
144
147
|
path: `/cashReceipts/${encodeURIComponent(issuanceKey)}/cancellation`,
|
|
145
|
-
supplierKey: options.supplierKey,
|
|
146
148
|
referenceId: options.referenceId,
|
|
147
149
|
});
|
|
148
150
|
}
|
|
149
151
|
// ========================
|
|
150
152
|
// Internal Request Method
|
|
151
153
|
// ========================
|
|
152
|
-
certificatePath(key, suffix = '') {
|
|
153
|
-
if (key.startsWith(DEPRECATED_CUSTOMER_KEY_PREFIX)) {
|
|
154
|
-
deprecationWarning("'CustomerKey_' 키는 deprecated입니다. 신규 supplierKey를 사용하세요.");
|
|
155
|
-
}
|
|
156
|
-
return `/suppliers/${encodeURIComponent(key)}/certificates${suffix}`;
|
|
157
|
-
}
|
|
158
154
|
async request(options) {
|
|
159
155
|
const url = `${this.baseUrl}${options.path}`;
|
|
160
156
|
const headers = {
|
|
@@ -162,23 +158,22 @@ export class BoltaClient {
|
|
|
162
158
|
'Content-Type': 'application/json',
|
|
163
159
|
'User-Agent': `bolta-cli/${getCurrentVersion()}`,
|
|
164
160
|
};
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
161
|
+
const legacyIssuer = this.legacyIssuer;
|
|
162
|
+
const maskedLegacyIssuerKey = legacyIssuer ? maskSecret(legacyIssuer.key, 8, 4) : undefined;
|
|
163
|
+
if (legacyIssuer) {
|
|
164
|
+
headers['Supplier-Key'] = legacyIssuer.key;
|
|
165
|
+
verbose('레거시 발급자 헤더 사용', {
|
|
166
|
+
legacyIssuerKey: maskedLegacyIssuerKey,
|
|
167
|
+
source: legacyIssuer.source,
|
|
168
|
+
});
|
|
173
169
|
}
|
|
174
170
|
if (options.referenceId) {
|
|
175
171
|
headers['Bolta-Client-Reference-Id'] = options.referenceId;
|
|
176
172
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
? { supplierKey: maskedSupplierKey, supplierKeySource }
|
|
173
|
+
const legacyIssuerDetails = legacyIssuer
|
|
174
|
+
? { legacyIssuerKey: maskedLegacyIssuerKey, source: legacyIssuer.source, legacyHeader: true }
|
|
180
175
|
: undefined;
|
|
181
|
-
const makeApiError = (status, code, message) => new BoltaApiError(message, code, status, getSuggestion(status, code, {
|
|
176
|
+
const makeApiError = (status, code, message) => new BoltaApiError(message, code, status, getSuggestion(status, code, { legacyIssuer }), status === 403 ? legacyIssuerDetails : undefined);
|
|
182
177
|
let lastError = null;
|
|
183
178
|
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
|
|
184
179
|
try {
|
|
@@ -271,9 +266,11 @@ function getSuggestion(status, code, ctx) {
|
|
|
271
266
|
if (status === 402)
|
|
272
267
|
return "포인트 잔액이 부족합니다. Bolta API는 사전 충전 포인트 차감 방식입니다. https://developers.bolta.io 개발자센터에서 포인트를 충전하세요. 'bolta guide payment'로 요금 정보를 확인할 수 있습니다.";
|
|
273
268
|
if (status === 403) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
269
|
+
if (ctx?.legacyIssuer) {
|
|
270
|
+
// 레거시 키를 실어 보낸 요청의 403은 키 ↔ API 키 불일치가 가장 흔한 원인이다.
|
|
271
|
+
// 어느 소스에서 왔는지 이미 알고 있으므로 해제 방법을 그대로 알려준다.
|
|
272
|
+
const { origin, removal, verifyCommand } = describeLegacyIssuerKeySource(ctx.legacyIssuer.source);
|
|
273
|
+
return `이 요청에는 ${origin}에서 온 레거시 Supplier-Key 헤더가 실렸습니다. 해제 방법: ${removal}. 요청 본문의 사업자등록번호로 발급자를 지정하세요. 등록 상태는 '${verifyCommand}'로 확인하세요.`;
|
|
277
274
|
}
|
|
278
275
|
return '해당 작업에 대한 권한이 없습니다. API 키의 권한을 확인하세요.';
|
|
279
276
|
}
|