deliveryapi 0.2.2 → 1.0.1
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/dist/index.cjs +381 -278
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +943 -411
- package/dist/index.d.ts +943 -411
- package/dist/index.js +353 -276
- package/dist/index.js.map +1 -0
- package/package.json +17 -21
package/dist/index.cjs
CHANGED
|
@@ -1,313 +1,416 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ApiError: () => ApiError,
|
|
24
|
+
CourierDeliveryStatus: () => CourierDeliveryStatus,
|
|
25
|
+
DeliveryAPIClient: () => DeliveryAPIClient
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
2
28
|
|
|
3
29
|
// src/http.ts
|
|
30
|
+
var BASE_URL = "https://api.deliveryapi.co.kr";
|
|
4
31
|
var ApiError = class extends Error {
|
|
5
|
-
constructor(
|
|
32
|
+
constructor(code, message, status) {
|
|
6
33
|
super(message);
|
|
7
|
-
this.statusCode = statusCode;
|
|
8
|
-
this.errorCode = errorCode;
|
|
9
34
|
this.name = "ApiError";
|
|
35
|
+
this.code = code;
|
|
36
|
+
this.status = status;
|
|
10
37
|
}
|
|
11
38
|
};
|
|
12
|
-
async function request(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
async function request(path, options, auth) {
|
|
40
|
+
let url = `${BASE_URL}${path}`;
|
|
41
|
+
if (options.params) {
|
|
42
|
+
const qs = Object.entries(options.params).filter(([, v]) => v !== void 0).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join("&");
|
|
43
|
+
if (qs) url += `?${qs}`;
|
|
44
|
+
}
|
|
45
|
+
const res = await fetch(url, {
|
|
46
|
+
method: options.method ?? "GET",
|
|
47
|
+
headers: {
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
Authorization: `Bearer ${auth.apiKey}:${auth.secretKey}`
|
|
50
|
+
},
|
|
51
|
+
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
24
52
|
});
|
|
25
|
-
const
|
|
26
|
-
if (!
|
|
53
|
+
const json = await res.json();
|
|
54
|
+
if (!json.isSuccess) {
|
|
27
55
|
throw new ApiError(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
56
|
+
json.errorCode ?? "INTERNAL_ERROR",
|
|
57
|
+
json.error ?? json.message ?? `HTTP ${res.status}`,
|
|
58
|
+
json.statusCode ?? res.status
|
|
31
59
|
);
|
|
32
60
|
}
|
|
33
|
-
return
|
|
61
|
+
return json.data;
|
|
34
62
|
}
|
|
35
63
|
|
|
36
|
-
// src/resources/
|
|
37
|
-
var
|
|
38
|
-
constructor(
|
|
39
|
-
this.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const token = await this.getToken();
|
|
59
|
-
return request(this.baseUrl, "/v1/homepage/ensure-user", {
|
|
60
|
-
method: "POST",
|
|
61
|
-
body: JSON.stringify({}),
|
|
62
|
-
token
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// src/resources/dashboard.ts
|
|
68
|
-
var DashboardResource = class {
|
|
69
|
-
constructor(baseUrl, getToken) {
|
|
70
|
-
this.baseUrl = baseUrl;
|
|
71
|
-
this.getToken = getToken;
|
|
72
|
-
}
|
|
73
|
-
/** 대시보드 데이터 조회 (API 키 목록, 사용량, 플랜 정보) */
|
|
74
|
-
async get() {
|
|
75
|
-
const token = await this.getToken();
|
|
76
|
-
return request(this.baseUrl, "/v1/homepage/dashboard", { token });
|
|
77
|
-
}
|
|
78
|
-
/** API 키 발급 */
|
|
79
|
-
async issueKey() {
|
|
80
|
-
const token = await this.getToken();
|
|
81
|
-
return request(this.baseUrl, "/v1/homepage/dashboard/issue-key", {
|
|
82
|
-
method: "POST",
|
|
83
|
-
body: JSON.stringify({}),
|
|
84
|
-
token
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// src/resources/qna.ts
|
|
90
|
-
var QnaResource = class {
|
|
91
|
-
constructor(baseUrl, getToken) {
|
|
92
|
-
this.baseUrl = baseUrl;
|
|
93
|
-
this.getToken = getToken;
|
|
94
|
-
}
|
|
95
|
-
/** 게시글 목록 조회 (비회원도 공개글 열람 가능) */
|
|
96
|
-
async listPosts(params = {}) {
|
|
97
|
-
const token = await this.getToken();
|
|
98
|
-
const qs = new URLSearchParams();
|
|
99
|
-
if (params.cursor) qs.set("cursor", params.cursor);
|
|
100
|
-
if (params.pageSize) qs.set("pageSize", String(params.pageSize));
|
|
101
|
-
const query = qs.toString() ? `?${qs.toString()}` : "";
|
|
102
|
-
return request(this.baseUrl, `/v1/homepage/posts${query}`, { token });
|
|
103
|
-
}
|
|
104
|
-
/** 게시글 상세 조회 */
|
|
105
|
-
async getPost(postId) {
|
|
106
|
-
const token = await this.getToken();
|
|
107
|
-
return request(this.baseUrl, `/v1/homepage/posts/${postId}`, { token });
|
|
108
|
-
}
|
|
109
|
-
/** 게시글 작성 (로그인 필요) */
|
|
110
|
-
async createPost(params) {
|
|
111
|
-
const token = await this.getToken();
|
|
112
|
-
return request(this.baseUrl, "/v1/homepage/posts", {
|
|
113
|
-
method: "POST",
|
|
114
|
-
body: JSON.stringify(params),
|
|
115
|
-
token
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
/** 게시글 수정 (작성자/관리자만) */
|
|
119
|
-
async updatePost(postId, params) {
|
|
120
|
-
const token = await this.getToken();
|
|
121
|
-
return request(this.baseUrl, `/v1/homepage/posts/${postId}`, {
|
|
122
|
-
method: "PUT",
|
|
123
|
-
body: JSON.stringify(params),
|
|
124
|
-
token
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
/** 게시글 삭제 (작성자/관리자만) */
|
|
128
|
-
async deletePost(postId) {
|
|
129
|
-
const token = await this.getToken();
|
|
130
|
-
await request(this.baseUrl, `/v1/homepage/posts/${postId}`, {
|
|
131
|
-
method: "DELETE",
|
|
132
|
-
token
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
/** 댓글 목록 조회 */
|
|
136
|
-
async listComments(postId) {
|
|
137
|
-
const token = await this.getToken();
|
|
138
|
-
return request(this.baseUrl, `/v1/homepage/posts/${postId}/comments`, { token });
|
|
139
|
-
}
|
|
140
|
-
/** 댓글 작성 (로그인 필요) */
|
|
141
|
-
async createComment(postId, params) {
|
|
142
|
-
const token = await this.getToken();
|
|
143
|
-
return request(this.baseUrl, `/v1/homepage/posts/${postId}/comments`, {
|
|
144
|
-
method: "POST",
|
|
145
|
-
body: JSON.stringify(params),
|
|
146
|
-
token
|
|
147
|
-
});
|
|
64
|
+
// src/resources/tracking.ts
|
|
65
|
+
var TrackingResource = class {
|
|
66
|
+
constructor(auth) {
|
|
67
|
+
this.auth = auth;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 지원 택배사 목록을 조회합니다.
|
|
71
|
+
*
|
|
72
|
+
* 택배사 코드(`trackingApiCode`)는 `trace()`의 `courierCode` 파라미터에 사용합니다.
|
|
73
|
+
*
|
|
74
|
+
* @returns 지원 택배사 목록 및 총 수
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* const { couriers } = await client.tracking.getCouriers()
|
|
78
|
+
* // couriers: [{ trackingApiCode: 'cj', displayName: 'CJ대한통운' }, ...]
|
|
79
|
+
*/
|
|
80
|
+
async getCouriers() {
|
|
81
|
+
return request(
|
|
82
|
+
"/v1/tracking/couriers",
|
|
83
|
+
{},
|
|
84
|
+
this.auth
|
|
85
|
+
);
|
|
148
86
|
}
|
|
149
|
-
/**
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
87
|
+
/**
|
|
88
|
+
* 송장번호로 배송 정보를 조회합니다.
|
|
89
|
+
*
|
|
90
|
+
* - 요청당 여러 건을 배열로 전달할 수 있습니다.
|
|
91
|
+
* - 결과는 요청 순서와 동일한 인덱스로 반환됩니다.
|
|
92
|
+
* - 일부 아이템이 실패해도 전체 요청이 실패하지 않습니다. `results[].success`로 건별 확인하세요.
|
|
93
|
+
*
|
|
94
|
+
* **과금 안내**: `NOT_FOUND` 에러는 과금됩니다. `results[].error.billable`로 확인하세요.
|
|
95
|
+
*
|
|
96
|
+
* @param params 조회 파라미터
|
|
97
|
+
* @returns 아이템별 조회 결과 및 집계 요약
|
|
98
|
+
*
|
|
99
|
+
* @throws {ApiError} API 인증 실패, 요청 한도 초과 등 전체 요청 실패 시
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* const { results, summary } = await client.tracking.trace({
|
|
103
|
+
* items: [
|
|
104
|
+
* { courierCode: 'cj', trackingNumber: '1234567890', clientId: 'order_001' },
|
|
105
|
+
* { courierCode: 'lotte', trackingNumber: '9876543210', clientId: 'order_002' },
|
|
106
|
+
* ],
|
|
107
|
+
* includeProgresses: true,
|
|
108
|
+
* })
|
|
109
|
+
*
|
|
110
|
+
* for (const result of results) {
|
|
111
|
+
* if (result.success) {
|
|
112
|
+
* console.log(result.data?.deliveryStatus) // 'DELIVERED'
|
|
113
|
+
* } else {
|
|
114
|
+
* console.warn(result.error?.code) // 'NOT_FOUND'
|
|
115
|
+
* }
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* console.log(`성공: ${summary.successful} / 전체: ${summary.total}`)
|
|
119
|
+
*/
|
|
120
|
+
async trace(params) {
|
|
121
|
+
return request(
|
|
122
|
+
"/v1/tracking/trace",
|
|
123
|
+
{ method: "POST", body: params },
|
|
124
|
+
this.auth
|
|
125
|
+
);
|
|
156
126
|
}
|
|
157
127
|
};
|
|
158
128
|
|
|
159
|
-
// src/resources/
|
|
160
|
-
var
|
|
161
|
-
constructor(
|
|
162
|
-
this.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
token: await this.token()
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
/** 사용자 상세 조회 (API 키 + 사용량 포함) */
|
|
195
|
-
async getUserDetail(uid) {
|
|
196
|
-
return request(this.baseUrl, `/v1/homepage/admin/users/${uid}/detail`, {
|
|
197
|
-
token: await this.token()
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
/** customers 목록 조회 */
|
|
201
|
-
async listCustomers() {
|
|
202
|
-
return request(this.baseUrl, "/v1/homepage/admin/customers", {
|
|
203
|
-
token: await this.token()
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
/** API 키 목록 조회 */
|
|
207
|
-
async listKeys() {
|
|
208
|
-
return request(this.baseUrl, "/v1/homepage/admin/keys", {
|
|
209
|
-
token: await this.token()
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/** API 키 플랜 변경 */
|
|
213
|
-
async updateKeyPlan(apiKeyHash, params) {
|
|
214
|
-
await request(this.baseUrl, `/v1/homepage/admin/keys/${apiKeyHash}/plan`, {
|
|
215
|
-
method: "PATCH",
|
|
216
|
-
body: JSON.stringify(params),
|
|
217
|
-
token: await this.token()
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
/** API 키 플랜 일괄 변경 */
|
|
221
|
-
async bulkUpdateKeyPlan(params) {
|
|
222
|
-
await request(this.baseUrl, "/v1/homepage/admin/keys/bulk/plan", {
|
|
223
|
-
method: "PATCH",
|
|
224
|
-
body: JSON.stringify(params),
|
|
225
|
-
token: await this.token()
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
/** Secret Key limits 수정 */
|
|
229
|
-
async updateKeyLimits(apiKeyHash, params) {
|
|
230
|
-
await request(this.baseUrl, `/v1/homepage/admin/keys/${apiKeyHash}/limits`, {
|
|
231
|
-
method: "PATCH",
|
|
232
|
-
body: JSON.stringify(params),
|
|
233
|
-
token: await this.token()
|
|
234
|
-
});
|
|
129
|
+
// src/resources/webhooks.ts
|
|
130
|
+
var WebhooksResource = class {
|
|
131
|
+
constructor(auth) {
|
|
132
|
+
this.auth = auth;
|
|
133
|
+
}
|
|
134
|
+
// ─────────────────────── 엔드포인트 관리 ────────────────────────────────
|
|
135
|
+
/**
|
|
136
|
+
* 웹훅 엔드포인트를 등록합니다.
|
|
137
|
+
*
|
|
138
|
+
* 등록 시 서버에서 해당 URL로 테스트 POST 요청을 전송하여 연결 가능 여부를 검증합니다.
|
|
139
|
+
* 응답의 `webhookSecret`은 **이 응답에서만 평문으로 반환**됩니다.
|
|
140
|
+
* 분실 시 `rotateSecret()`으로 재발급해야 합니다.
|
|
141
|
+
*
|
|
142
|
+
* @param params 엔드포인트 등록 파라미터
|
|
143
|
+
* @returns 생성된 엔드포인트 정보 (webhookSecret 포함)
|
|
144
|
+
*
|
|
145
|
+
* @throws {ApiError} `WEBHOOK_ENDPOINT_LIMIT` — 엔드포인트 등록 한도 초과
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* const endpoint = await client.webhooks.createEndpoint({
|
|
149
|
+
* url: 'https://my-server.com/webhook',
|
|
150
|
+
* name: '운영 서버',
|
|
151
|
+
* })
|
|
152
|
+
* console.log(endpoint.endpointId) // 'ep_xxxx'
|
|
153
|
+
* console.log(endpoint.webhookSecret) // 반드시 저장하세요!
|
|
154
|
+
*/
|
|
155
|
+
async createEndpoint(params) {
|
|
156
|
+
return request(
|
|
157
|
+
"/v1/webhooks/endpoints",
|
|
158
|
+
{ method: "POST", body: params },
|
|
159
|
+
this.auth
|
|
160
|
+
);
|
|
235
161
|
}
|
|
236
|
-
/**
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
162
|
+
/**
|
|
163
|
+
* 등록된 웹훅 엔드포인트 목록을 조회합니다.
|
|
164
|
+
*
|
|
165
|
+
* @returns 엔드포인트 목록 및 총 수
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* const { endpoints } = await client.webhooks.listEndpoints()
|
|
169
|
+
* const active = endpoints.filter(ep => ep.status === 'active')
|
|
170
|
+
*/
|
|
171
|
+
async listEndpoints() {
|
|
172
|
+
return request(
|
|
173
|
+
"/v1/webhooks/endpoints",
|
|
174
|
+
{},
|
|
175
|
+
this.auth
|
|
176
|
+
);
|
|
243
177
|
}
|
|
244
|
-
/**
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
178
|
+
/**
|
|
179
|
+
* 웹훅 엔드포인트 이름을 수정합니다.
|
|
180
|
+
*
|
|
181
|
+
* URL은 변경할 수 없습니다. URL을 변경해야 한다면 엔드포인트를 삭제 후 재등록하세요.
|
|
182
|
+
*
|
|
183
|
+
* @param endpointId 수정할 엔드포인트 ID
|
|
184
|
+
* @param params 수정 내용
|
|
185
|
+
*
|
|
186
|
+
* @throws {ApiError} `NOT_FOUND` — 존재하지 않는 엔드포인트
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* await client.webhooks.updateEndpoint('ep_xxxx', { name: '스테이징 서버' })
|
|
190
|
+
*/
|
|
191
|
+
async updateEndpoint(endpointId, params) {
|
|
192
|
+
await request(
|
|
193
|
+
`/v1/webhooks/endpoints/${endpointId}`,
|
|
194
|
+
{ method: "PUT", body: params },
|
|
195
|
+
this.auth
|
|
196
|
+
);
|
|
249
197
|
}
|
|
250
|
-
/**
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
198
|
+
/**
|
|
199
|
+
* 웹훅 엔드포인트를 삭제합니다.
|
|
200
|
+
*
|
|
201
|
+
* 해당 엔드포인트에 연결된 구독도 함께 삭제됩니다 (cascade).
|
|
202
|
+
*
|
|
203
|
+
* @param endpointId 삭제할 엔드포인트 ID
|
|
204
|
+
*
|
|
205
|
+
* @throws {ApiError} `NOT_FOUND` — 존재하지 않는 엔드포인트
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* await client.webhooks.deleteEndpoint('ep_xxxx')
|
|
209
|
+
*/
|
|
210
|
+
async deleteEndpoint(endpointId) {
|
|
211
|
+
await request(
|
|
212
|
+
`/v1/webhooks/endpoints/${endpointId}`,
|
|
213
|
+
{ method: "DELETE" },
|
|
214
|
+
this.auth
|
|
215
|
+
);
|
|
257
216
|
}
|
|
258
|
-
/**
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
217
|
+
/**
|
|
218
|
+
* 웹훅 서명 시크릿을 재발급합니다.
|
|
219
|
+
*
|
|
220
|
+
* 기존 시크릿은 즉시 무효화됩니다.
|
|
221
|
+
* 새 시크릿은 **이 응답에서만 평문으로 반환**됩니다.
|
|
222
|
+
*
|
|
223
|
+
* @param endpointId 대상 엔드포인트 ID
|
|
224
|
+
* @param params 새 시크릿 (선택, 미제공 시 서버 생성)
|
|
225
|
+
* @returns 새 웹훅 시크릿
|
|
226
|
+
*
|
|
227
|
+
* @throws {ApiError} `NOT_FOUND` — 존재하지 않는 엔드포인트
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* const { webhookSecret } = await client.webhooks.rotateSecret('ep_xxxx')
|
|
231
|
+
* console.log(webhookSecret) // 새 시크릿 — 반드시 저장하세요!
|
|
232
|
+
*/
|
|
233
|
+
async rotateSecret(endpointId, params) {
|
|
234
|
+
return request(
|
|
235
|
+
`/v1/webhooks/endpoints/${endpointId}/rotate`,
|
|
236
|
+
{ method: "POST", body: params ?? {} },
|
|
237
|
+
this.auth
|
|
238
|
+
);
|
|
265
239
|
}
|
|
266
|
-
|
|
267
|
-
|
|
240
|
+
// ─────────────────────── 구독 관리 ──────────────────────────────────────
|
|
241
|
+
/**
|
|
242
|
+
* 택배 추적 구독을 등록합니다.
|
|
243
|
+
*
|
|
244
|
+
* **구독형** (`recurring: true`): 배송 완료 또는 최대 14일까지 주기적으로 폴링하여
|
|
245
|
+
* 상태 변경 시 `endpointId`로 웹훅을 발송합니다.
|
|
246
|
+
*
|
|
247
|
+
* **일회성** (`recurring: false`): 등록 즉시 1회 크롤 후 종료합니다.
|
|
248
|
+
* `endpointId` 없이 사용하면 결과를 `getSubscription(requestId)`으로 직접 조회할 수 있습니다.
|
|
249
|
+
*
|
|
250
|
+
* @param params 구독 등록 파라미터
|
|
251
|
+
* @returns 구독 ID (`requestId`) 및 기본 정보
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* // 구독형 — 상태 변경 시 웹훅 수신
|
|
255
|
+
* const sub = await client.webhooks.register({
|
|
256
|
+
* endpointId: 'ep_xxxx',
|
|
257
|
+
* items: [
|
|
258
|
+
* { courierCode: 'cj', trackingNumber: '1234567890', clientId: 'order_001' },
|
|
259
|
+
* ],
|
|
260
|
+
* recurring: true,
|
|
261
|
+
* })
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* // 일회성 즉시 조회 — 웹훅 없이 결과를 직접 폴링
|
|
265
|
+
* const req = await client.webhooks.register({
|
|
266
|
+
* items: [{ courierCode: 'lotte', trackingNumber: '9876543210' }],
|
|
267
|
+
* recurring: false,
|
|
268
|
+
* })
|
|
269
|
+
* const detail = await client.webhooks.getSubscription(req.requestId)
|
|
270
|
+
*/
|
|
271
|
+
async register(params) {
|
|
268
272
|
return request(
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
273
|
+
"/v1/webhooks/register",
|
|
274
|
+
{ method: "POST", body: params },
|
|
275
|
+
this.auth
|
|
272
276
|
);
|
|
273
277
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
278
|
+
/**
|
|
279
|
+
* 구독 목록을 조회합니다.
|
|
280
|
+
*
|
|
281
|
+
* 커서 기반 페이지네이션을 지원합니다.
|
|
282
|
+
* 다음 페이지가 있으면 응답의 `nextCursor`를 다음 호출의 `cursor` 파라미터로 전달하세요.
|
|
283
|
+
*
|
|
284
|
+
* @param params 페이지네이션 파라미터 (선택)
|
|
285
|
+
* @returns 구독 목록 및 다음 페이지 커서
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* // 전체 구독 목록 순회
|
|
289
|
+
* let cursor: string | undefined
|
|
290
|
+
* do {
|
|
291
|
+
* const page = await client.webhooks.listSubscriptions({ cursor, limit: 50 })
|
|
292
|
+
* for (const sub of page.subscriptions) {
|
|
293
|
+
* console.log(sub.requestId, sub.isActive)
|
|
294
|
+
* }
|
|
295
|
+
* cursor = page.nextCursor
|
|
296
|
+
* } while (cursor)
|
|
297
|
+
*/
|
|
298
|
+
async listSubscriptions(params) {
|
|
299
|
+
return request(
|
|
300
|
+
"/v1/webhooks/subscriptions",
|
|
301
|
+
{
|
|
302
|
+
params: {
|
|
303
|
+
cursor: params?.cursor,
|
|
304
|
+
limit: params?.limit
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
this.auth
|
|
308
|
+
);
|
|
280
309
|
}
|
|
281
|
-
/**
|
|
282
|
-
|
|
283
|
-
|
|
310
|
+
/**
|
|
311
|
+
* 구독 상세 정보를 조회합니다.
|
|
312
|
+
*
|
|
313
|
+
* 각 택배별 현재 상태 및 최신 배송 데이터를 포함합니다.
|
|
314
|
+
*
|
|
315
|
+
* @param requestId `register()` 응답의 `requestId`
|
|
316
|
+
* @returns 구독 상세 (아이템별 상태 포함)
|
|
317
|
+
*
|
|
318
|
+
* @throws {ApiError} `NOT_FOUND` — 존재하지 않는 구독
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* const detail = await client.webhooks.getSubscription('req_xxxx')
|
|
322
|
+
*
|
|
323
|
+
* for (const item of detail.items) {
|
|
324
|
+
* console.log(item.trackingNumber, item.currentStatus)
|
|
325
|
+
* }
|
|
326
|
+
*/
|
|
327
|
+
async getSubscription(requestId) {
|
|
328
|
+
return request(
|
|
329
|
+
`/v1/webhooks/subscriptions/${requestId}`,
|
|
330
|
+
{},
|
|
331
|
+
this.auth
|
|
332
|
+
);
|
|
284
333
|
}
|
|
285
|
-
/**
|
|
286
|
-
|
|
287
|
-
|
|
334
|
+
/**
|
|
335
|
+
* 구독을 취소합니다.
|
|
336
|
+
*
|
|
337
|
+
* 취소된 구독은 더 이상 폴링되지 않으며 웹훅도 발송되지 않습니다.
|
|
338
|
+
*
|
|
339
|
+
* @param requestId 취소할 구독 ID
|
|
340
|
+
*
|
|
341
|
+
* @throws {ApiError} `NOT_FOUND` — 존재하지 않는 구독
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* await client.webhooks.cancelSubscription('req_xxxx')
|
|
345
|
+
*/
|
|
346
|
+
async cancelSubscription(requestId) {
|
|
347
|
+
await request(
|
|
348
|
+
`/v1/webhooks/subscriptions/${requestId}`,
|
|
349
|
+
{ method: "DELETE" },
|
|
350
|
+
this.auth
|
|
351
|
+
);
|
|
288
352
|
}
|
|
289
|
-
/**
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
353
|
+
/**
|
|
354
|
+
* 여러 송장번호의 최신 배송 정보를 한 번에 조회합니다.
|
|
355
|
+
*
|
|
356
|
+
* 구독 ID 없이 택배사 코드 + 송장번호로 검색합니다.
|
|
357
|
+
* 해당 계정에 등록된 구독 중 일치하는 아이템을 반환합니다.
|
|
358
|
+
*
|
|
359
|
+
* @param params 조회할 아이템 목록
|
|
360
|
+
* @returns 아이템별 최신 배송 정보
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* const { results } = await client.webhooks.batchResults({
|
|
364
|
+
* items: [
|
|
365
|
+
* { courierCode: 'cj', trackingNumber: '1111111111' },
|
|
366
|
+
* { courierCode: 'lotte', trackingNumber: '2222222222' },
|
|
367
|
+
* ],
|
|
368
|
+
* })
|
|
369
|
+
*
|
|
370
|
+
* for (const r of results) {
|
|
371
|
+
* console.log(r.currentStatus, r.isDelivered)
|
|
372
|
+
* }
|
|
373
|
+
*/
|
|
374
|
+
async batchResults(params) {
|
|
375
|
+
return request(
|
|
376
|
+
"/v1/webhooks/results",
|
|
377
|
+
{ method: "POST", body: params },
|
|
378
|
+
this.auth
|
|
379
|
+
);
|
|
295
380
|
}
|
|
296
381
|
};
|
|
297
382
|
|
|
298
383
|
// src/client.ts
|
|
299
|
-
var
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
this.
|
|
305
|
-
this.
|
|
306
|
-
this.qna = new QnaResource(BASE_URL, getToken);
|
|
307
|
-
this.admin = new AdminResource(BASE_URL, getToken);
|
|
308
|
-
this.public = new PublicResource(BASE_URL);
|
|
384
|
+
var DeliveryAPIClient = class {
|
|
385
|
+
constructor(options) {
|
|
386
|
+
/** API Base URL (`https://api.deliveryapi.co.kr`) */
|
|
387
|
+
this.baseUrl = BASE_URL;
|
|
388
|
+
const auth = { apiKey: options.apiKey, secretKey: options.secretKey };
|
|
389
|
+
this.tracking = new TrackingResource(auth);
|
|
390
|
+
this.webhooks = new WebhooksResource(auth);
|
|
309
391
|
}
|
|
310
392
|
};
|
|
311
393
|
|
|
312
|
-
|
|
313
|
-
|
|
394
|
+
// src/types.ts
|
|
395
|
+
var CourierDeliveryStatus = /* @__PURE__ */ ((CourierDeliveryStatus2) => {
|
|
396
|
+
CourierDeliveryStatus2["PENDING"] = "PENDING";
|
|
397
|
+
CourierDeliveryStatus2["REGISTERED"] = "REGISTERED";
|
|
398
|
+
CourierDeliveryStatus2["PICKUP_READY"] = "PICKUP_READY";
|
|
399
|
+
CourierDeliveryStatus2["PICKED_UP"] = "PICKED_UP";
|
|
400
|
+
CourierDeliveryStatus2["IN_TRANSIT"] = "IN_TRANSIT";
|
|
401
|
+
CourierDeliveryStatus2["OUT_FOR_DELIVERY"] = "OUT_FOR_DELIVERY";
|
|
402
|
+
CourierDeliveryStatus2["DELIVERED"] = "DELIVERED";
|
|
403
|
+
CourierDeliveryStatus2["FAILED"] = "FAILED";
|
|
404
|
+
CourierDeliveryStatus2["RETURNED"] = "RETURNED";
|
|
405
|
+
CourierDeliveryStatus2["CANCELLED"] = "CANCELLED";
|
|
406
|
+
CourierDeliveryStatus2["HOLD"] = "HOLD";
|
|
407
|
+
CourierDeliveryStatus2["UNKNOWN"] = "UNKNOWN";
|
|
408
|
+
return CourierDeliveryStatus2;
|
|
409
|
+
})(CourierDeliveryStatus || {});
|
|
410
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
411
|
+
0 && (module.exports = {
|
|
412
|
+
ApiError,
|
|
413
|
+
CourierDeliveryStatus,
|
|
414
|
+
DeliveryAPIClient
|
|
415
|
+
});
|
|
416
|
+
//# sourceMappingURL=index.cjs.map
|