entity-server-client 0.2.5 → 0.2.6

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.
Files changed (44) hide show
  1. package/README.md +0 -1
  2. package/build.mjs +4 -1
  3. package/dist/EntityServerClient.d.ts +705 -199
  4. package/dist/client/base.d.ts +59 -0
  5. package/dist/client/packet.d.ts +8 -6
  6. package/dist/client/request.d.ts +0 -1
  7. package/dist/client/utils.d.ts +5 -1
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +4 -4
  10. package/dist/mixins/alimtalk.d.ts +56 -0
  11. package/dist/mixins/auth.d.ts +167 -0
  12. package/dist/mixins/email.d.ts +51 -0
  13. package/dist/mixins/entity.d.ts +119 -0
  14. package/dist/mixins/file.d.ts +78 -0
  15. package/dist/mixins/identity.d.ts +52 -0
  16. package/dist/mixins/pg.d.ts +63 -0
  17. package/dist/mixins/push.d.ts +110 -0
  18. package/dist/mixins/sms.d.ts +55 -0
  19. package/dist/mixins/smtp.d.ts +44 -0
  20. package/dist/mixins/utils.d.ts +70 -0
  21. package/dist/react.js +1 -1
  22. package/dist/react.js.map +4 -4
  23. package/dist/types.d.ts +165 -1
  24. package/docs/apis.md +5 -12
  25. package/docs/react.md +6 -7
  26. package/package.json +2 -1
  27. package/src/EntityServerClient.ts +54 -546
  28. package/src/client/base.ts +246 -0
  29. package/src/client/packet.ts +14 -27
  30. package/src/client/request.ts +2 -11
  31. package/src/client/utils.ts +18 -2
  32. package/src/hooks/useEntityServer.ts +3 -4
  33. package/src/mixins/alimtalk.ts +35 -0
  34. package/src/mixins/auth.ts +287 -0
  35. package/src/mixins/email.ts +46 -0
  36. package/src/mixins/entity.ts +205 -0
  37. package/src/mixins/file.ts +99 -0
  38. package/src/mixins/identity.ts +35 -0
  39. package/src/mixins/pg.ts +58 -0
  40. package/src/mixins/push.ts +132 -0
  41. package/src/mixins/sms.ts +46 -0
  42. package/src/mixins/smtp.ts +20 -0
  43. package/src/mixins/utils.ts +75 -0
  44. package/src/types.ts +203 -1
