deliveryapi 0.1.4 → 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/dist/index.cjs CHANGED
@@ -1,232 +1,312 @@
1
1
  'use strict';
2
2
 
3
- // src/errors.ts
4
- var DeliverySaasError = class extends Error {
5
- constructor(message, statusCode, code) {
3
+ // src/http.ts
4
+ var ApiError = class extends Error {
5
+ constructor(statusCode, errorCode, message) {
6
6
  super(message);
7
7
  this.statusCode = statusCode;
8
- this.code = code;
9
- this.name = "DeliverySaasError";
10
- }
11
- };
12
- var AuthenticationError = class extends DeliverySaasError {
13
- constructor(message = "Invalid API key or secret key") {
14
- super(message, 401, "AUTHENTICATION_ERROR");
15
- this.name = "AuthenticationError";
8
+ this.errorCode = errorCode;
9
+ this.name = "ApiError";
16
10
  }
17
11
  };
18
- var RateLimitError = class extends DeliverySaasError {
19
- constructor(message = "Rate limit exceeded") {
20
- super(message, 429, "RATE_LIMIT_ERROR");
21
- this.name = "RateLimitError";
12
+ async function request(baseUrl, path, options = {}) {
13
+ const { token, ...fetchOptions } = options;
14
+ const headers = {
15
+ "Content-Type": "application/json",
16
+ ...fetchOptions.headers
17
+ };
18
+ if (token) {
19
+ headers["Authorization"] = `Bearer ${token}`;
22
20
  }
23
- };
24
- var NotFoundError = class extends DeliverySaasError {
25
- constructor(message = "Resource not found") {
26
- super(message, 404, "NOT_FOUND");
27
- this.name = "NotFoundError";
21
+ const res = await fetch(`${baseUrl}${path}`, {
22
+ ...fetchOptions,
23
+ headers
24
+ });
25
+ const body = await res.json();
26
+ if (!res.ok || !body.isSuccess) {
27
+ throw new ApiError(
28
+ res.status,
29
+ body.errorCode,
30
+ body.error ?? `Request failed with status ${res.status}`
31
+ );
28
32
  }
29
- };
33
+ return body.data;
34
+ }
30
35
 
31
- // src/http.ts
32
- var HttpClient = class {
33
- constructor(apiKey, secretKey, baseUrl) {
34
- this.baseUrl = baseUrl.replace(/\/$/, "");
35
- this.authHeader = `Bearer ${apiKey}:${secretKey}`;
36
- }
37
- async get(path, params) {
38
- const url = new URL(`${this.baseUrl}${path}`);
39
- if (params) {
40
- Object.entries(params).forEach(([key, value]) => url.searchParams.set(key, value));
41
- }
42
- return this.request("GET", url.toString());
43
- }
44
- async post(path, body) {
45
- return this.request("POST", `${this.baseUrl}${path}`, body);
46
- }
47
- async put(path, body) {
48
- return this.request("PUT", `${this.baseUrl}${path}`, body);
49
- }
50
- async patch(path, body) {
51
- return this.request("PATCH", `${this.baseUrl}${path}`, body);
52
- }
53
- async delete(path) {
54
- return this.request("DELETE", `${this.baseUrl}${path}`);
55
- }
56
- async request(method, url, body) {
57
- const headers = {
58
- Authorization: this.authHeader,
59
- "Content-Type": "application/json"
60
- };
61
- const response = await fetch(url, {
62
- method,
63
- headers,
64
- body: body !== void 0 ? JSON.stringify(body) : void 0
65
- });
66
- const json = await response.json();
67
- if (!response.ok) {
68
- if (response.status === 401) throw new AuthenticationError(json.message);
69
- if (response.status === 404) throw new NotFoundError(json.message);
70
- if (response.status === 429) throw new RateLimitError(json.message);
71
- throw new DeliverySaasError(json.message ?? "Request failed", response.status, json.error);
72
- }
73
- if (!json.isSuccess) {
74
- throw new DeliverySaasError(json.message ?? "API returned failure", response.status, json.error);
75
- }
76
- return json.data;
36
+ // src/resources/auth.ts
37
+ var AuthResource = class {
38
+ constructor(baseUrl, getToken) {
39
+ this.baseUrl = baseUrl;
40
+ this.getToken = getToken;
41
+ }
42
+ /** Step 1: 이메일 인증 코드 요청 */
43
+ async requestVerification(params) {
44
+ await request(this.baseUrl, "/v1/homepage/register/request", {
45
+ method: "POST",
46
+ body: JSON.stringify(params)
47
+ });
48
+ }
49
+ /** Step 2: 인증 코드 검증 + Firebase 계정 생성 → customToken 반환 */
50
+ async verifyAndRegister(params) {
51
+ return request(this.baseUrl, "/v1/homepage/register/verify", {
52
+ method: "POST",
53
+ body: JSON.stringify(params)
54
+ });
55
+ }
56
+ /** Google 로그인 후 HP 사용자 문서 확인/생성 */
57
+ async ensureUser() {
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
+ });
77
64
  }
78
65
  };
79
66
 
80
- // src/resources/tracking.ts
81
- var TrackingResource = class {
82
- constructor(http) {
83
- this.http = http;
84
- }
85
- /**
86
- * 택배 조회 (공개 API, 계정 불필요)
87
- * @param items 조회할 택배 목록 (1건도 배열로)
88
- * @param includeProgresses 진행 내역 포함 여부 (기본값: true)
89
- */
90
- async get(items, includeProgresses = true) {
91
- return this.http.post("/v1/tracking/trace", {
92
- items,
93
- includeProgresses
94
- });
95
- }
96
- /**
97
- * 단건 택배 조회 (편의 메서드)
98
- */
99
- async getOne(courierCode, trackingNumber, options) {
100
- return this.get(
101
- [{ courierCode, trackingNumber, clientId: options?.clientId }],
102
- options?.includeProgresses ?? true
103
- );
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
+ });
104
86
  }
105
87
  };
106
88
 
107
- // src/resources/subscriptions.ts
108
- var SubscriptionsResource = class {
109
- constructor(http) {
110
- this.http = http;
111
- }
112
- /**
113
- * 택배 구독 생성 (단건)
114
- * 상태 변경 등록된 웹훅 엔드포인트로 알림 전송
115
- */
116
- async create(data) {
117
- return this.http.post("/v1/tracking/subscriptions", {
118
- items: [data]
119
- });
120
- }
121
- /**
122
- * 택배 구독 일괄 생성 (최대 100건)
123
- */
124
- async createBatch(items) {
125
- return this.http.post("/v1/tracking/subscriptions", { items });
126
- }
127
- /**
128
- * 택배 구독 목록 조회
129
- */
130
- async list(options) {
131
- const params = {};
132
- if (options?.status) params["status"] = options.status;
133
- if (options?.limit) params["limit"] = String(options.limit);
134
- if (options?.cursor) params["cursor"] = options.cursor;
135
- return this.http.get("/v1/tracking/subscriptions", params);
136
- }
137
- /**
138
- * 택배 구독 상세 조회
139
- */
140
- async retrieve(subscriptionId) {
141
- return this.http.get(`/v1/tracking/subscriptions/${subscriptionId}`);
142
- }
143
- /**
144
- * 택배 구독 취소 (ID)
145
- */
146
- async cancel(subscriptionId) {
147
- await this.http.delete(`/v1/tracking/subscriptions/${subscriptionId}`);
148
- }
149
- /**
150
- * 택배 구독 취소 (송장번호)
151
- */
152
- async cancelByTracking(courierCode, trackingNumber) {
153
- return this.http.delete(
154
- `/v1/tracking/subscriptions?courierCode=${encodeURIComponent(courierCode)}&trackingNumber=${encodeURIComponent(trackingNumber)}`
155
- );
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
+ });
148
+ }
149
+ /** 댓글 삭제 (작성자/관리자만) */
150
+ async deleteComment(commentId) {
151
+ const token = await this.getToken();
152
+ await request(this.baseUrl, `/v1/homepage/comments/${commentId}`, {
153
+ method: "DELETE",
154
+ token
155
+ });
156
156
  }
157
157
  };