@@ -0,0 +1,58 @@
1
+ import type {
2
+ PgCreateOrderRequest,
3
+ PgConfirmPaymentRequest,
4
+ PgCancelPaymentRequest,
5
+ } from "../types";
6
+ import type { GConstructor, EntityServerClientBase } from "../client/base";
7
+
8
+ export function PgMixin<TBase extends GConstructor<EntityServerClientBase>>(
9
+ Base: TBase,
10
+ ) {
11
+ return class PgMixinClass extends Base {
12
+ // ─── PG(결제 게이트웨이) ──────────────────────────────────────────────
13
+
14
+ /** 결제 주문을 생성합니다. */
15
+ pgCreateOrder(
16
+ req: PgCreateOrderRequest,
17
+ ): Promise<{ ok: boolean; data: Record<string, unknown> }> {
18
+ return this._request("POST", "/v1/pg/orders", req);
19
+ }
20
+
21
+ /** 주문 정보를 조회합니다. */
22
+ pgGetOrder(orderId: string): Promise<{
23
+ ok: boolean;
24
+ data: Record<string, unknown>;
25
+ }> {
26
+ return this._request("GET", `/v1/pg/orders/${orderId}`);
27
+ }
28
+
29
+ /** 결제를 승인합니다. */
30
+ pgConfirmPayment(
31
+ req: PgConfirmPaymentRequest,
32
+ ): Promise<{ ok: boolean; data: Record<string, unknown> }> {
33
+ return this._request("POST", "/v1/pg/confirm", req);
34
+ }
35
+
36
+ /** 결제를 취소합니다. */
37
+ pgCancelPayment(
38
+ orderId: string,
39
+ req: PgCancelPaymentRequest,
40
+ ): Promise<{ ok: boolean; data: Record<string, unknown> }> {
41
+ return this._request(
42
+ "POST",
43
+ `/v1/pg/orders/${orderId}/cancel`,
44
+ req,
45
+ );
46
+ }
47
+
48
+ /** 결제 상태를 외부 PG와 동기화합니다. */
49
+ pgSyncPayment(orderId: string): Promise<{ ok: boolean }> {
50
+ return this._request("POST", `/v1/pg/orders/${orderId}/sync`, {});
51
+ }
52
+
53
+ /** 클라이언트 SDK 설정을 반환합니다 (공개 API, 인증 불필요). */
54
+ pgConfig(): Promise<{ ok: boolean; data: Record<string, unknown> }> {
55
+ return this._request("GET", "/v1/pg/config", undefined, false);
56
+ }
57
+ };
58
+ }
@@ -0,0 +1,132 @@
1
+ import type {
2
+ EntityListParams,
3
+ EntityListResult,
4
+ RegisterPushDeviceOptions,
5
+ PushSendRequest,
6
+ PushSendAllRequest,
7
+ } from "../types";
8
+ import type { GConstructor, EntityServerClientBase } from "../client/base";
9
+
10
+ // entity submit을 가진 base 타입 (EntityMixin 적용 후)
11
+ type WithSubmit = EntityServerClientBase & {
12
+ submit(
13
+ entity: string,
14
+ data: Record<string, unknown>,
15
+ opts?: { transactionId?: string; skipHooks?: boolean },
16
+ ): Promise<{ ok: boolean; seq: number }>;
17
+ list<T = unknown>(
18
+ entity: string,
19
+ params?: EntityListParams,
20
+ ): Promise<{ ok: boolean; data: EntityListResult<T> }>;
21
+ };
22
+
23
+ export function PushMixin<TBase extends GConstructor<WithSubmit>>(Base: TBase) {
24
+ return class PushMixinClass extends Base {
25
+ // ─── 푸시 submit 래퍼 ────────────────────────────────────────────────
26
+
27
+ /**
28
+ * 푸시 관련 엔티티로 payload를 전송(Submit)합니다.
29
+ * 내부적으로 `submit()` 메서드를 호출합니다.
30
+ */
31
+ push(
32
+ pushEntity: string,
33
+ payload: Record<string, unknown>,
34
+ opts: { transactionId?: string } = {},
35
+ ): Promise<{ ok: boolean; seq: number }> {
36
+ return this.submit(pushEntity, payload, opts);
37
+ }
38
+
39
+ // ─── 푸시 디바이스 관리 ───────────────────────────────────────────────
40
+
41
+ /** 푸시 로그 엔티티 목록을 조회합니다. */
42
+ pushLogList<T = unknown>(
43
+ params: EntityListParams = {},
44
+ ): Promise<{ ok: boolean; data: EntityListResult<T> }> {
45
+ return this.list<T>("push_log", params);
46
+ }
47
+
48
+ /** 계정의 푸시 디바이스를 등록합니다. */
49
+ registerPushDevice(
50
+ accountSeq: number,
51
+ deviceId: string,
52
+ pushToken: string,
53
+ opts: RegisterPushDeviceOptions = {},
54
+ ): Promise<{ ok: boolean; seq: number }> {
55
+ const {
56
+ platform,
57
+ deviceType,
58
+ browser,
59
+ browserVersion,
60
+ pushEnabled = true,
61
+ transactionId,
62
+ } = opts;
63
+ return this.submit(
64
+ "account_device",
65
+ {
66
+ id: deviceId,
67
+ account_seq: accountSeq,
68
+ push_token: pushToken,
69
+ push_enabled: pushEnabled,
70
+ ...(platform ? { platform } : {}),
71
+ ...(deviceType ? { device_type: deviceType } : {}),
72
+ ...(browser ? { browser } : {}),
73
+ ...(browserVersion
74
+ ? { browser_version: browserVersion }
75
+ : {}),
76
+ },
77
+ { transactionId },
78
+ );
79
+ }
80
+
81
+ /** 디바이스 레코드의 푸시 토큰을 갱신합니다. */
82
+ updatePushDeviceToken(
83
+ deviceSeq: number,
84
+ pushToken: string,
85
+ opts: { pushEnabled?: boolean; transactionId?: string } = {},
86
+ ): Promise<{ ok: boolean; seq: number }> {
87
+ const { pushEnabled = true, transactionId } = opts;
88
+ return this.submit(
89
+ "account_device",
90
+ {
91
+ seq: deviceSeq,
92
+ push_token: pushToken,
93
+ push_enabled: pushEnabled,
94
+ },
95
+ { transactionId },
96
+ );
97
+ }
98
+
99
+ /** 디바이스의 푸시 수신을 비활성화합니다. */
100
+ disablePushDevice(
101
+ deviceSeq: number,
102
+ opts: { transactionId?: string } = {},
103
+ ): Promise<{ ok: boolean; seq: number }> {
104
+ return this.submit(
105
+ "account_device",
106
+ { seq: deviceSeq, push_enabled: false },
107
+ { transactionId: opts.transactionId },
108
+ );
109
+ }
110
+
111
+ // ─── 푸시 발송 API ────────────────────────────────────────────────────
112
+
113
+ /** 특정 계정에 푸시 알림을 발송합니다. */
114
+ pushSend(req: PushSendRequest): Promise<{ ok: boolean; seq: number }> {
115
+ return this._request("POST", "/v1/push/send", req);
116
+ }
117
+
118
+ /** 전체 사용자에게 푸시 알림을 발송합니다. */
119
+ pushSendAll(req: PushSendAllRequest): Promise<{
120
+ ok: boolean;
121
+ sent: number;
122
+ failed: number;
123
+ }> {
124
+ return this._request("POST", "/v1/push/send-all", req);
125
+ }
126
+
127
+ /** 푸시 발송 상태를 조회합니다. */
128
+ pushStatus(seq: number): Promise<{ ok: boolean; status: string }> {
129
+ return this._request("POST", `/v1/push/status/${seq}`, {});
130
+ }
131
+ };
132
+ }
@@ -0,0 +1,46 @@
1
+ import type { SmsSendRequest } from "../types";
2
+ import type { GConstructor, EntityServerClientBase } from "../client/base";
3
+
4
+ export function SmsMixin<TBase extends GConstructor<EntityServerClientBase>>(
5
+ Base: TBase,
6
+ ) {
7
+ return class SmsMixinClass extends Base {
8
+ // ─── SMS 발송 / 인증 ──────────────────────────────────────────────────
9
+
10
+ /** SMS를 발송합니다. */
11
+ smsSend(req: SmsSendRequest): Promise<{ ok: boolean; seq: number }> {
12
+ return this._request("POST", "/v1/sms/send", req);
13
+ }
14
+
15
+ /** SMS 발송 상태를 조회합니다. */
16
+ smsStatus(seq: number): Promise<{ ok: boolean; status: string }> {
17
+ return this._request("GET", `/v1/sms/status/${seq}`);
18
+ }
19
+
20
+ /** SMS 인증 코드를 발송합니다. */
21
+ smsVerificationSend(
22
+ phone: string,
23
+ opts: { purpose?: string } = {},
24
+ ): Promise<{ ok: boolean }> {
25
+ return this._request(
26
+ "POST",
27
+ "/v1/sms/verification/send",
28
+ { phone, ...opts },
29
+ false,
30
+ );
31
+ }
32
+
33
+ /** SMS 인증 코드를 검증합니다. */
34
+ smsVerificationVerify(
35
+ phone: string,
36
+ code: string,
37
+ ): Promise<{ ok: boolean; verified: boolean }> {
38
+ return this._request(
39
+ "POST",
40
+ "/v1/sms/verification/verify",
41
+ { phone, code },
42
+ false,
43
+ );
44
+ }
45
+ };
46
+ }
@@ -0,0 +1,20 @@
1
+ import type { SmtpSendRequest } from "../types";
2
+ import type { GConstructor, EntityServerClientBase } from "../client/base";
3
+
4
+ export function SmtpMixin<TBase extends GConstructor<EntityServerClientBase>>(
5
+ Base: TBase,
6
+ ) {
7
+ return class SmtpMixinClass extends Base {
8
+ // ─── SMTP 메일 발송 ───────────────────────────────────────────────────
9
+
10
+ /** SMTP로 메일을 발송합니다. */
11
+ smtpSend(req: SmtpSendRequest): Promise<{ ok: boolean; seq: number }> {
12
+ return this._request("POST", "/v1/smtp/send", req);
13
+ }
14
+
15
+ /** SMTP 발송 상태를 조회합니다. */
16
+ smtpStatus(seq: number): Promise<{ ok: boolean; status: string }> {
17
+ return this._request("POST", `/v1/smtp/status/${seq}`, {});
18
+ }
19
+ };
20
+ }
@@ -0,0 +1,75 @@
1
+ import type { QRCodeOptions, BarcodeOptions } from "../types";
2
+ import type { GConstructor, EntityServerClientBase } from "../client/base";
3
+
4
+ export function UtilsMixin<TBase extends GConstructor<EntityServerClientBase>>(
5
+ Base: TBase,
6
+ ) {
7
+ return class UtilsMixinClass extends Base {
8
+ // ─── Utils (QR / 바코드) ──────────────────────────────────────────────
9
+
10
+ /**
11
+ * QR 코드 PNG를 생성합니다. `ArrayBuffer`를 반환합니다.
12
+ *
13
+ * ```ts
14
+ * const buf = await client.qrcode("https://example.com");
15
+ * const blob = new Blob([buf], { type: "image/png" });
16
+ * img.src = URL.createObjectURL(blob);
17
+ * ```
18
+ */
19
+ qrcode(
20
+ content: string,
21
+ opts: QRCodeOptions = {},
22
+ ): Promise<ArrayBuffer> {
23
+ return this._requestBinary("POST", "/v1/utils/qrcode", {
24
+ content,
25
+ ...opts,
26
+ });
27
+ }
28
+
29
+ /**
30
+ * QR 코드를 base64/data URI JSON으로 반환합니다.
31
+ *
32
+ * ```ts
33
+ * const { data_uri } = await client.qrcodeBase64("https://example.com");
34
+ * img.src = data_uri;
35
+ * ```
36
+ */
37
+ qrcodeBase64(
38
+ content: string,
39
+ opts: QRCodeOptions = {},
40
+ ): Promise<{ ok: boolean; data: string; data_uri: string }> {
41
+ return this._request("POST", "/v1/utils/qrcode/base64", {
42
+ content,
43
+ ...opts,
44
+ });
45
+ }
46
+
47
+ /** QR 코드를 ASCII 아트 텍스트로 반환합니다. */
48
+ qrcodeText(
49
+ content: string,
50
+ opts: QRCodeOptions = {},
51
+ ): Promise<{ ok: boolean; text: string }> {
52
+ return this._request("POST", "/v1/utils/qrcode/text", {
53
+ content,
54
+ ...opts,
55
+ });
56
+ }
57
+
58
+ /**
59
+ * 바코드 PNG를 생성합니다. `ArrayBuffer`를 반환합니다.
60
+ *
61
+ * ```ts
62
+ * const buf = await client.barcode("1234567890128", { type: "ean13" });
63
+ * ```
64
+ */
65
+ barcode(
66
+ content: string,
67
+ opts: BarcodeOptions = {},
68
+ ): Promise<ArrayBuffer> {
69
+ return this._requestBinary("POST", "/v1/utils/barcode", {
70
+ content,
71
+ ...opts,
72
+ });
73
+ }
74
+ };
75
+ }
package/src/types.ts CHANGED
@@ -129,7 +129,6 @@ export interface RegisterPushDeviceOptions {
129
129
  export interface EntityServerClientOptions {
130
130
  baseUrl?: string;
131
131
  token?: string;
132
- packetMagicLen?: number;
133
132
  /**
134
133
  * `true`이면 인증된 POST/PUT 요청 바디를 XChaCha20-Poly1305로 암호화합니다.
135
134
  *
@@ -184,3 +183,206 @@ export interface EntityServerClientOptions {
184
183
  */
185
184
  hmacSecret?: string;
186
185
  }
186
+
187
+ // ─── SMTP ─────────────────────────────────────────────────────────────────────
188
+
189
+ /** `smtpSend()` 요청 파라미터입니다. */
190
+ export interface SmtpSendRequest {
191
+ /** provider 식별자 (생략 시 기본 provider 사용) */
192
+ provider?: string;
193
+ from?: string;
194
+ to: string[];
195
+ cc?: string[];
196
+ bcc?: string[];
197
+ subject?: string;
198
+ body_text?: string;
199
+ body_html?: string;
200
+ /** 이메일 템플릿 이름 */
201
+ template_name?: string;
202
+ /** 템플릿 변수 */
203
+ template_data?: Record<string, unknown>;
204
+ /** 첨부 파일 seq 배열 */
205
+ attachments?: number[];
206
+ reply_to?: string;
207
+ ref_entity?: string;
208
+ ref_seq?: number;
209
+ }
210
+
211
+ // ─── SMS ──────────────────────────────────────────────────────────────────────
212
+
213
+ /** `smsSend()` 요청 파라미터입니다. */
214
+ export interface SmsSendRequest {
215
+ provider?: string;
216
+ sender?: string;
217
+ /** 수신자 전화번호 (필수) */
218
+ receiver: string;
219
+ /** 메시지 내용 (필수) */
220
+ content: string;
221
+ /** MMS 제목 (LMS/MMS 전용) */
222
+ subject?: string;
223
+ image_url?: string;
224
+ ref_entity?: string;
225
+ ref_seq?: number;
226
+ }
227
+
228
+ // ─── Push 발송 API ──────────────────────────────────────────────────────────────
229
+
230
+ /** `pushSend()` 요청 파라미터 (`POST /v1/push/send`) */
231
+ export interface PushSendRequest {
232
+ /** 수신 계정 seq 배열 (필수) */
233
+ account_seqs: number[];
234
+ title: string;
235
+ body: string;
236
+ /** 커스텀 페이로드 */
237
+ data?: Record<string, string>;
238
+ ref_entity?: string;
239
+ ref_seq?: number;
240
+ }
241
+
242
+ /** `pushSendAll()` 요청 파라미터 (`POST /v1/push/send-all`) */
243
+ export interface PushSendAllRequest {
244
+ title: string;
245
+ body: string;
246
+ data?: Record<string, string>;
247
+ ref_entity?: string;
248
+ ref_seq?: number;
249
+ }
250
+
251
+ // ─── 알림톡 / 친구톡 ───────────────────────────────────────────────────────────
252
+
253
+ /** 알림톡 / 친구톡 버튼 */
254
+ export interface AlimtalkButton {
255
+ name: string;
256
+ type: string;
257
+ url_mobile?: string;
258
+ url_pc?: string;
259
+ }
260
+
261
+ /** `alimtalkSend()` 요청 파라미터 */
262
+ export interface AlimtalkSendRequest {
263
+ /** 알림톡 템플릿 코드 (필수) */
264
+ template_code: string;
265
+ /** 수신자 전화번호 (필수) */
266
+ receiver: string;
267
+ variables?: Record<string, string>;
268
+ provider?: string;
269
+ }
270
+
271
+ /** `friendtalkSend()` 요청 파라미터 */
272
+ export interface FriendtalkSendRequest {
273
+ /** 수신자 전화번호 (필수) */
274
+ receiver: string;
275
+ /** 메시지 내용 (필수) */
276
+ content: string;
277
+ /** 메시지 타입 (`"text"` | `"image"` | `"wide_image"` 등, 기본 `"text"`) */
278
+ msg_type?: string;
279
+ image_url?: string;
280
+ image_link?: string;
281
+ /** 광고 여부 (기본 `true`) */
282
+ is_ad?: boolean;
283
+ buttons?: AlimtalkButton[];
284
+ carousel_json?: string;
285
+ items_json?: string;
286
+ header?: string;
287
+ provider?: string;
288
+ }
289
+
290
+ // ─── PG 결제 ──────────────────────────────────────────────────────────────────
291
+
292
+ /** `pgCreateOrder()` 요청 파라미터 */
293
+ export interface PgCreateOrderRequest {
294
+ /** 결제 금액 (필수) */
295
+ amount: number;
296
+ /** 주문명 (필수) */
297
+ order_name: string;
298
+ currency?: string;
299
+ customer_name?: string;
300
+ customer_email?: string;
301
+ provider?: string;
302
+ metadata?: Record<string, unknown>;
303
+ }
304
+
305
+ /** `pgConfirmPayment()` 요청 파라미터 */
306
+ export interface PgConfirmPaymentRequest {
307
+ payment_key: string;
308
+ order_id: string;
309
+ amount: number;
310
+ }
311
+
312
+ /** `pgCancelPayment()` 요청 파라미터 */
313
+ export interface PgCancelPaymentRequest {
314
+ /** 취소 사유 (필수) */
315
+ cancel_reason: string;
316
+ /** 부분 취소 금액 (생략 시 전액 취소) */
317
+ cancel_amount?: number;
318
+ refund_account?: {
319
+ bank: string;
320
+ account_number: string;
321
+ holder_name: string;
322
+ };
323
+ }
324
+
325
+ // ─── 본인인증 ──────────────────────────────────────────────────────────────────
326
+
327
+ /** `identityRequest()` 요청 파라미터 */
328
+ export interface IdentityRequestOptions {
329
+ /** 인증 목적 (필수, 예: `"signup"`, `"password_reset"`) */
330
+ purpose: string;
331
+ /** 인증 방법 (예: `"simple"`, `"pass"`) */
332
+ method?: string;
333
+ provider?: string;
334
+ }
335
+
336
+ // ─── Utils ────────────────────────────────────────────────────────────────────
337
+
338
+ /** `qrcode()` / `qrcodeBase64()` / `qrcodeText()` 공통 옵션 */
339
+ export interface QRCodeOptions {
340
+ /** PNG 크기 픽셀 (기본 256, 최대 2048) */
341
+ size?: number;
342
+ /** 오류 복구 수준 (기본 `"medium"`) */
343
+ error_correction?: "low" | "medium" | "high" | "highest";
344
+ /** 전경색 hex (기본 `"#000000"`) */
345
+ fg_color?: string;
346
+ /** 배경색 hex (기본 `"#ffffff"`) */
347
+ bg_color?: string;
348
+ }
349
+
350
+ /** `barcode()` 옵션 */
351
+ export interface BarcodeOptions {
352
+ /** 바코드 타입 (기본 `"code128"`) */
353
+ type?:
354
+ | "code128"
355
+ | "code39"
356
+ | "ean13"
357
+ | "ean8"
358
+ | "codabar"
359
+ | "datamatrix"
360
+ | "itf";
361
+ /** 너비 픽셀 (기본 300, 최대 2048) */
362
+ width?: number;
363
+ /** 높이 픽셀 (기본 100, 최대 2048) */
364
+ height?: number;
365
+ }
366
+
367
+ // ─── 파일 ─────────────────────────────────────────────────────────────────────
368
+
369
+ /** 파일 메타 정보 */
370
+ export interface FileMeta {
371
+ uuid: string;
372
+ original_name: string;
373
+ size: number;
374
+ mime_type: string;
375
+ entity: string;
376
+ ref_seq?: number;
377
+ is_public?: boolean;
378
+ created_time: string;
379
+ url?: string;
380
+ }
381
+
382
+ /** `fileUpload()` 옵션 */
383
+ export interface FileUploadOptions {
384
+ /** 파일에 연결할 ref_seq */
385
+ refSeq?: number;
386
+ /** 공개 파일 여부 (기본 서버 설정 따름) */
387
+ isPublic?: boolean;
388
+ }