158
158
 
159
- // src/resources/webhooks.ts
160
- var WebhooksResource = class {
161
- constructor(http) {
162
- this.http = http;
163
- }
164
- /**
165
- * 웹훅 엔드포인트 등록
166
- */
167
- async create(data) {
168
- return this.http.post("/v1/webhook-v2/endpoints", data);
169
- }
170
- /**
171
- * 웹훅 엔드포인트 목록 조회
172
- */
173
- async list() {
174
- return this.http.get("/v1/webhook-v2/endpoints");
175
- }
176
- /**
177
- * 웹훅 엔드포인트 이름 수정
178
- */
179
- async update(endpointId, data) {
180
- await this.http.put(`/v1/webhook-v2/endpoints/${endpointId}`, data);
181
- }
182
- /**
183
- * 웹훅 엔드포인트 삭제
184
- */
185
- async delete(endpointId) {
186
- await this.http.delete(`/v1/webhook-v2/endpoints/${endpointId}`);
187
- }
188
- /**
189
- * 웹훅 시크릿 재발급
190
- */
191
- async rotateSecret(endpointId, webhookSecret) {
192
- return this.http.post(
193
- `/v1/webhook-v2/endpoints/${endpointId}/rotate`,
194
- webhookSecret ? { webhookSecret } : void 0
159
+ // src/resources/admin.ts
160
+ var AdminResource = class {
161
+ constructor(baseUrl, getToken) {
162
+ this.baseUrl = baseUrl;
163
+ this.getToken = getToken;
164
+ }
165
+ async token() {
166
+ return this.getToken();
167
+ }
168
+ /** 전체 통계 조회 */
169
+ async getStats() {
170
+ return request(this.baseUrl, "/v1/homepage/admin/stats", {
171
+ token: await this.token()
172
+ });
173
+ }
174
+ /** 최근 14일 일별 가입자 수 */
175
+ async getDailySignups() {
176
+ return request(this.baseUrl, "/v1/homepage/admin/daily-signups", {
177
+ token: await this.token()
178
+ });
179
+ }
180
+ /** 사용자 목록 조회 */
181
+ async listUsers() {
182
+ return request(this.baseUrl, "/v1/homepage/admin/users", {
183
+ token: await this.token()
184
+ });
185
+ }
186
+ /** 사용자 정보 수정 */
187
+ async updateUser(uid, params) {
188
+ await request(this.baseUrl, `/v1/homepage/admin/users/${uid}`, {
189
+ method: "PATCH",
190
+ body: JSON.stringify(params),
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
+ });
235
+ }
236
+ /** 데모 키 생성 */
237
+ async createDemoKey(params = {}) {
238
+ return request(this.baseUrl, "/v1/homepage/admin/demo-keys", {
239
+ method: "POST",
240
+ body: JSON.stringify(params),
241
+ token: await this.token()
242
+ });
243
+ }
244
+ /** 데모 키 목록 조회 */
245
+ async listDemoKeys() {
246
+ return request(this.baseUrl, "/v1/homepage/admin/demo-keys", {
247
+ token: await this.token()
248
+ });
249
+ }
250
+ /** 데모 키 비활성화 */
251
+ async deactivateDemoKey(apiKeyHash) {
252
+ await request(this.baseUrl, `/v1/homepage/admin/demo-keys/${apiKeyHash}/deactivate`, {
253
+ method: "PATCH",
254
+ body: JSON.stringify({}),
255
+ token: await this.token()
256
+ });
257
+ }
258
+ /** 데모 키 활성화 */
259
+ async activateDemoKey(apiKeyHash) {
260
+ await request(this.baseUrl, `/v1/homepage/admin/demo-keys/${apiKeyHash}/activate`, {
261
+ method: "PATCH",
262
+ body: JSON.stringify({}),
263
+ token: await this.token()
264
+ });
265
+ }
266
+ /** 조회 로그 목록 */
267
+ async listTrackingLogs(page = 1) {
268
+ return request(
269
+ this.baseUrl,
270
+ `/v1/homepage/admin/tracking-logs?page=${page}`,
271
+ { token: await this.token() }
195
272
  );
196
273
  }
197
274
  };
198
275
 
199
- // src/resources/couriers.ts
200
- var CouriersResource = class {
201
- constructor(http) {
202
- this.http = http;
276
+ // src/resources/public.ts
277
+ var PublicResource = class {
278
+ constructor(baseUrl) {
279
+ this.baseUrl = baseUrl;
203
280
  }
204
- /**
205
- * 지원 택배사 목록 조회
206
- */
207
- async list() {
208
- return this.http.get("/v1/tracking/couriers");
281
+ /** 요금제 목록 조회 */
282
+ async getPlans() {
283
+ return request(this.baseUrl, "/v1/homepage/plans");
284
+ }
285
+ /** Secret Key 프리셋 목록 조회 */
286
+ async getSecretPresets() {
287
+ return request(this.baseUrl, "/v1/homepage/secret-presets");
288
+ }
289
+ /** 개발 의뢰 문의 전송 */
290
+ async sendContactInquiry(params) {
291
+ await request(this.baseUrl, "/v1/homepage/contact/inquiry", {
292
+ method: "POST",
293
+ body: JSON.stringify(params)
294
+ });
209
295
  }
210
296
  };
211
297
 
212
298
  // src/client.ts
213
- var DEFAULT_BASE_URL = "https://api.deliveryapi.co.kr";
214
- var DeliverySaasClient = class {
215
- constructor(config) {
216
- const http = new HttpClient(
217
- config.apiKey,
218
- config.secretKey,
219
- config.baseUrl ?? DEFAULT_BASE_URL
220
- );
221
- this.tracking = new TrackingResource(http);
222
- this.subscriptions = new SubscriptionsResource(http);
223
- this.webhooks = new WebhooksResource(http);
224
- this.couriers = new CouriersResource(http);
299
+ var noToken = async () => null;
300
+ var HomepageClient = class {
301
+ constructor(options) {
302
+ const { baseUrl, getToken = noToken } = options;
303
+ this.auth = new AuthResource(baseUrl, getToken);
304
+ this.dashboard = new DashboardResource(baseUrl, getToken);
305
+ this.qna = new QnaResource(baseUrl, getToken);
306
+ this.admin = new AdminResource(baseUrl, getToken);
307
+ this.public = new PublicResource(baseUrl);
225
308
  }
226
309
  };
227
310
 
228
- exports.AuthenticationError = AuthenticationError;
229
- exports.DeliverySaasClient = DeliverySaasClient;
230
- exports.DeliverySaasError = DeliverySaasError;
231
- exports.NotFoundError = NotFoundError;
232
- exports.RateLimitError = RateLimitError;
311
+ exports.ApiError = ApiError;
312
+ exports.HomepageClient = HomepageClient;