entity-server-client 0.2.6 → 0.3.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/README.md +32 -0
- package/build.mjs +7 -0
- package/docs/api/alimtalk.md +62 -0
- package/docs/api/auth.md +256 -0
- package/docs/api/email.md +37 -0
- package/docs/api/entity.md +273 -0
- package/docs/api/file.md +80 -0
- package/docs/api/health.md +41 -0
- package/docs/api/identity.md +32 -0
- package/docs/api/import.md +34 -0
- package/docs/api/packet.md +25 -0
- package/docs/api/pg.md +90 -0
- package/docs/api/push.md +107 -0
- package/docs/api/react.md +141 -0
- package/docs/api/setup.md +43 -0
- package/docs/api/sms.md +45 -0
- package/docs/api/smtp.md +33 -0
- package/docs/api/transaction.md +50 -0
- package/docs/api/utils.md +52 -0
- package/docs/apis.md +22 -780
- package/docs/react.md +58 -0
- package/package.json +6 -1
- package/src/EntityServerClient.ts +5 -31
- package/src/client/base.ts +71 -12
- package/src/client/packet.ts +8 -31
- package/src/client/request.ts +52 -6
- package/src/client/utils.ts +5 -6
- package/src/mixins/auth.ts +14 -158
- package/src/mixins/push.ts +0 -23
- package/src/mixins/utils.ts +32 -1
- package/src/packet.ts +84 -0
- package/src/types.ts +15 -125
- package/tests/packet.test.mjs +50 -0
- package/dist/EntityServerClient.d.ts +0 -709
- package/dist/client/base.d.ts +0 -59
- package/dist/client/hmac.d.ts +0 -8
- package/dist/client/packet.d.ts +0 -24
- package/dist/client/request.d.ts +0 -15
- package/dist/client/utils.d.ts +0 -8
- package/dist/hooks/useEntityServer.d.ts +0 -63
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -7
- package/dist/mixins/alimtalk.d.ts +0 -56
- package/dist/mixins/auth.d.ts +0 -167
- package/dist/mixins/email.d.ts +0 -51
- package/dist/mixins/entity.d.ts +0 -119
- package/dist/mixins/file.d.ts +0 -78
- package/dist/mixins/identity.d.ts +0 -52
- package/dist/mixins/pg.d.ts +0 -63
- package/dist/mixins/push.d.ts +0 -110
- package/dist/mixins/sms.d.ts +0 -55
- package/dist/mixins/smtp.d.ts +0 -44
- package/dist/mixins/utils.d.ts +0 -70
- package/dist/react.d.ts +0 -1
- package/dist/react.js +0 -2
- package/dist/react.js.map +0 -7
- package/dist/types.d.ts +0 -329
- package/src/mixins/alimtalk.ts +0 -35
- package/src/mixins/email.ts +0 -46
- package/src/mixins/identity.ts +0 -35
- package/src/mixins/pg.ts +0 -58
- package/src/mixins/sms.ts +0 -46
package/dist/client/base.d.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { EntityServerClientOptions } from "../types";
|
|
2
|
-
import { type RequestOptions } from "./request";
|
|
3
|
-
export type GConstructor<T = object> = new (...args: any[]) => T;
|
|
4
|
-
export declare class EntityServerClientBase {
|
|
5
|
-
baseUrl: string;
|
|
6
|
-
token: string;
|
|
7
|
-
apiKey: string;
|
|
8
|
-
hmacSecret: string;
|
|
9
|
-
encryptRequests: boolean;
|
|
10
|
-
activeTxId: string | null;
|
|
11
|
-
keepSession: boolean;
|
|
12
|
-
refreshBuffer: number;
|
|
13
|
-
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
14
|
-
onSessionExpired?: (error: Error) => void;
|
|
15
|
-
_sessionRefreshToken: string | null;
|
|
16
|
-
_refreshTimer: ReturnType<typeof setTimeout> | null;
|
|
17
|
-
/**
|
|
18
|
-
* EntityServerClient 인스턴스를 생성합니다.
|
|
19
|
-
*
|
|
20
|
-
* 기본값:
|
|
21
|
-
* - `baseUrl`: `VITE_ENTITY_SERVER_URL` 또는 `http://localhost:47200`
|
|
22
|
-
*/
|
|
23
|
-
constructor(options?: EntityServerClientOptions);
|
|
24
|
-
/** baseUrl, token, encryptRequests 값을 런타임에 갱신합니다. */
|
|
25
|
-
configure(options: Partial<EntityServerClientOptions>): void;
|
|
26
|
-
/** 인증 요청에 사용할 JWT Access Token을 설정합니다. */
|
|
27
|
-
setToken(token: string): void;
|
|
28
|
-
/** HMAC 인증용 API Key를 설정합니다. */
|
|
29
|
-
setApiKey(apiKey: string): void;
|
|
30
|
-
/** HMAC 인증용 시크릿을 설정합니다. */
|
|
31
|
-
setHmacSecret(secret: string): void;
|
|
32
|
-
/** 암호화 요청 활성화 여부를 설정합니다. */
|
|
33
|
-
setEncryptRequests(value: boolean): void;
|
|
34
|
-
/** @internal 자동 토큰 갱신 타이머를 시작합니다. */
|
|
35
|
-
_scheduleKeepSession(refreshToken: string, expiresIn: number, refreshFn: (rt: string) => Promise<{
|
|
36
|
-
access_token: string;
|
|
37
|
-
expires_in: number;
|
|
38
|
-
}>): void;
|
|
39
|
-
/** @internal 자동 갱신 타이머를 정리합니다. */
|
|
40
|
-
_clearRefreshTimer(): void;
|
|
41
|
-
/**
|
|
42
|
-
* 세션 유지 타이머를 중지합니다.
|
|
43
|
-
* `logout()` 호출 시 자동으로 중지되며, 직접 호출이 필요한 경우는 드뭅니다.
|
|
44
|
-
*/
|
|
45
|
-
stopKeepSession(): void;
|
|
46
|
-
/**
|
|
47
|
-
* 요청 바디를 파싱합니다.
|
|
48
|
-
* `application/octet-stream`이면 XChaCha20-Poly1305 복호화, 그 외는 JSON 파싱합니다.
|
|
49
|
-
*
|
|
50
|
-
* @param requireEncrypted `true`이면 암호화된 요청만 허용합니다.
|
|
51
|
-
*/
|
|
52
|
-
readRequestBody<T = Record<string, unknown>>(body: ArrayBuffer | Uint8Array | string | T | null | undefined, contentType?: string, requireEncrypted?: boolean): T;
|
|
53
|
-
get _reqOpts(): RequestOptions;
|
|
54
|
-
_request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
55
|
-
/** PNG/바이너리 응답을 ArrayBuffer로 반환합니다. (QR, 바코드 등) */
|
|
56
|
-
_requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
57
|
-
/** multipart/form-data 요청을 보냅니다. (파일 업로드 등) */
|
|
58
|
-
_requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
59
|
-
}
|
package/dist/client/hmac.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HMAC-SHA256 서명 헤더를 생성합니다.
|
|
3
|
-
*
|
|
4
|
-
* 서명 대상: `METHOD|PATH|TIMESTAMP|NONCE|BODY`
|
|
5
|
-
*
|
|
6
|
-
* @returns `X-API-Key`, `X-Timestamp`, `X-Nonce`, `X-Signature` 헤더 객체
|
|
7
|
-
*/
|
|
8
|
-
export declare function buildHmacHeaders(method: string, path: string, bodyBytes: Uint8Array, apiKey: string, hmacSecret: string): Record<string, string>;
|
package/dist/client/packet.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 패킷 암호화 키를 유도합니다.
|
|
3
|
-
* - HMAC 모드 (`hmacSecret` 유효 시): HKDF-SHA256(hmac_secret, "entity-server:packet-encryption")
|
|
4
|
-
* - JWT 모드: HKDF-SHA256(jwt_token, "entity-server:packet-encryption")
|
|
5
|
-
*/
|
|
6
|
-
export declare function derivePacketKey(hmacSecret: string, token: string): Uint8Array;
|
|
7
|
-
/**
|
|
8
|
-
* 평문 바이트를 XChaCha20-Poly1305로 암호화합니다.
|
|
9
|
-
* 포맷: [random_magic:K][random_nonce:24][ciphertext+tag]
|
|
10
|
-
* K = 2 + key[31] % 14 (패킷 키에서 자동 파생)
|
|
11
|
-
*/
|
|
12
|
-
export declare function encryptPacket(plaintext: Uint8Array, key: Uint8Array): Uint8Array;
|
|
13
|
-
/**
|
|
14
|
-
* XChaCha20-Poly1305 패킷을 복호화해 JSON 객체로 변환합니다.
|
|
15
|
-
* 포맷: [magic:K][nonce:24][ciphertext+tag]
|
|
16
|
-
* K = 2 + key[31] % 14 (패킷 키에서 자동 파생)
|
|
17
|
-
*/
|
|
18
|
-
export declare function decryptPacket<T>(buffer: ArrayBuffer, key: Uint8Array): T;
|
|
19
|
-
/**
|
|
20
|
-
* 요청 바디를 파싱합니다. `application/octet-stream`이면 복호화, 그 외는 JSON 파싱합니다.
|
|
21
|
-
*
|
|
22
|
-
* @param requireEncrypted `true`이면 암호화된 요청만 허용합니다.
|
|
23
|
-
*/
|
|
24
|
-
export declare function parseRequestBody<T>(body: ArrayBuffer | Uint8Array | string | T | null | undefined, contentType: string, requireEncrypted: boolean, key: Uint8Array): T;
|
package/dist/client/request.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface RequestOptions {
|
|
2
|
-
baseUrl: string;
|
|
3
|
-
token: string;
|
|
4
|
-
apiKey: string;
|
|
5
|
-
hmacSecret: string;
|
|
6
|
-
encryptRequests: boolean;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Entity Server에 HTTP 요청을 보냅니다.
|
|
10
|
-
*
|
|
11
|
-
* - `encryptRequests` 활성화 시 인증된 POST 바디를 자동 암호화합니다.
|
|
12
|
-
* - 응답이 `application/octet-stream`이면 자동 복호화합니다.
|
|
13
|
-
* - JSON 응답의 `ok`가 false이면 에러를 던집니다.
|
|
14
|
-
*/
|
|
15
|
-
export declare function entityRequest<T>(opts: RequestOptions, method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
package/dist/client/utils.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 환경변수를 읽습니다.
|
|
3
|
-
* - 브라우저/Vite: `import.meta.env`
|
|
4
|
-
* - Node.js: `process.env`
|
|
5
|
-
*/
|
|
6
|
-
export declare function readEnv(name: string): string | undefined;
|
|
7
|
-
/** 쿼리 파라미터 객체를 URL 쿼리 문자열로 변환합니다. `orderBy` 키는 `order_by`로 변환됩니다. */
|
|
8
|
-
export declare function buildQuery(params: Record<string, unknown>): string;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { EntityServerClient, type EntityQueryRequest, type EntityServerClientOptions } from "../index";
|
|
2
|
-
export interface UseEntityServerOptions extends EntityServerClientOptions {
|
|
3
|
-
singleton?: boolean;
|
|
4
|
-
tokenResolver?: () => string | undefined | null;
|
|
5
|
-
/**
|
|
6
|
-
* 페이지 새로고침 후 로그인 상태를 복원할 때 사용합니다.
|
|
7
|
-
* 이 값이 있으면 마운트 시 `client.refreshToken()`을 호출해 새 access_token을 발급받습니다.
|
|
8
|
-
* `keepSession: true`와 함께 사용하면 세션 유지 타이머도 재시작됩니다.
|
|
9
|
-
* 갱신 성공 시 `onTokenRefreshed` 콜백이 호출됩니다.
|
|
10
|
-
*/
|
|
11
|
-
resumeSession?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface UseEntityServerResult {
|
|
14
|
-
/** EntityServerClient 인스턴스 (read 전용 메서드 직접 호출 시 사용) */
|
|
15
|
-
client: EntityServerClient;
|
|
16
|
-
/** submit 또는 delete 진행 중 여부 */
|
|
17
|
-
isPending: boolean;
|
|
18
|
-
/** 마지막 mutation 에러 (없으면 null) */
|
|
19
|
-
error: Error | null;
|
|
20
|
-
/** 에러·결과 상태 초기화 */
|
|
21
|
-
reset: () => void;
|
|
22
|
-
/** entity 데이터 생성/수정 (seq 없으면 INSERT, 있으면 UPDATE) */
|
|
23
|
-
submit: (entity: string, data: Record<string, unknown>, opts?: {
|
|
24
|
-
transactionId?: string;
|
|
25
|
-
skipHooks?: boolean;
|
|
26
|
-
}) => Promise<{
|
|
27
|
-
ok: boolean;
|
|
28
|
-
seq: number;
|
|
29
|
-
}>;
|
|
30
|
-
/** entity 데이터 삭제 */
|
|
31
|
-
del: (entity: string, seq: number, opts?: {
|
|
32
|
-
transactionId?: string;
|
|
33
|
-
hard?: boolean;
|
|
34
|
-
skipHooks?: boolean;
|
|
35
|
-
}) => Promise<{
|
|
36
|
-
ok: boolean;
|
|
37
|
-
deleted: number;
|
|
38
|
-
}>;
|
|
39
|
-
/** 커스텀 SQL 조회 */
|
|
40
|
-
query: <T = unknown>(entity: string, req: EntityQueryRequest) => Promise<{
|
|
41
|
-
ok: boolean;
|
|
42
|
-
data: {
|
|
43
|
-
items: T[];
|
|
44
|
-
count: number;
|
|
45
|
-
};
|
|
46
|
-
}>;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* React 환경에서 EntityServerClient 인스턴스와 mutation 상태를 반환합니다.
|
|
50
|
-
*
|
|
51
|
-
* - `singleton=true`(기본): 패키지 전역 `entityServer` 인스턴스를 사용합니다.
|
|
52
|
-
* - `singleton=false`: 컴포넌트 스코프의 새 인스턴스를 생성합니다.
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```tsx
|
|
56
|
-
* const { submit, del, isPending, error, reset } = useEntityServer();
|
|
57
|
-
*
|
|
58
|
-
* const handleSave = async () => {
|
|
59
|
-
* await submit("account", { name: "홍길동" });
|
|
60
|
-
* };
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
export declare function useEntityServer(options?: UseEntityServerOptions): UseEntityServerResult;
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function S(n){let r=import.meta;if(r?.env?.[n]!=null)return r.env[n];if(typeof process<"u"&&process.env&&process.env[n]!=null)return process.env[n]}function P(n){return Object.entries(n).filter(([,r])=>r!=null).map(([r,e])=>`${encodeURIComponent(r==="orderBy"?"order_by":r)}=${encodeURIComponent(String(e))}`).join("&")}import{xchacha20poly1305 as v}from"@noble/ciphers/chacha";import{sha256 as K}from"@noble/hashes/sha2";import{hkdf as L}from"@noble/hashes/hkdf";function h(n,r){let e=n||r,t=new TextEncoder().encode("entity-server:hkdf:v1"),s=new TextEncoder().encode("entity-server:packet-encryption");return L(K,new TextEncoder().encode(e),t,s,32)}function _(n,r){let e=2+r[31]%14,t=new Uint8Array(e),s=new Uint8Array(24);crypto.getRandomValues(t),crypto.getRandomValues(s);let a=v(r,s).encrypt(n),o=new Uint8Array(e+24+a.length);return o.set(t,0),o.set(s,e),o.set(a,e+24),o}function y(n,r){let e=2+r[31]%14,t=new Uint8Array(n);if(t.length<e+24+16)throw new Error("Encrypted packet too short");let s=t.slice(e,e+24),i=t.slice(e+24),o=v(r,s).decrypt(i);return JSON.parse(new TextDecoder().decode(o))}function q(n,r,e,t){let s=r.toLowerCase().includes("application/octet-stream");if(e&&!s)throw new Error("Encrypted request required: Content-Type must be application/octet-stream");if(s){if(n==null)throw new Error("Encrypted request body is empty");if(n instanceof ArrayBuffer)return y(n,t);if(n instanceof Uint8Array){let i=n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength);return y(i,t)}throw new Error("Encrypted request body must be ArrayBuffer or Uint8Array")}return n==null||n===""?{}:typeof n=="string"?JSON.parse(n):n}import{sha256 as F}from"@noble/hashes/sha2";import{hmac as D}from"@noble/hashes/hmac";function x(n,r,e,t,s){let i=String(Math.floor(Date.now()/1e3)),a=crypto.randomUUID(),o=new TextEncoder().encode(`${n}|${r}|${i}|${a}|`),u=new Uint8Array(o.length+e.length);u.set(o,0),u.set(e,o.length);let p=[...D(F,new TextEncoder().encode(s),u)].map(m=>m.toString(16).padStart(2,"0")).join("");return{"X-API-Key":t,"X-Timestamp":i,"X-Nonce":a,"X-Signature":p}}async function R(n,r,e,t,s=!0,i={}){let{baseUrl:a,token:o,apiKey:u,hmacSecret:c,encryptRequests:p}=n,m=s&&!!(u&&c),g={"Content-Type":"application/json",...i};!m&&s&&o&&(g.Authorization=`Bearer ${o}`);let l=null;if(t!=null)if(p&&s&&(o||m)&&r!=="GET"&&r!=="HEAD"){let H=h(c,o);l=_(new TextEncoder().encode(JSON.stringify(t)),H),g["Content-Type"]="application/octet-stream"}else l=JSON.stringify(t);if(m){let d=l instanceof Uint8Array?l:typeof l=="string"?new TextEncoder().encode(l):new Uint8Array(0);Object.assign(g,x(r,e,d,u,c))}let f=await fetch(a+e,{method:r,headers:g,...l!=null?{body:l}:{}});if((f.headers.get("Content-Type")??"").includes("application/octet-stream")){let d=h(c,o);return y(await f.arrayBuffer(),d)}let b=await f.json();if(!b.ok){let d=new Error(b.message??`EntityServer error (HTTP ${f.status})`);throw d.status=f.status,d}return b}var k=class{baseUrl;token;apiKey;hmacSecret;encryptRequests;activeTxId=null;keepSession;refreshBuffer;onTokenRefreshed;onSessionExpired;_sessionRefreshToken=null;_refreshTimer=null;constructor(r={}){let e=S("VITE_ENTITY_SERVER_URL");this.baseUrl=(r.baseUrl??e??"http://localhost:47200").replace(/\/$/,""),this.token=r.token??"",this.apiKey=r.apiKey??"",this.hmacSecret=r.hmacSecret??"",this.encryptRequests=r.encryptRequests??!1,this.keepSession=r.keepSession??!1,this.refreshBuffer=r.refreshBuffer??60,this.onTokenRefreshed=r.onTokenRefreshed,this.onSessionExpired=r.onSessionExpired}configure(r){r.baseUrl&&(this.baseUrl=r.baseUrl.replace(/\/$/,"")),typeof r.token=="string"&&(this.token=r.token),typeof r.encryptRequests=="boolean"&&(this.encryptRequests=r.encryptRequests),typeof r.apiKey=="string"&&(this.apiKey=r.apiKey),typeof r.hmacSecret=="string"&&(this.hmacSecret=r.hmacSecret),typeof r.keepSession=="boolean"&&(this.keepSession=r.keepSession),typeof r.refreshBuffer=="number"&&(this.refreshBuffer=r.refreshBuffer),r.onTokenRefreshed&&(this.onTokenRefreshed=r.onTokenRefreshed),r.onSessionExpired&&(this.onSessionExpired=r.onSessionExpired)}setToken(r){this.token=r}setApiKey(r){this.apiKey=r}setHmacSecret(r){this.hmacSecret=r}setEncryptRequests(r){this.encryptRequests=r}_scheduleKeepSession(r,e,t){this._clearRefreshTimer(),this._sessionRefreshToken=r;let s=Math.max((e-this.refreshBuffer)*1e3,0);this._refreshTimer=setTimeout(async()=>{if(this._sessionRefreshToken)try{let i=await t(this._sessionRefreshToken);this.onTokenRefreshed?.(i.access_token,i.expires_in),this._scheduleKeepSession(this._sessionRefreshToken,i.expires_in,t)}catch(i){this._clearRefreshTimer(),this.onSessionExpired?.(i instanceof Error?i:new Error(String(i)))}},s)}_clearRefreshTimer(){this._refreshTimer!==null&&(clearTimeout(this._refreshTimer),this._refreshTimer=null)}stopKeepSession(){this._clearRefreshTimer(),this._sessionRefreshToken=null}readRequestBody(r,e="application/json",t=!1){let s=h(this.hmacSecret,this.token);return q(r,e,t,s)}get _reqOpts(){return{baseUrl:this.baseUrl,token:this.token,apiKey:this.apiKey,hmacSecret:this.hmacSecret,encryptRequests:this.encryptRequests}}_request(r,e,t,s=!0,i){return R(this._reqOpts,r,e,t,s,i)}async _requestBinary(r,e,t,s=!0){let i={"Content-Type":"application/json"};s&&this.token&&(i.Authorization=`Bearer ${this.token}`),this.apiKey&&(i["X-API-Key"]=this.apiKey);let a=await fetch(this.baseUrl+e,{method:r,headers:i,...t!=null?{body:JSON.stringify(t)}:{}});if(!a.ok){let o=await a.text(),u=new Error(`HTTP ${a.status}: ${o}`);throw u.status=a.status,u}return a.arrayBuffer()}async _requestForm(r,e,t,s=!0){let i={};s&&this.token&&(i.Authorization=`Bearer ${this.token}`),this.apiKey&&(i["X-API-Key"]=this.apiKey);let a=await fetch(this.baseUrl+e,{method:r,headers:i,body:t}),o=await a.json();if(!o.ok){let u=new Error(o.message??`EntityServer error (HTTP ${a.status})`);throw u.status=a.status,u}return o}};function E(n){return class extends n{async checkHealth(){let t=await(await fetch(`${this.baseUrl}/v1/health`,{signal:AbortSignal.timeout(3e3)})).json();return t.packet_encryption&&(this.encryptRequests=!0),t}async login(e,t){let s=await this._request("POST","/v1/auth/login",{email:e,passwd:t},!1);return this.token=s.data.access_token,this.keepSession&&this._scheduleKeepSession(s.data.refresh_token,s.data.expires_in,i=>this.refreshToken(i)),s.data}async refreshToken(e){let t=await this._request("POST","/v1/auth/refresh",{refresh_token:e},!1);return this.token=t.data.access_token,this.keepSession&&this._scheduleKeepSession(e,t.data.expires_in,s=>this.refreshToken(s)),t.data}async logout(e){this.stopKeepSession();let t=await this._request("POST","/v1/auth/logout",{refresh_token:e},!1);return this.token="",t}me(){return this._request("GET","/v1/auth/me")}changePassword(e,t){return this._request("POST","/v1/auth/change-password",{current_passwd:e,new_passwd:t})}withdraw(e){return this._request("POST","/v1/auth/withdraw",e?{passwd:e}:{})}reactivate(e){return this._request("POST","/v1/auth/reactivate",e,!1)}passwordResetRequest(e){return this._request("POST","/v1/auth/password-reset",{email:e},!1)}passwordResetConfirm(e,t){return this._request("POST","/v1/auth/password-reset/confirm",{token:e,new_passwd:t},!1)}oauthLink(e,t,s){return this._request("POST","/v1/auth/oauth/link",{provider:e,code:t,...s?{state:s}:{}})}oauthUnlink(e){return this._request("DELETE",`/v1/auth/oauth/link/${e}`)}oauthProviders(){return this._request("GET","/v1/auth/oauth/providers")}oauthTokenRefresh(e){return this._request("POST",`/v1/auth/oauth/refresh/${e}`)}twoFactorSetup(){return this._request("POST","/v1/auth/2fa/setup")}twoFactorSetupVerify(e,t){return this._request("POST","/v1/auth/2fa/setup/verify",{code:e,setup_token:t})}twoFactorDisable(e){return this._request("DELETE","/v1/auth/2fa",{code:e})}twoFactorStatus(){return this._request("GET","/v1/auth/2fa/status")}twoFactorVerify(e,t){return this._request("POST","/v1/auth/2fa/verify",{two_factor_token:e,code:t},!1)}twoFactorRecovery(e,t){return this._request("POST","/v1/auth/2fa/recovery",{two_factor_token:e,recovery_code:t},!1)}twoFactorRegenerateRecovery(e){return this._request("POST","/v1/auth/2fa/recovery/regenerate",{code:e})}}}function w(n){return class extends n{async transStart(){let e=await this._request("POST","/v1/transaction/start",void 0,!1);return this.activeTxId=e.transaction_id,this.activeTxId}transRollback(e){let t=e??this.activeTxId;return t?(this.activeTxId=null,this._request("POST",`/v1/transaction/rollback/${t}`)):Promise.reject(new Error("No active transaction. Call transStart() first."))}transCommit(e){let t=e??this.activeTxId;return t?(this.activeTxId=null,this._request("POST",`/v1/transaction/commit/${t}`)):Promise.reject(new Error("No active transaction. Call transStart() first."))}get(e,t,s={}){let i=s.skipHooks?"?skipHooks=true":"";return this._request("GET",`/v1/entity/${e}/${t}${i}`)}find(e,t,s={}){let i=s.skipHooks?"?skipHooks=true":"";return this._request("POST",`/v1/entity/${e}/find${i}`,t??{})}list(e,t={}){let{conditions:s,fields:i,orderDir:a,orderBy:o,...u}=t,c={page:1,limit:20,...u};return o&&(c.orderBy=a==="DESC"?`-${o}`:o),i?.length&&(c.fields=i.join(",")),this._request("POST",`/v1/entity/${e}/list?${P(c)}`,s??{})}count(e,t){return this._request("POST",`/v1/entity/${e}/count`,t??{})}query(e,t){return this._request("POST",`/v1/entity/${e}/query`,t)}submit(e,t,s={}){let i=s.transactionId??this.activeTxId,a=i?{"X-Transaction-ID":i}:void 0,o=s.skipHooks?"?skipHooks=true":"";return this._request("POST",`/v1/entity/${e}/submit${o}`,t,!0,a)}delete(e,t,s={}){let i=new URLSearchParams;s.hard&&i.set("hard","true"),s.skipHooks&&i.set("skipHooks","true");let a=i.size?`?${i}`:"",o=s.transactionId??this.activeTxId,u=o?{"X-Transaction-ID":o}:void 0;return this._request("POST",`/v1/entity/${e}/delete/${t}${a}`,void 0,!0,u)}history(e,t,s={}){return this._request("GET",`/v1/entity/${e}/history/${t}?${P({page:1,limit:50,...s})}`)}rollback(e,t){return this._request("POST",`/v1/entity/${e}/rollback/${t}`)}}}function C(n){return class extends n{push(e,t,s={}){return this.submit(e,t,s)}pushLogList(e={}){return this.list("push_log",e)}registerPushDevice(e,t,s,i={}){let{platform:a,deviceType:o,browser:u,browserVersion:c,pushEnabled:p=!0,transactionId:m}=i;return this.submit("account_device",{id:t,account_seq:e,push_token:s,push_enabled:p,...a?{platform:a}:{},...o?{device_type:o}:{},...u?{browser:u}:{},...c?{browser_version:c}:{}},{transactionId:m})}updatePushDeviceToken(e,t,s={}){let{pushEnabled:i=!0,transactionId:a}=s;return this.submit("account_device",{seq:e,push_token:t,push_enabled:i},{transactionId:a})}disablePushDevice(e,t={}){return this.submit("account_device",{seq:e,push_enabled:!1},{transactionId:t.transactionId})}pushSend(e){return this._request("POST","/v1/push/send",e)}pushSendAll(e){return this._request("POST","/v1/push/send-all",e)}pushStatus(e){return this._request("POST",`/v1/push/status/${e}`,{})}}}function O(n){return class extends n{emailVerificationSend(e){return this._request("POST","/v1/email/verification/send",{email:e},!1)}emailVerificationConfirm(e){return this._request("POST","/v1/email/verification/confirm",{token:e},!1)}emailVerificationStatus(){return this._request("GET","/v1/email/verification/status")}emailChange(e,t){return this._request("POST","/v1/email/change",{new_email:e,...t?{code:t}:{}})}}}function B(n){return class extends n{smsSend(e){return this._request("POST","/v1/sms/send",e)}smsStatus(e){return this._request("GET",`/v1/sms/status/${e}`)}smsVerificationSend(e,t={}){return this._request("POST","/v1/sms/verification/send",{phone:e,...t},!1)}smsVerificationVerify(e,t){return this._request("POST","/v1/sms/verification/verify",{phone:e,code:t},!1)}}}function $(n){return class extends n{smtpSend(e){return this._request("POST","/v1/smtp/send",e)}smtpStatus(e){return this._request("POST",`/v1/smtp/status/${e}`,{})}}}function A(n){return class extends n{alimtalkSend(e){return this._request("POST","/v1/alimtalk/send",e)}alimtalkStatus(e){return this._request("GET",`/v1/alimtalk/status/${e}`)}alimtalkTemplates(){return this._request("GET","/v1/alimtalk/templates")}friendtalkSend(e){return this._request("POST","/v1/friendtalk/send",e)}}}function U(n){return class extends n{pgCreateOrder(e){return this._request("POST","/v1/pg/orders",e)}pgGetOrder(e){return this._request("GET",`/v1/pg/orders/${e}`)}pgConfirmPayment(e){return this._request("POST","/v1/pg/confirm",e)}pgCancelPayment(e,t){return this._request("POST",`/v1/pg/orders/${e}/cancel`,t)}pgSyncPayment(e){return this._request("POST",`/v1/pg/orders/${e}/sync`,{})}pgConfig(){return this._request("GET","/v1/pg/config",void 0,!1)}}}function I(n){return class extends n{async fileUpload(e,t,s={}){let i=new FormData;return i.append("file",t,t instanceof File?t.name:"upload"),s.refSeq!=null&&i.append("ref_seq",String(s.refSeq)),s.isPublic!=null&&i.append("is_public",s.isPublic?"true":"false"),this._requestForm("POST",`/v1/files/${e}/upload`,i)}fileDownload(e,t){return this._requestBinary("POST",`/v1/files/${e}/download/${t}`,{})}fileDelete(e,t){return this._request("POST",`/v1/files/${e}/delete/${t}`,{})}fileList(e,t={}){return this._request("POST",`/v1/files/${e}/list`,t.refSeq?{ref_seq:t.refSeq}:{})}fileMeta(e,t){return this._request("POST",`/v1/files/${e}/meta/${t}`,{})}fileToken(e){return this._request("POST",`/v1/files/token/${e}`,{})}fileUrl(e){return`${this.baseUrl}/v1/files/${e}`}}}function M(n){return class extends n{identityRequest(e){return this._request("POST","/v1/identity/request",e)}identityResult(e){return this._request("GET",`/v1/identity/result/${e}`)}identityVerifyCI(e){return this._request("POST","/v1/identity/verify-ci",{ci_hash:e})}}}function G(n){return class extends n{qrcode(e,t={}){return this._requestBinary("POST","/v1/utils/qrcode",{content:e,...t})}qrcodeBase64(e,t={}){return this._request("POST","/v1/utils/qrcode/base64",{content:e,...t})}qrcodeText(e,t={}){return this._request("POST","/v1/utils/qrcode/text",{content:e,...t})}barcode(e,t={}){return this._requestBinary("POST","/v1/utils/barcode",{content:e,...t})}}}var T=class extends G(M(I(U(A($(B(O(C(w(E(k))))))))))){};var De=new T;export{T as EntityServerClient,De as entityServer};
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/client/utils.ts", "../src/client/packet.ts", "../src/client/hmac.ts", "../src/client/request.ts", "../src/client/base.ts", "../src/mixins/auth.ts", "../src/mixins/entity.ts", "../src/mixins/push.ts", "../src/mixins/email.ts", "../src/mixins/sms.ts", "../src/mixins/smtp.ts", "../src/mixins/alimtalk.ts", "../src/mixins/pg.ts", "../src/mixins/file.ts", "../src/mixins/identity.ts", "../src/mixins/utils.ts", "../src/EntityServerClient.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * \uD658\uACBD\uBCC0\uC218\uB97C \uC77D\uC2B5\uB2C8\uB2E4.\n * - \uBE0C\uB77C\uC6B0\uC800/Vite: `import.meta.env`\n * - Node.js: `process.env`\n */\nexport function readEnv(name: string): string | undefined {\n // Vite / \uAE30\uD0C0 \uBC88\uB4E4\uB7EC (import.meta.env)\n const meta = import.meta as unknown as {\n env?: Record<string, string | undefined>;\n };\n if (meta?.env?.[name] != null) return meta.env[name];\n\n // Node.js (process.env)\n if (\n typeof process !== \"undefined\" &&\n process.env &&\n process.env[name] != null\n ) {\n return process.env[name];\n }\n\n return undefined;\n}\n\n/** \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uAC1D\uCCB4\uB97C URL \uCFFC\uB9AC \uBB38\uC790\uC5F4\uB85C \uBCC0\uD658\uD569\uB2C8\uB2E4. `orderBy` \uD0A4\uB294 `order_by`\uB85C \uBCC0\uD658\uB429\uB2C8\uB2E4. */\nexport function buildQuery(params: Record<string, unknown>): string {\n return Object.entries(params)\n .filter(([, value]) => value != null)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key === \"orderBy\" ? \"order_by\" : key)}=${encodeURIComponent(String(value))}`,\n )\n .join(\"&\");\n}\n", "// @ts-ignore\nimport { xchacha20poly1305 } from \"@noble/ciphers/chacha\";\n// @ts-ignore\nimport { sha256 } from \"@noble/hashes/sha2\";\n// @ts-ignore\nimport { hkdf } from \"@noble/hashes/hkdf\";\n\n/**\n * \uD328\uD0B7 \uC554\uD638\uD654 \uD0A4\uB97C \uC720\uB3C4\uD569\uB2C8\uB2E4.\n * - HMAC \uBAA8\uB4DC (`hmacSecret` \uC720\uD6A8 \uC2DC): HKDF-SHA256(hmac_secret, \"entity-server:packet-encryption\")\n * - JWT \uBAA8\uB4DC: HKDF-SHA256(jwt_token, \"entity-server:packet-encryption\")\n */\nexport function derivePacketKey(hmacSecret: string, token: string): Uint8Array {\n const ikm = hmacSecret || token;\n const salt = new TextEncoder().encode(\"entity-server:hkdf:v1\");\n const info = new TextEncoder().encode(\"entity-server:packet-encryption\");\n return hkdf(sha256, new TextEncoder().encode(ikm), salt, info, 32);\n}\n\n/**\n * \uD3C9\uBB38 \uBC14\uC774\uD2B8\uB97C XChaCha20-Poly1305\uB85C \uC554\uD638\uD654\uD569\uB2C8\uB2E4.\n * \uD3EC\uB9F7: [random_magic:K][random_nonce:24][ciphertext+tag]\n * K = 2 + key[31] % 14 (\uD328\uD0B7 \uD0A4\uC5D0\uC11C \uC790\uB3D9 \uD30C\uC0DD)\n */\nexport function encryptPacket(\n plaintext: Uint8Array,\n key: Uint8Array,\n): Uint8Array {\n const magicLen = 2 + (key[31] % 14);\n const magic = new Uint8Array(magicLen);\n const nonce = new Uint8Array(24);\n crypto.getRandomValues(magic);\n crypto.getRandomValues(nonce);\n const cipher = xchacha20poly1305(key, nonce);\n const ciphertext = cipher.encrypt(plaintext);\n const result = new Uint8Array(magicLen + 24 + ciphertext.length);\n result.set(magic, 0);\n result.set(nonce, magicLen);\n result.set(ciphertext, magicLen + 24);\n return result;\n}\n\n/**\n * XChaCha20-Poly1305 \uD328\uD0B7\uC744 \uBCF5\uD638\uD654\uD574 JSON \uAC1D\uCCB4\uB85C \uBCC0\uD658\uD569\uB2C8\uB2E4.\n * \uD3EC\uB9F7: [magic:K][nonce:24][ciphertext+tag]\n * K = 2 + key[31] % 14 (\uD328\uD0B7 \uD0A4\uC5D0\uC11C \uC790\uB3D9 \uD30C\uC0DD)\n */\nexport function decryptPacket<T>(buffer: ArrayBuffer, key: Uint8Array): T {\n const magicLen = 2 + (key[31] % 14);\n const data = new Uint8Array(buffer);\n if (data.length < magicLen + 24 + 16) {\n throw new Error(\"Encrypted packet too short\");\n }\n const nonce = data.slice(magicLen, magicLen + 24);\n const ciphertext = data.slice(magicLen + 24);\n const cipher = xchacha20poly1305(key, nonce);\n const plaintext = cipher.decrypt(ciphertext);\n return JSON.parse(new TextDecoder().decode(plaintext)) as T;\n}\n\n/**\n * \uC694\uCCAD \uBC14\uB514\uB97C \uD30C\uC2F1\uD569\uB2C8\uB2E4. `application/octet-stream`\uC774\uBA74 \uBCF5\uD638\uD654, \uADF8 \uC678\uB294 JSON \uD30C\uC2F1\uD569\uB2C8\uB2E4.\n *\n * @param requireEncrypted `true`\uC774\uBA74 \uC554\uD638\uD654\uB41C \uC694\uCCAD\uB9CC \uD5C8\uC6A9\uD569\uB2C8\uB2E4.\n */\nexport function parseRequestBody<T>(\n body: ArrayBuffer | Uint8Array | string | T | null | undefined,\n contentType: string,\n requireEncrypted: boolean,\n key: Uint8Array,\n): T {\n const isEncrypted = contentType\n .toLowerCase()\n .includes(\"application/octet-stream\");\n\n if (requireEncrypted && !isEncrypted) {\n throw new Error(\n \"Encrypted request required: Content-Type must be application/octet-stream\",\n );\n }\n\n if (isEncrypted) {\n if (body == null) throw new Error(\"Encrypted request body is empty\");\n if (body instanceof ArrayBuffer) return decryptPacket<T>(body, key);\n if (body instanceof Uint8Array) {\n const sliced = body.buffer.slice(\n body.byteOffset,\n body.byteOffset + body.byteLength,\n );\n return decryptPacket<T>(sliced as ArrayBuffer, key);\n }\n throw new Error(\n \"Encrypted request body must be ArrayBuffer or Uint8Array\",\n );\n }\n\n if (body == null || body === \"\") return {} as T;\n if (typeof body === \"string\") return JSON.parse(body) as T;\n return body as T;\n}\n", "// @ts-ignore\nimport { sha256 } from \"@noble/hashes/sha2\";\n// @ts-ignore\nimport { hmac } from \"@noble/hashes/hmac\";\n\n/**\n * HMAC-SHA256 \uC11C\uBA85 \uD5E4\uB354\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n *\n * \uC11C\uBA85 \uB300\uC0C1: `METHOD|PATH|TIMESTAMP|NONCE|BODY`\n *\n * @returns `X-API-Key`, `X-Timestamp`, `X-Nonce`, `X-Signature` \uD5E4\uB354 \uAC1D\uCCB4\n */\nexport function buildHmacHeaders(\n method: string,\n path: string,\n bodyBytes: Uint8Array,\n apiKey: string,\n hmacSecret: string,\n): Record<string, string> {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonce = crypto.randomUUID();\n\n const prefix = new TextEncoder().encode(\n `${method}|${path}|${timestamp}|${nonce}|`,\n );\n const payload = new Uint8Array(prefix.length + bodyBytes.length);\n payload.set(prefix, 0);\n payload.set(bodyBytes, prefix.length);\n\n const sig = hmac(sha256, new TextEncoder().encode(hmacSecret), payload);\n const signature = [...sig]\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n return {\n \"X-API-Key\": apiKey,\n \"X-Timestamp\": timestamp,\n \"X-Nonce\": nonce,\n \"X-Signature\": signature,\n };\n}\n", "import { derivePacketKey, encryptPacket, decryptPacket } from \"./packet\";\nimport { buildHmacHeaders } from \"./hmac\";\n\nexport interface RequestOptions {\n baseUrl: string;\n token: string;\n apiKey: string;\n hmacSecret: string;\n encryptRequests: boolean;\n}\n\n/**\n * Entity Server\uC5D0 HTTP \uC694\uCCAD\uC744 \uBCF4\uB0C5\uB2C8\uB2E4.\n *\n * - `encryptRequests` \uD65C\uC131\uD654 \uC2DC \uC778\uC99D\uB41C POST \uBC14\uB514\uB97C \uC790\uB3D9 \uC554\uD638\uD654\uD569\uB2C8\uB2E4.\n * - \uC751\uB2F5\uC774 `application/octet-stream`\uC774\uBA74 \uC790\uB3D9 \uBCF5\uD638\uD654\uD569\uB2C8\uB2E4.\n * - JSON \uC751\uB2F5\uC758 `ok`\uAC00 false\uC774\uBA74 \uC5D0\uB7EC\uB97C \uB358\uC9D1\uB2C8\uB2E4.\n */\nexport async function entityRequest<T>(\n opts: RequestOptions,\n method: string,\n path: string,\n body?: unknown,\n withAuth = true,\n extraHeaders: Record<string, string> = {},\n): Promise<T> {\n const { baseUrl, token, apiKey, hmacSecret, encryptRequests } = opts;\n const isHmacMode = withAuth && !!(apiKey && hmacSecret);\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...extraHeaders,\n };\n if (!isHmacMode && withAuth && token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n let fetchBody: string | Uint8Array | null = null;\n if (body != null) {\n const shouldEncrypt =\n encryptRequests &&\n withAuth &&\n (token || isHmacMode) &&\n method !== \"GET\" &&\n method !== \"HEAD\";\n\n if (shouldEncrypt) {\n const key = derivePacketKey(hmacSecret, token);\n fetchBody = encryptPacket(\n new TextEncoder().encode(JSON.stringify(body)),\n key,\n );\n headers[\"Content-Type\"] = \"application/octet-stream\";\n } else {\n fetchBody = JSON.stringify(body);\n }\n }\n\n if (isHmacMode) {\n const bodyBytes =\n fetchBody instanceof Uint8Array\n ? fetchBody\n : typeof fetchBody === \"string\"\n ? new TextEncoder().encode(fetchBody)\n : new Uint8Array(0);\n Object.assign(\n headers,\n buildHmacHeaders(method, path, bodyBytes, apiKey, hmacSecret),\n );\n }\n\n const res = await fetch(baseUrl + path, {\n method,\n headers,\n ...(fetchBody != null ? { body: fetchBody as BodyInit } : {}),\n });\n\n const contentType = res.headers.get(\"Content-Type\") ?? \"\";\n if (contentType.includes(\"application/octet-stream\")) {\n const key = derivePacketKey(hmacSecret, token);\n return decryptPacket<T>(await res.arrayBuffer(), key);\n }\n\n const data = await res.json();\n if (!data.ok) {\n const err = new Error(\n data.message ?? `EntityServer error (HTTP ${res.status})`,\n );\n (err as { status?: number }).status = res.status;\n throw err;\n }\n return data as T;\n}\n", "import type { EntityServerClientOptions } from \"../types\";\nimport { readEnv } from \"./utils\";\nimport { derivePacketKey, parseRequestBody } from \"./packet\";\nimport { entityRequest, type RequestOptions } from \"./request\";\n\n// mixin \uD5EC\uD37C \uD0C0\uC785\nexport type GConstructor<T = object> = new (...args: any[]) => T;\n\nexport class EntityServerClientBase {\n baseUrl: string;\n token: string;\n apiKey: string;\n hmacSecret: string;\n encryptRequests: boolean;\n activeTxId: string | null = null;\n\n // \uC138\uC158 \uC720\uC9C0 \uAD00\uB828\n keepSession: boolean;\n refreshBuffer: number;\n onTokenRefreshed?: (\n accessToken: string,\n expiresIn: number,\n ) => void;\n onSessionExpired?: (error: Error) => void;\n _sessionRefreshToken: string | null = null;\n _refreshTimer: ReturnType<typeof setTimeout> | null = null;\n\n // \u2500\u2500\u2500 \uCD08\uAE30\uD654 & \uC124\uC815 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * EntityServerClient \uC778\uC2A4\uD134\uC2A4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n *\n * \uAE30\uBCF8\uAC12:\n * - `baseUrl`: `VITE_ENTITY_SERVER_URL` \uB610\uB294 `http://localhost:47200`\n */\n constructor(options: EntityServerClientOptions = {}) {\n const envBaseUrl = readEnv(\"VITE_ENTITY_SERVER_URL\");\n\n this.baseUrl = (\n options.baseUrl ??\n envBaseUrl ??\n \"http://localhost:47200\"\n ).replace(/\\/$/, \"\");\n this.token = options.token ?? \"\";\n this.apiKey = options.apiKey ?? \"\";\n this.hmacSecret = options.hmacSecret ?? \"\";\n this.encryptRequests = options.encryptRequests ?? false;\n this.keepSession = options.keepSession ?? false;\n this.refreshBuffer = options.refreshBuffer ?? 60;\n this.onTokenRefreshed = options.onTokenRefreshed;\n this.onSessionExpired = options.onSessionExpired;\n }\n\n /** baseUrl, token, encryptRequests \uAC12\uC744 \uB7F0\uD0C0\uC784\uC5D0 \uAC31\uC2E0\uD569\uB2C8\uB2E4. */\n configure(options: Partial<EntityServerClientOptions>): void {\n if (options.baseUrl) this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n if (typeof options.token === \"string\") this.token = options.token;\n if (typeof options.encryptRequests === \"boolean\")\n this.encryptRequests = options.encryptRequests;\n if (typeof options.apiKey === \"string\") this.apiKey = options.apiKey;\n if (typeof options.hmacSecret === \"string\")\n this.hmacSecret = options.hmacSecret;\n if (typeof options.keepSession === \"boolean\")\n this.keepSession = options.keepSession;\n if (typeof options.refreshBuffer === \"number\")\n this.refreshBuffer = options.refreshBuffer;\n if (options.onTokenRefreshed)\n this.onTokenRefreshed = options.onTokenRefreshed;\n if (options.onSessionExpired)\n this.onSessionExpired = options.onSessionExpired;\n }\n\n /** \uC778\uC99D \uC694\uCCAD\uC5D0 \uC0AC\uC6A9\uD560 JWT Access Token\uC744 \uC124\uC815\uD569\uB2C8\uB2E4. */\n setToken(token: string): void {\n this.token = token;\n }\n\n /** HMAC \uC778\uC99D\uC6A9 API Key\uB97C \uC124\uC815\uD569\uB2C8\uB2E4. */\n setApiKey(apiKey: string): void {\n this.apiKey = apiKey;\n }\n\n /** HMAC \uC778\uC99D\uC6A9 \uC2DC\uD06C\uB9BF\uC744 \uC124\uC815\uD569\uB2C8\uB2E4. */\n setHmacSecret(secret: string): void {\n this.hmacSecret = secret;\n }\n\n /** \uC554\uD638\uD654 \uC694\uCCAD \uD65C\uC131\uD654 \uC5EC\uBD80\uB97C \uC124\uC815\uD569\uB2C8\uB2E4. */\n setEncryptRequests(value: boolean): void {\n this.encryptRequests = value;\n }\n\n // \u2500\u2500\u2500 \uC138\uC158 \uC720\uC9C0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** @internal \uC790\uB3D9 \uD1A0\uD070 \uAC31\uC2E0 \uD0C0\uC774\uBA38\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4. */\n _scheduleKeepSession(\n refreshToken: string,\n expiresIn: number,\n refreshFn: (\n rt: string,\n ) => Promise<{ access_token: string; expires_in: number }>,\n ): void {\n this._clearRefreshTimer();\n this._sessionRefreshToken = refreshToken;\n const delayMs = Math.max((expiresIn - this.refreshBuffer) * 1000, 0);\n this._refreshTimer = setTimeout(async () => {\n if (!this._sessionRefreshToken) return;\n try {\n const result = await refreshFn(this._sessionRefreshToken);\n this.onTokenRefreshed?.(result.access_token, result.expires_in);\n this._scheduleKeepSession(\n this._sessionRefreshToken,\n result.expires_in,\n refreshFn,\n );\n } catch (err) {\n this._clearRefreshTimer();\n this.onSessionExpired?.(\n err instanceof Error ? err : new Error(String(err)),\n );\n }\n }, delayMs);\n }\n\n /** @internal \uC790\uB3D9 \uAC31\uC2E0 \uD0C0\uC774\uBA38\uB97C \uC815\uB9AC\uD569\uB2C8\uB2E4. */\n _clearRefreshTimer(): void {\n if (this._refreshTimer !== null) {\n clearTimeout(this._refreshTimer);\n this._refreshTimer = null;\n }\n }\n\n /**\n * \uC138\uC158 \uC720\uC9C0 \uD0C0\uC774\uBA38\uB97C \uC911\uC9C0\uD569\uB2C8\uB2E4.\n * `logout()` \uD638\uCD9C \uC2DC \uC790\uB3D9\uC73C\uB85C \uC911\uC9C0\uB418\uBA70, \uC9C1\uC811 \uD638\uCD9C\uC774 \uD544\uC694\uD55C \uACBD\uC6B0\uB294 \uB4DC\uBB45\uB2C8\uB2E4.\n */\n stopKeepSession(): void {\n this._clearRefreshTimer();\n this._sessionRefreshToken = null;\n }\n\n // \u2500\u2500\u2500 \uC694\uCCAD \uBCF8\uBB38 \uD30C\uC2F1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * \uC694\uCCAD \uBC14\uB514\uB97C \uD30C\uC2F1\uD569\uB2C8\uB2E4.\n * `application/octet-stream`\uC774\uBA74 XChaCha20-Poly1305 \uBCF5\uD638\uD654, \uADF8 \uC678\uB294 JSON \uD30C\uC2F1\uD569\uB2C8\uB2E4.\n *\n * @param requireEncrypted `true`\uC774\uBA74 \uC554\uD638\uD654\uB41C \uC694\uCCAD\uB9CC \uD5C8\uC6A9\uD569\uB2C8\uB2E4.\n */\n readRequestBody<T = Record<string, unknown>>(\n body: ArrayBuffer | Uint8Array | string | T | null | undefined,\n contentType = \"application/json\",\n requireEncrypted = false,\n ): T {\n const key = derivePacketKey(this.hmacSecret, this.token);\n return parseRequestBody<T>(body, contentType, requireEncrypted, key);\n }\n\n // \u2500\u2500\u2500 \uB0B4\uBD80 \uD5EC\uD37C \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n get _reqOpts(): RequestOptions {\n return {\n baseUrl: this.baseUrl,\n token: this.token,\n apiKey: this.apiKey,\n hmacSecret: this.hmacSecret,\n encryptRequests: this.encryptRequests,\n };\n }\n\n _request<T>(\n method: string,\n path: string,\n body?: unknown,\n withAuth = true,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n return entityRequest<T>(\n this._reqOpts,\n method,\n path,\n body,\n withAuth,\n extraHeaders,\n );\n }\n\n /** PNG/\uBC14\uC774\uB108\uB9AC \uC751\uB2F5\uC744 ArrayBuffer\uB85C \uBC18\uD658\uD569\uB2C8\uB2E4. (QR, \uBC14\uCF54\uB4DC \uB4F1) */\n async _requestBinary(\n method: string,\n path: string,\n body?: unknown,\n withAuth = true,\n ): Promise<ArrayBuffer> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (withAuth && this.token)\n headers[\"Authorization\"] = `Bearer ${this.token}`;\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const res = await fetch(this.baseUrl + path, {\n method,\n headers,\n ...(body != null ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const text = await res.text();\n const err = new Error(`HTTP ${res.status}: ${text}`);\n (err as { status?: number }).status = res.status;\n throw err;\n }\n\n return res.arrayBuffer();\n }\n\n /** multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0C5\uB2C8\uB2E4. (\uD30C\uC77C \uC5C5\uB85C\uB4DC \uB4F1) */\n async _requestForm<T>(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<T> {\n const headers: Record<string, string> = {};\n if (withAuth && this.token)\n headers[\"Authorization\"] = `Bearer ${this.token}`;\n if (this.apiKey) headers[\"X-API-Key\"] = this.apiKey;\n\n const res = await fetch(this.baseUrl + path, {\n method,\n headers,\n body: form,\n });\n\n const data = await res.json();\n if (!data.ok) {\n const err = new Error(\n data.message ?? `EntityServer error (HTTP ${res.status})`,\n );\n (err as { status?: number }).status = res.status;\n throw err;\n }\n return data as T;\n }\n}\n", "import type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function AuthMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class AuthMixinClass extends Base {\n // \u2500\u2500\u2500 \uC778\uC99D \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * \uC11C\uBC84 \uD5EC\uC2A4 \uCCB4\uD06C\uB97C \uC218\uD589\uD558\uACE0 \uD328\uD0B7 \uC554\uD638\uD654 \uD65C\uC131 \uC5EC\uBD80\uB97C \uC790\uB3D9\uC73C\uB85C \uAC10\uC9C0\uD569\uB2C8\uB2E4.\n *\n * \uC11C\uBC84\uAC00 `packet_encryption: true`\uB97C \uC751\uB2F5\uD558\uBA74 \uC774\uD6C4 \uBAA8\uB4E0 \uC694\uCCAD\uC5D0 \uC554\uD638\uD654\uAC00 \uC790\uB3D9 \uC801\uC6A9\uB429\uB2C8\uB2E4.\n *\n * ```ts\n * await client.checkHealth();\n * await client.login(email, password);\n * ```\n */\n async checkHealth(): Promise<{\n ok: boolean;\n packet_encryption?: boolean;\n }> {\n const res = await fetch(`${this.baseUrl}/v1/health`, {\n signal: AbortSignal.timeout(3000),\n });\n const data = (await res.json()) as {\n ok: boolean;\n packet_encryption?: boolean;\n };\n if (data.packet_encryption) this.encryptRequests = true;\n return data;\n }\n\n /** \uB85C\uADF8\uC778 \uD6C4 `access_token`\uC744 \uB0B4\uBD80 \uC0C1\uD0DC\uC5D0 \uC800\uC7A5\uD569\uB2C8\uB2E4. */\n async login(\n email: string,\n password: string,\n ): Promise<{\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }> {\n const data = await this._request<{\n data: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n }>(\"POST\", \"/v1/auth/login\", { email, passwd: password }, false);\n this.token = data.data.access_token;\n if (this.keepSession)\n this._scheduleKeepSession(\n data.data.refresh_token,\n data.data.expires_in,\n (rt) => this.refreshToken(rt),\n );\n return data.data;\n }\n\n /** Refresh Token\uC73C\uB85C Access Token\uC744 \uC7AC\uBC1C\uAE09\uBC1B\uC544 \uB0B4\uBD80 \uD1A0\uD070\uC744 \uAD50\uCCB4\uD569\uB2C8\uB2E4. */\n async refreshToken(\n refreshToken: string,\n ): Promise<{ access_token: string; expires_in: number }> {\n const data = await this._request<{\n data: { access_token: string; expires_in: number };\n }>(\n \"POST\",\n \"/v1/auth/refresh\",\n { refresh_token: refreshToken },\n false,\n );\n this.token = data.data.access_token;\n if (this.keepSession)\n this._scheduleKeepSession(\n refreshToken,\n data.data.expires_in,\n (rt) => this.refreshToken(rt),\n );\n return data.data;\n }\n\n /**\n * \uC11C\uBC84\uC5D0 \uB85C\uADF8\uC544\uC6C3\uC744 \uC694\uCCAD\uD558\uACE0 \uB0B4\uBD80 \uD1A0\uD070\uC744 \uCD08\uAE30\uD654\uD569\uB2C8\uB2E4.\n * refresh_token\uC744 \uC11C\uBC84\uC5D0 \uC804\uB2EC\uD574 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n */\n async logout(refreshToken: string): Promise<{ ok: boolean }> {\n this.stopKeepSession();\n const data = await this._request<{ ok: boolean }>(\n \"POST\",\n \"/v1/auth/logout\",\n { refresh_token: refreshToken },\n false,\n );\n this.token = \"\";\n return data;\n }\n\n /** \uD604\uC7AC \uB85C\uADF8\uC778\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4. */\n me<T = Record<string, unknown>>(): Promise<{ ok: boolean; data: T }> {\n return this._request(\"GET\", \"/v1/auth/me\");\n }\n\n /** \uBE44\uBC00\uBC88\uD638\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4. */\n changePassword(\n currentPasswd: string,\n newPasswd: string,\n ): Promise<{ ok: boolean }> {\n return this._request(\"POST\", \"/v1/auth/change-password\", {\n current_passwd: currentPasswd,\n new_passwd: newPasswd,\n });\n }\n\n /** \uD68C\uC6D0 \uD0C8\uD1F4\uB97C \uC694\uCCAD\uD569\uB2C8\uB2E4. */\n withdraw(passwd?: string): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/auth/withdraw\",\n passwd ? { passwd } : {},\n );\n }\n\n /**\n * \uD734\uBA74 \uACC4\uC815\uC744 \uC7AC\uD65C\uC131\uD654\uD569\uB2C8\uB2E4.\n * \uBE44\uBC00\uBC88\uD638 \uB610\uB294 OAuth(provider + code)\uB85C \uBCF8\uC778 \uD655\uC778\uD569\uB2C8\uB2E4.\n */\n reactivate(params: {\n email: string;\n passwd?: string;\n provider?: string;\n code?: string;\n }): Promise<{\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }> {\n return this._request(\"POST\", \"/v1/auth/reactivate\", params, false);\n }\n\n /** \uBE44\uBC00\uBC88\uD638 \uC7AC\uC124\uC815 \uBA54\uC77C\uC744 \uC694\uCCAD\uD569\uB2C8\uB2E4. */\n passwordResetRequest(email: string): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/auth/password-reset\",\n { email },\n false,\n );\n }\n\n /** \uC774\uBA54\uC77C\uB85C \uC804\uB2EC\uB41C \uD1A0\uD070\uC73C\uB85C \uBE44\uBC00\uBC88\uD638\uB97C \uC7AC\uC124\uC815\uD569\uB2C8\uB2E4. */\n passwordResetConfirm(\n token: string,\n newPasswd: string,\n ): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/auth/password-reset/confirm\",\n { token, new_passwd: newPasswd },\n false,\n );\n }\n\n // \u2500\u2500\u2500 OAuth \uC5F0\uB3D9 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** OAuth \uD504\uB85C\uBC14\uC774\uB354\uB97C \uD604\uC7AC \uACC4\uC815\uC5D0 \uC5F0\uB3D9\uD569\uB2C8\uB2E4. */\n oauthLink(\n provider: string,\n code: string,\n state?: string,\n ): Promise<{ ok: boolean; message: string; provider: string }> {\n return this._request(\"POST\", \"/v1/auth/oauth/link\", {\n provider,\n code,\n ...(state ? { state } : {}),\n });\n }\n\n /** OAuth \uD504\uB85C\uBC14\uC774\uB354 \uC5F0\uB3D9\uC744 \uD574\uC81C\uD569\uB2C8\uB2E4. */\n oauthUnlink(\n provider: string,\n ): Promise<{ ok: boolean; message: string; provider: string }> {\n return this._request(\"DELETE\", `/v1/auth/oauth/link/${provider}`);\n }\n\n /** \uD604\uC7AC \uACC4\uC815\uC5D0 \uC5F0\uB3D9\uB41C OAuth \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. */\n oauthProviders(): Promise<{\n ok: boolean;\n data: Array<{\n provider: string;\n email?: string;\n linked_at?: string;\n }>;\n }> {\n return this._request(\"GET\", \"/v1/auth/oauth/providers\");\n }\n\n /** \uD2B9\uC815 OAuth \uD504\uB85C\uBC14\uC774\uB354\uC758 \uC561\uC138\uC2A4 \uD1A0\uD070\uC744 \uAC31\uC2E0\uD569\uB2C8\uB2E4. */\n oauthTokenRefresh(provider: string): Promise<{\n ok: boolean;\n access_token: string;\n expires_at?: string;\n }> {\n return this._request(\"POST\", `/v1/auth/oauth/refresh/${provider}`);\n }\n\n // \u2500\u2500\u2500 2\uB2E8\uACC4 \uC778\uC99D (2FA) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** 2FA \uC124\uC815\uC744 \uC2DC\uC791\uD558\uACE0 QR \uCF54\uB4DC / \uC2DC\uD06C\uB9BF\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. */\n twoFactorSetup(): Promise<{\n ok: boolean;\n setup_token: string;\n qr_url: string;\n secret: string;\n }> {\n return this._request(\"POST\", \"/v1/auth/2fa/setup\");\n }\n\n /** TOTP \uCF54\uB4DC\uB85C 2FA \uC124\uC815\uC744 \uC644\uB8CC\uD569\uB2C8\uB2E4. */\n twoFactorSetupVerify(\n code: string,\n setupToken: string,\n ): Promise<{ ok: boolean; recovery_codes: string[] }> {\n return this._request(\"POST\", \"/v1/auth/2fa/setup/verify\", {\n code,\n setup_token: setupToken,\n });\n }\n\n /** 2FA\uB97C \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4. */\n twoFactorDisable(code: string): Promise<{ ok: boolean }> {\n return this._request(\"DELETE\", \"/v1/auth/2fa\", { code });\n }\n\n /** 2FA \uD65C\uC131\uD654 \uC5EC\uBD80\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n twoFactorStatus(): Promise<{ ok: boolean; enabled: boolean }> {\n return this._request(\"GET\", \"/v1/auth/2fa/status\");\n }\n\n /** \uC784\uC2DC \uD1A0\uD070\uC73C\uB85C TOTP \uCF54\uB4DC\uB97C \uAC80\uC99D\uD558\uC5EC \uCD5C\uC885 JWT\uB97C \uBC1C\uAE09\uBC1B\uC2B5\uB2C8\uB2E4. */\n twoFactorVerify(\n twoFactorToken: string,\n code: string,\n ): Promise<{\n ok: boolean;\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }> {\n return this._request(\n \"POST\",\n \"/v1/auth/2fa/verify\",\n { two_factor_token: twoFactorToken, code },\n false,\n );\n }\n\n /** \uBCF5\uAD6C \uCF54\uB4DC\uB85C 2FA\uB97C \uC6B0\uD68C\uD558\uC5EC \uCD5C\uC885 JWT\uB97C \uBC1C\uAE09\uBC1B\uC2B5\uB2C8\uB2E4. */\n twoFactorRecovery(\n twoFactorToken: string,\n recoveryCode: string,\n ): Promise<{\n ok: boolean;\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }> {\n return this._request(\n \"POST\",\n \"/v1/auth/2fa/recovery\",\n {\n two_factor_token: twoFactorToken,\n recovery_code: recoveryCode,\n },\n false,\n );\n }\n\n /** \uBCF5\uAD6C \uCF54\uB4DC\uB97C \uC7AC\uC0DD\uC131\uD569\uB2C8\uB2E4. */\n twoFactorRegenerateRecovery(\n code: string,\n ): Promise<{ ok: boolean; recovery_codes: string[] }> {\n return this._request(\"POST\", \"/v1/auth/2fa/recovery/regenerate\", {\n code,\n });\n }\n };\n}\n", "import type {\n EntityHistoryRecord,\n EntityListParams,\n EntityListResult,\n EntityQueryRequest,\n} from \"../types\";\nimport { buildQuery } from \"../client/utils\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function EntityMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class EntityMixinClass extends Base {\n // \u2500\u2500\u2500 \uD2B8\uB79C\uC7AD\uC158 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uD2B8\uB79C\uC7AD\uC158\uC744 \uC2DC\uC791\uD558\uACE0 \uD65C\uC131 \uD2B8\uB79C\uC7AD\uC158 ID\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4. */\n async transStart(): Promise<string> {\n const res = await this._request<{\n ok: boolean;\n transaction_id: string;\n }>(\"POST\", \"/v1/transaction/start\", undefined, false);\n this.activeTxId = res.transaction_id;\n return this.activeTxId;\n }\n\n /** \uD65C\uC131 \uD2B8\uB79C\uC7AD\uC158(\uB610\uB294 \uC804\uB2EC\uB41C transactionId)\uC744 \uB864\uBC31\uD569\uB2C8\uB2E4. */\n transRollback(transactionId?: string): Promise<{ ok: boolean }> {\n const txId = transactionId ?? this.activeTxId;\n if (!txId)\n return Promise.reject(\n new Error(\n \"No active transaction. Call transStart() first.\",\n ),\n );\n this.activeTxId = null;\n return this._request(\"POST\", `/v1/transaction/rollback/${txId}`);\n }\n\n /**\n * \uD65C\uC131 \uD2B8\uB79C\uC7AD\uC158(\uB610\uB294 \uC804\uB2EC\uB41C transactionId)\uC744 \uCEE4\uBC0B\uD569\uB2C8\uB2E4.\n *\n * @returns `results` \uBC30\uC5F4: commit\uB41C \uAC01 \uC791\uC5C5\uC758 `entity`, `action`, `seq`\n */\n transCommit(transactionId?: string): Promise<{\n ok: boolean;\n results: Array<{ entity: string; action: string; seq: number }>;\n }> {\n const txId = transactionId ?? this.activeTxId;\n if (!txId)\n return Promise.reject(\n new Error(\n \"No active transaction. Call transStart() first.\",\n ),\n );\n this.activeTxId = null;\n return this._request(\"POST\", `/v1/transaction/commit/${txId}`);\n }\n\n // \u2500\u2500\u2500 \uC5D4\uD2F0\uD2F0 CRUD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uC2DC\uD000\uC2A4 ID\uB85C \uC5D4\uD2F0\uD2F0 \uB2E8\uAC74\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. */\n get<T = unknown>(\n entity: string,\n seq: number,\n opts: { skipHooks?: boolean } = {},\n ): Promise<{ ok: boolean; data: T }> {\n const q = opts.skipHooks ? \"?skipHooks=true\" : \"\";\n return this._request(\"GET\", `/v1/entity/${entity}/${seq}${q}`);\n }\n\n /** \uC870\uAC74\uC73C\uB85C \uC5D4\uD2F0\uD2F0 \uB2E8\uAC74\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. data \uCEEC\uB7FC\uC744 \uC644\uC804\uD788 \uBCF5\uD638\uD654\uD558\uC5EC \uBC18\uD658\uD569\uB2C8\uB2E4. */\n find<T = unknown>(\n entity: string,\n conditions?: Record<string, unknown>,\n opts: { skipHooks?: boolean } = {},\n ): Promise<{ ok: boolean; data: T }> {\n const q = opts.skipHooks ? \"?skipHooks=true\" : \"\";\n return this._request(\n \"POST\",\n `/v1/entity/${entity}/find${q}`,\n conditions ?? {},\n );\n }\n\n /** \uD398\uC774\uC9C0\uB124\uC774\uC158/\uC815\uB82C/\uD544\uD130 \uC870\uAC74\uC73C\uB85C \uC5D4\uD2F0\uD2F0 \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. */\n list<T = unknown>(\n entity: string,\n params: EntityListParams = {},\n ): Promise<{ ok: boolean; data: EntityListResult<T> }> {\n const { conditions, fields, orderDir, orderBy, ...rest } = params;\n const queryObj: Record<string, unknown> = {\n page: 1,\n limit: 20,\n ...rest,\n };\n if (orderBy)\n queryObj.orderBy =\n orderDir === \"DESC\" ? `-${orderBy}` : orderBy;\n if (fields?.length) queryObj.fields = fields.join(\",\");\n return this._request(\n \"POST\",\n `/v1/entity/${entity}/list?${buildQuery(queryObj)}`,\n conditions ?? {},\n );\n }\n\n /**\n * \uC5D4\uD2F0\uD2F0 \uCD1D \uAC74\uC218\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.\n *\n * @param conditions \uD544\uD130 \uC870\uAC74 (\uC608: `{ status: \"active\" }`)\n */\n count(\n entity: string,\n conditions?: Record<string, unknown>,\n ): Promise<{ ok: boolean; count: number }> {\n return this._request(\n \"POST\",\n `/v1/entity/${entity}/count`,\n conditions ?? {},\n );\n }\n\n /**\n * \uCEE4\uC2A4\uD140 SQL\uB85C \uC5D4\uD2F0\uD2F0\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.\n *\n * SELECT \uC804\uC6A9\uC774\uBA70 \uC778\uB371\uC2A4 \uD14C\uC774\uBE14\uB9CC \uC870\uD68C \uAC00\uB2A5\uD569\uB2C8\uB2E4. JOIN \uC9C0\uC6D0.\n */\n query<T = unknown>(\n entity: string,\n req: EntityQueryRequest,\n ): Promise<{ ok: boolean; data: { items: T[]; count: number } }> {\n return this._request(\"POST\", `/v1/entity/${entity}/query`, req);\n }\n\n /** \uC5D4\uD2F0\uD2F0 \uB370\uC774\uD130\uB97C \uC0DD\uC131/\uC218\uC815(Submit)\uD569\uB2C8\uB2E4. `seq`\uAC00 \uC5C6\uC73C\uBA74 INSERT, \uC788\uC73C\uBA74 UPDATE\uC785\uB2C8\uB2E4. */\n submit(\n entity: string,\n data: Record<string, unknown>,\n opts: { transactionId?: string; skipHooks?: boolean } = {},\n ): Promise<{ ok: boolean; seq: number }> {\n const txId = opts.transactionId ?? this.activeTxId;\n const extraHeaders = txId\n ? { \"X-Transaction-ID\": txId }\n : undefined;\n const q = opts.skipHooks ? \"?skipHooks=true\" : \"\";\n return this._request(\n \"POST\",\n `/v1/entity/${entity}/submit${q}`,\n data,\n true,\n extraHeaders,\n );\n }\n\n /** \uC2DC\uD000\uC2A4 ID\uB85C \uC5D4\uD2F0\uD2F0\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4(`hard=true`\uBA74 \uD558\uB4DC \uC0AD\uC81C, \uAE30\uBCF8\uC740 \uC18C\uD504\uD2B8 \uC0AD\uC81C). */\n delete(\n entity: string,\n seq: number,\n opts: {\n transactionId?: string;\n hard?: boolean;\n skipHooks?: boolean;\n } = {},\n ): Promise<{ ok: boolean; deleted: number }> {\n const params = new URLSearchParams();\n if (opts.hard) params.set(\"hard\", \"true\");\n if (opts.skipHooks) params.set(\"skipHooks\", \"true\");\n const q = params.size ? `?${params}` : \"\";\n const txId = opts.transactionId ?? this.activeTxId;\n const extraHeaders = txId\n ? { \"X-Transaction-ID\": txId }\n : undefined;\n return this._request(\n \"POST\",\n `/v1/entity/${entity}/delete/${seq}${q}`,\n undefined,\n true,\n extraHeaders,\n );\n }\n\n /** \uC5D4\uD2F0\uD2F0 \uB2E8\uAC74\uC758 \uBCC0\uACBD \uC774\uB825\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. */\n history<T = unknown>(\n entity: string,\n seq: number,\n params: Pick<EntityListParams, \"page\" | \"limit\"> = {},\n ): Promise<{\n ok: boolean;\n data: EntityListResult<EntityHistoryRecord<T>>;\n }> {\n return this._request(\n \"GET\",\n `/v1/entity/${entity}/history/${seq}?${buildQuery({ page: 1, limit: 50, ...params })}`,\n );\n }\n\n /** \uD2B9\uC815 \uC774\uB825 \uC2DC\uC810\uC73C\uB85C \uC5D4\uD2F0\uD2F0\uB97C \uB864\uBC31\uD569\uB2C8\uB2E4. */\n rollback(entity: string, historySeq: number): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n `/v1/entity/${entity}/rollback/${historySeq}`,\n );\n }\n };\n}\n", "import type {\n EntityListParams,\n EntityListResult,\n RegisterPushDeviceOptions,\n PushSendRequest,\n PushSendAllRequest,\n} from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\n// entity submit\uC744 \uAC00\uC9C4 base \uD0C0\uC785 (EntityMixin \uC801\uC6A9 \uD6C4)\ntype WithSubmit = EntityServerClientBase & {\n submit(\n entity: string,\n data: Record<string, unknown>,\n opts?: { transactionId?: string; skipHooks?: boolean },\n ): Promise<{ ok: boolean; seq: number }>;\n list<T = unknown>(\n entity: string,\n params?: EntityListParams,\n ): Promise<{ ok: boolean; data: EntityListResult<T> }>;\n};\n\nexport function PushMixin<TBase extends GConstructor<WithSubmit>>(Base: TBase) {\n return class PushMixinClass extends Base {\n // \u2500\u2500\u2500 \uD478\uC2DC submit \uB798\uD37C \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * \uD478\uC2DC \uAD00\uB828 \uC5D4\uD2F0\uD2F0\uB85C payload\uB97C \uC804\uC1A1(Submit)\uD569\uB2C8\uB2E4.\n * \uB0B4\uBD80\uC801\uC73C\uB85C `submit()` \uBA54\uC11C\uB4DC\uB97C \uD638\uCD9C\uD569\uB2C8\uB2E4.\n */\n push(\n pushEntity: string,\n payload: Record<string, unknown>,\n opts: { transactionId?: string } = {},\n ): Promise<{ ok: boolean; seq: number }> {\n return this.submit(pushEntity, payload, opts);\n }\n\n // \u2500\u2500\u2500 \uD478\uC2DC \uB514\uBC14\uC774\uC2A4 \uAD00\uB9AC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uD478\uC2DC \uB85C\uADF8 \uC5D4\uD2F0\uD2F0 \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. */\n pushLogList<T = unknown>(\n params: EntityListParams = {},\n ): Promise<{ ok: boolean; data: EntityListResult<T> }> {\n return this.list<T>(\"push_log\", params);\n }\n\n /** \uACC4\uC815\uC758 \uD478\uC2DC \uB514\uBC14\uC774\uC2A4\uB97C \uB4F1\uB85D\uD569\uB2C8\uB2E4. */\n registerPushDevice(\n accountSeq: number,\n deviceId: string,\n pushToken: string,\n opts: RegisterPushDeviceOptions = {},\n ): Promise<{ ok: boolean; seq: number }> {\n const {\n platform,\n deviceType,\n browser,\n browserVersion,\n pushEnabled = true,\n transactionId,\n } = opts;\n return this.submit(\n \"account_device\",\n {\n id: deviceId,\n account_seq: accountSeq,\n push_token: pushToken,\n push_enabled: pushEnabled,\n ...(platform ? { platform } : {}),\n ...(deviceType ? { device_type: deviceType } : {}),\n ...(browser ? { browser } : {}),\n ...(browserVersion\n ? { browser_version: browserVersion }\n : {}),\n },\n { transactionId },\n );\n }\n\n /** \uB514\uBC14\uC774\uC2A4 \uB808\uCF54\uB4DC\uC758 \uD478\uC2DC \uD1A0\uD070\uC744 \uAC31\uC2E0\uD569\uB2C8\uB2E4. */\n updatePushDeviceToken(\n deviceSeq: number,\n pushToken: string,\n opts: { pushEnabled?: boolean; transactionId?: string } = {},\n ): Promise<{ ok: boolean; seq: number }> {\n const { pushEnabled = true, transactionId } = opts;\n return this.submit(\n \"account_device\",\n {\n seq: deviceSeq,\n push_token: pushToken,\n push_enabled: pushEnabled,\n },\n { transactionId },\n );\n }\n\n /** \uB514\uBC14\uC774\uC2A4\uC758 \uD478\uC2DC \uC218\uC2E0\uC744 \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4. */\n disablePushDevice(\n deviceSeq: number,\n opts: { transactionId?: string } = {},\n ): Promise<{ ok: boolean; seq: number }> {\n return this.submit(\n \"account_device\",\n { seq: deviceSeq, push_enabled: false },\n { transactionId: opts.transactionId },\n );\n }\n\n // \u2500\u2500\u2500 \uD478\uC2DC \uBC1C\uC1A1 API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uD2B9\uC815 \uACC4\uC815\uC5D0 \uD478\uC2DC \uC54C\uB9BC\uC744 \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n pushSend(req: PushSendRequest): Promise<{ ok: boolean; seq: number }> {\n return this._request(\"POST\", \"/v1/push/send\", req);\n }\n\n /** \uC804\uCCB4 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD478\uC2DC \uC54C\uB9BC\uC744 \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n pushSendAll(req: PushSendAllRequest): Promise<{\n ok: boolean;\n sent: number;\n failed: number;\n }> {\n return this._request(\"POST\", \"/v1/push/send-all\", req);\n }\n\n /** \uD478\uC2DC \uBC1C\uC1A1 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n pushStatus(seq: number): Promise<{ ok: boolean; status: string }> {\n return this._request(\"POST\", `/v1/push/status/${seq}`, {});\n }\n };\n}\n", "import type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function EmailMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class EmailMixinClass extends Base {\n // \u2500\u2500\u2500 \uC774\uBA54\uC77C \uC778\uC99D / \uBCC0\uACBD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uC774\uBA54\uC77C \uC778\uC99D \uCF54\uB4DC \uB610\uB294 \uB9C1\uD06C\uB97C \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n emailVerificationSend(email: string): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/email/verification/send\",\n { email },\n false,\n );\n }\n\n /** \uC774\uBA54\uC77C \uC778\uC99D \uCF54\uB4DC\uB97C \uD655\uC778\uD569\uB2C8\uB2E4. */\n emailVerificationConfirm(token: string): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/email/verification/confirm\",\n { token },\n false,\n );\n }\n\n /** \uD604\uC7AC \uACC4\uC815\uC758 \uC774\uBA54\uC77C \uC778\uC99D \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. (JWT \uD544\uC694) */\n emailVerificationStatus(): Promise<{\n ok: boolean;\n verified: boolean;\n email?: string;\n }> {\n return this._request(\"GET\", \"/v1/email/verification/status\");\n }\n\n /** \uC774\uBA54\uC77C \uC8FC\uC18C\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4. (JWT + \uC778\uC99D \uCF54\uB4DC \uD544\uC694) */\n emailChange(newEmail: string, code?: string): Promise<{ ok: boolean }> {\n return this._request(\"POST\", \"/v1/email/change\", {\n new_email: newEmail,\n ...(code ? { code } : {}),\n });\n }\n };\n}\n", "import type { SmsSendRequest } from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function SmsMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class SmsMixinClass extends Base {\n // \u2500\u2500\u2500 SMS \uBC1C\uC1A1 / \uC778\uC99D \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** SMS\uB97C \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n smsSend(req: SmsSendRequest): Promise<{ ok: boolean; seq: number }> {\n return this._request(\"POST\", \"/v1/sms/send\", req);\n }\n\n /** SMS \uBC1C\uC1A1 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n smsStatus(seq: number): Promise<{ ok: boolean; status: string }> {\n return this._request(\"GET\", `/v1/sms/status/${seq}`);\n }\n\n /** SMS \uC778\uC99D \uCF54\uB4DC\uB97C \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n smsVerificationSend(\n phone: string,\n opts: { purpose?: string } = {},\n ): Promise<{ ok: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/sms/verification/send\",\n { phone, ...opts },\n false,\n );\n }\n\n /** SMS \uC778\uC99D \uCF54\uB4DC\uB97C \uAC80\uC99D\uD569\uB2C8\uB2E4. */\n smsVerificationVerify(\n phone: string,\n code: string,\n ): Promise<{ ok: boolean; verified: boolean }> {\n return this._request(\n \"POST\",\n \"/v1/sms/verification/verify\",\n { phone, code },\n false,\n );\n }\n };\n}\n", "import type { SmtpSendRequest } from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function SmtpMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class SmtpMixinClass extends Base {\n // \u2500\u2500\u2500 SMTP \uBA54\uC77C \uBC1C\uC1A1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** SMTP\uB85C \uBA54\uC77C\uC744 \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n smtpSend(req: SmtpSendRequest): Promise<{ ok: boolean; seq: number }> {\n return this._request(\"POST\", \"/v1/smtp/send\", req);\n }\n\n /** SMTP \uBC1C\uC1A1 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n smtpStatus(seq: number): Promise<{ ok: boolean; status: string }> {\n return this._request(\"POST\", `/v1/smtp/status/${seq}`, {});\n }\n };\n}\n", "import type { AlimtalkSendRequest, FriendtalkSendRequest } from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function AlimtalkMixin<\n TBase extends GConstructor<EntityServerClientBase>,\n>(Base: TBase) {\n return class AlimtalkMixinClass extends Base {\n // \u2500\u2500\u2500 \uC54C\uB9BC\uD1A1 / \uCE5C\uAD6C\uD1A1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uC54C\uB9BC\uD1A1(KakaoTalk \uBE44\uC988 \uBA54\uC2DC\uC9C0)\uC744 \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n alimtalkSend(req: AlimtalkSendRequest): Promise<{ message: string }> {\n return this._request(\"POST\", \"/v1/alimtalk/send\", req);\n }\n\n /** \uC54C\uB9BC\uD1A1 \uBC1C\uC1A1 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n alimtalkStatus(seq: number): Promise<{ ok: boolean; status: string }> {\n return this._request(\"GET\", `/v1/alimtalk/status/${seq}`);\n }\n\n /** \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC54C\uB9BC\uD1A1 \uD15C\uD50C\uB9BF \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. */\n alimtalkTemplates(): Promise<{\n templates: Array<{ code: string; name: string; content: string }>;\n count: number;\n }> {\n return this._request(\"GET\", \"/v1/alimtalk/templates\");\n }\n\n /** \uCE5C\uAD6C\uD1A1(KakaoTalk \uCC44\uB110 \uBA54\uC2DC\uC9C0)\uC744 \uBC1C\uC1A1\uD569\uB2C8\uB2E4. */\n friendtalkSend(\n req: FriendtalkSendRequest,\n ): Promise<{ message: string }> {\n return this._request(\"POST\", \"/v1/friendtalk/send\", req);\n }\n };\n}\n", "import type {\n PgCreateOrderRequest,\n PgConfirmPaymentRequest,\n PgCancelPaymentRequest,\n} from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function PgMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class PgMixinClass extends Base {\n // \u2500\u2500\u2500 PG(\uACB0\uC81C \uAC8C\uC774\uD2B8\uC6E8\uC774) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uACB0\uC81C \uC8FC\uBB38\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4. */\n pgCreateOrder(\n req: PgCreateOrderRequest,\n ): Promise<{ ok: boolean; data: Record<string, unknown> }> {\n return this._request(\"POST\", \"/v1/pg/orders\", req);\n }\n\n /** \uC8FC\uBB38 \uC815\uBCF4\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n pgGetOrder(orderId: string): Promise<{\n ok: boolean;\n data: Record<string, unknown>;\n }> {\n return this._request(\"GET\", `/v1/pg/orders/${orderId}`);\n }\n\n /** \uACB0\uC81C\uB97C \uC2B9\uC778\uD569\uB2C8\uB2E4. */\n pgConfirmPayment(\n req: PgConfirmPaymentRequest,\n ): Promise<{ ok: boolean; data: Record<string, unknown> }> {\n return this._request(\"POST\", \"/v1/pg/confirm\", req);\n }\n\n /** \uACB0\uC81C\uB97C \uCDE8\uC18C\uD569\uB2C8\uB2E4. */\n pgCancelPayment(\n orderId: string,\n req: PgCancelPaymentRequest,\n ): Promise<{ ok: boolean; data: Record<string, unknown> }> {\n return this._request(\n \"POST\",\n `/v1/pg/orders/${orderId}/cancel`,\n req,\n );\n }\n\n /** \uACB0\uC81C \uC0C1\uD0DC\uB97C \uC678\uBD80 PG\uC640 \uB3D9\uAE30\uD654\uD569\uB2C8\uB2E4. */\n pgSyncPayment(orderId: string): Promise<{ ok: boolean }> {\n return this._request(\"POST\", `/v1/pg/orders/${orderId}/sync`, {});\n }\n\n /** \uD074\uB77C\uC774\uC5B8\uD2B8 SDK \uC124\uC815\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4 (\uACF5\uAC1C API, \uC778\uC99D \uBD88\uD544\uC694). */\n pgConfig(): Promise<{ ok: boolean; data: Record<string, unknown> }> {\n return this._request(\"GET\", \"/v1/pg/config\", undefined, false);\n }\n };\n}\n", "import type { FileMeta, FileUploadOptions } from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function FileMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class FileMixinClass extends Base {\n // \u2500\u2500\u2500 \uD30C\uC77C \uAD00\uB9AC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD569\uB2C8\uB2E4. (multipart/form-data)\n *\n * ```ts\n * const input = document.querySelector('input[type=\"file\"]');\n * const result = await client.fileUpload(\"product\", input.files[0]);\n * console.log(result.data.uuid);\n * ```\n */\n async fileUpload(\n entity: string,\n file: File | Blob,\n opts: FileUploadOptions = {},\n ): Promise<{ ok: boolean; uuid: string; data: FileMeta }> {\n const form = new FormData();\n form.append(\n \"file\",\n file,\n file instanceof File ? file.name : \"upload\",\n );\n if (opts.refSeq != null)\n form.append(\"ref_seq\", String(opts.refSeq));\n if (opts.isPublic != null)\n form.append(\"is_public\", opts.isPublic ? \"true\" : \"false\");\n return this._requestForm(\n \"POST\",\n `/v1/files/${entity}/upload`,\n form,\n );\n }\n\n /** \uD30C\uC77C\uC744 \uB2E4\uC6B4\uB85C\uB4DC\uD569\uB2C8\uB2E4. `ArrayBuffer`\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4. */\n fileDownload(entity: string, uuid: string): Promise<ArrayBuffer> {\n return this._requestBinary(\n \"POST\",\n `/v1/files/${entity}/download/${uuid}`,\n {},\n );\n }\n\n /** \uD30C\uC77C\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4. */\n fileDelete(\n entity: string,\n uuid: string,\n ): Promise<{ ok: boolean; uuid: string; deleted: boolean }> {\n return this._request(\n \"POST\",\n `/v1/files/${entity}/delete/${uuid}`,\n {},\n );\n }\n\n /** \uC5D4\uD2F0\uD2F0\uC5D0 \uC5F0\uACB0\uB41C \uD30C\uC77C \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. */\n fileList(\n entity: string,\n opts: { refSeq?: number } = {},\n ): Promise<{\n ok: boolean;\n data: { items: FileMeta[]; total: number };\n }> {\n return this._request(\n \"POST\",\n `/v1/files/${entity}/list`,\n opts.refSeq ? { ref_seq: opts.refSeq } : {},\n );\n }\n\n /** \uD30C\uC77C \uBA54\uD0C0 \uC815\uBCF4\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n fileMeta(\n entity: string,\n uuid: string,\n ): Promise<{ ok: boolean; data: FileMeta }> {\n return this._request(\n \"POST\",\n `/v1/files/${entity}/meta/${uuid}`,\n {},\n );\n }\n\n /** \uC784\uC2DC \uD30C\uC77C \uC811\uADFC \uD1A0\uD070\uC744 \uBC1C\uAE09\uD569\uB2C8\uB2E4. */\n fileToken(uuid: string): Promise<{ ok: boolean; token: string }> {\n return this._request(\"POST\", `/v1/files/token/${uuid}`, {});\n }\n\n /** \uD30C\uC77C \uC778\uB77C\uC778 \uBDF0 URL\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. (fetch \uC5C6\uC74C, URL \uC870\uD569\uB9CC) */\n fileUrl(uuid: string): string {\n return `${this.baseUrl}/v1/files/${uuid}`;\n }\n };\n}\n", "import type { IdentityRequestOptions } from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function IdentityMixin<\n TBase extends GConstructor<EntityServerClientBase>,\n>(Base: TBase) {\n return class IdentityMixinClass extends Base {\n // \u2500\u2500\u2500 \uBCF8\uC778\uC778\uC99D \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** \uBCF8\uC778\uC778\uC99D \uC694\uCCAD\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4. */\n identityRequest(\n opts: IdentityRequestOptions,\n ): Promise<{ ok: boolean; data: Record<string, unknown> }> {\n return this._request(\"POST\", \"/v1/identity/request\", opts);\n }\n\n /** \uBCF8\uC778\uC778\uC99D \uACB0\uACFC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n identityResult(requestId: string): Promise<{\n ok: boolean;\n data: Record<string, unknown>;\n }> {\n return this._request(\"GET\", `/v1/identity/result/${requestId}`);\n }\n\n /** CI \uD574\uC2DC \uC911\uBCF5 \uC5EC\uBD80\uB97C \uD655\uC778\uD569\uB2C8\uB2E4. */\n identityVerifyCI(ciHash: string): Promise<{\n ok: boolean;\n data: { exists: boolean; account_seq?: number };\n }> {\n return this._request(\"POST\", \"/v1/identity/verify-ci\", {\n ci_hash: ciHash,\n });\n }\n };\n}\n", "import type { QRCodeOptions, BarcodeOptions } from \"../types\";\nimport type { GConstructor, EntityServerClientBase } from \"../client/base\";\n\nexport function UtilsMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class UtilsMixinClass extends Base {\n // \u2500\u2500\u2500 Utils (QR / \uBC14\uCF54\uB4DC) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * QR \uCF54\uB4DC PNG\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4. `ArrayBuffer`\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n *\n * ```ts\n * const buf = await client.qrcode(\"https://example.com\");\n * const blob = new Blob([buf], { type: \"image/png\" });\n * img.src = URL.createObjectURL(blob);\n * ```\n */\n qrcode(\n content: string,\n opts: QRCodeOptions = {},\n ): Promise<ArrayBuffer> {\n return this._requestBinary(\"POST\", \"/v1/utils/qrcode\", {\n content,\n ...opts,\n });\n }\n\n /**\n * QR \uCF54\uB4DC\uB97C base64/data URI JSON\uC73C\uB85C \uBC18\uD658\uD569\uB2C8\uB2E4.\n *\n * ```ts\n * const { data_uri } = await client.qrcodeBase64(\"https://example.com\");\n * img.src = data_uri;\n * ```\n */\n qrcodeBase64(\n content: string,\n opts: QRCodeOptions = {},\n ): Promise<{ ok: boolean; data: string; data_uri: string }> {\n return this._request(\"POST\", \"/v1/utils/qrcode/base64\", {\n content,\n ...opts,\n });\n }\n\n /** QR \uCF54\uB4DC\uB97C ASCII \uC544\uD2B8 \uD14D\uC2A4\uD2B8\uB85C \uBC18\uD658\uD569\uB2C8\uB2E4. */\n qrcodeText(\n content: string,\n opts: QRCodeOptions = {},\n ): Promise<{ ok: boolean; text: string }> {\n return this._request(\"POST\", \"/v1/utils/qrcode/text\", {\n content,\n ...opts,\n });\n }\n\n /**\n * \uBC14\uCF54\uB4DC PNG\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4. `ArrayBuffer`\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n *\n * ```ts\n * const buf = await client.barcode(\"1234567890128\", { type: \"ean13\" });\n * ```\n */\n barcode(\n content: string,\n opts: BarcodeOptions = {},\n ): Promise<ArrayBuffer> {\n return this._requestBinary(\"POST\", \"/v1/utils/barcode\", {\n content,\n ...opts,\n });\n }\n };\n}\n", "/**\n * @file EntityServerClient.ts\n * Mixin \uD328\uD134\uC73C\uB85C \uAD6C\uC131\uB41C EntityServerClient.\n *\n * \uC808(section)\uBCC4 \uAD6C\uD604:\n * src/client/base.ts \u2014 \uC0C1\uD0DC\u00B7\uC0DD\uC131\uC790\u00B7\uACF5\uD1B5 \uD5EC\uD37C\n * src/mixins/auth.ts \u2014 \uC778\uC99D (\uB85C\uADF8\uC778/\uB85C\uADF8\uC544\uC6C3/2FA/OAuth \uB4F1)\n * src/mixins/entity.ts \u2014 \uD2B8\uB79C\uC7AD\uC158 & \uC5D4\uD2F0\uD2F0 CRUD\n * src/mixins/push.ts \u2014 \uD478\uC2DC \uB514\uBC14\uC774\uC2A4 \uAD00\uB9AC & \uBC1C\uC1A1\n * src/mixins/email.ts \u2014 \uC774\uBA54\uC77C \uC778\uC99D/\uBCC0\uACBD\n * src/mixins/sms.ts \u2014 SMS \uBC1C\uC1A1/\uC778\uC99D\n * src/mixins/smtp.ts \u2014 SMTP \uBA54\uC77C \uBC1C\uC1A1\n * src/mixins/alimtalk.ts \u2014 \uC54C\uB9BC\uD1A1/\uCE5C\uAD6C\uD1A1\n * src/mixins/pg.ts \u2014 PG \uACB0\uC81C \uAC8C\uC774\uD2B8\uC6E8\uC774\n * src/mixins/file.ts \u2014 \uD30C\uC77C \uC2A4\uD1A0\uB9AC\uC9C0\n * src/mixins/identity.ts \u2014 \uBCF8\uC778\uC778\uC99D\n * src/mixins/utils.ts \u2014 QR\uCF54\uB4DC/\uBC14\uCF54\uB4DC\n */\nimport { EntityServerClientBase } from \"./client/base\";\nimport { AuthMixin } from \"./mixins/auth\";\nimport { EntityMixin } from \"./mixins/entity\";\nimport { PushMixin } from \"./mixins/push\";\nimport { EmailMixin } from \"./mixins/email\";\nimport { SmsMixin } from \"./mixins/sms\";\nimport { SmtpMixin } from \"./mixins/smtp\";\nimport { AlimtalkMixin } from \"./mixins/alimtalk\";\nimport { PgMixin } from \"./mixins/pg\";\nimport { FileMixin } from \"./mixins/file\";\nimport { IdentityMixin } from \"./mixins/identity\";\nimport { UtilsMixin } from \"./mixins/utils\";\n\n// \u2500\u2500\u2500 Composed class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class EntityServerClient extends UtilsMixin(\n IdentityMixin(\n FileMixin(\n PgMixin(\n AlimtalkMixin(\n SmtpMixin(\n SmsMixin(\n EmailMixin(\n PushMixin(\n EntityMixin(\n AuthMixin(EntityServerClientBase),\n ),\n ),\n ),\n ),\n ),\n ),\n ),\n ),\n ),\n) {}\n", "export * from \"./types\";\nexport * from \"./EntityServerClient\";\n\nimport { EntityServerClient } from \"./EntityServerClient\";\n\nexport const entityServer = new EntityServerClient();\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["readEnv", "name", "meta", "buildQuery", "params", "value", "key", "xchacha20poly1305", "sha256", "hkdf", "derivePacketKey", "hmacSecret", "token", "ikm", "salt", "info", "encryptPacket", "plaintext", "key", "magicLen", "magic", "nonce", "ciphertext", "result", "decryptPacket", "buffer", "data", "parseRequestBody", "body", "contentType", "requireEncrypted", "isEncrypted", "sliced", "sha256", "hmac", "buildHmacHeaders", "method", "path", "bodyBytes", "apiKey", "hmacSecret", "timestamp", "nonce", "prefix", "payload", "signature", "b", "entityRequest", "opts", "method", "path", "body", "withAuth", "extraHeaders", "baseUrl", "token", "apiKey", "hmacSecret", "encryptRequests", "isHmacMode", "headers", "fetchBody", "key", "derivePacketKey", "encryptPacket", "bodyBytes", "buildHmacHeaders", "res", "decryptPacket", "data", "err", "EntityServerClientBase", "options", "envBaseUrl", "readEnv", "token", "apiKey", "secret", "value", "refreshToken", "expiresIn", "refreshFn", "delayMs", "result", "err", "body", "contentType", "requireEncrypted", "key", "derivePacketKey", "parseRequestBody", "method", "path", "withAuth", "extraHeaders", "entityRequest", "headers", "res", "text", "form", "data", "AuthMixin", "Base", "data", "email", "password", "rt", "refreshToken", "currentPasswd", "newPasswd", "passwd", "params", "token", "provider", "code", "state", "setupToken", "twoFactorToken", "recoveryCode", "EntityMixin", "Base", "res", "transactionId", "txId", "entity", "seq", "opts", "q", "conditions", "params", "fields", "orderDir", "orderBy", "rest", "queryObj", "buildQuery", "req", "data", "extraHeaders", "historySeq", "PushMixin", "Base", "pushEntity", "payload", "opts", "params", "accountSeq", "deviceId", "pushToken", "platform", "deviceType", "browser", "browserVersion", "pushEnabled", "transactionId", "deviceSeq", "req", "seq", "EmailMixin", "Base", "email", "token", "newEmail", "code", "SmsMixin", "Base", "req", "seq", "phone", "opts", "code", "SmtpMixin", "Base", "req", "seq", "AlimtalkMixin", "Base", "req", "seq", "PgMixin", "Base", "req", "orderId", "FileMixin", "Base", "entity", "file", "opts", "form", "uuid", "IdentityMixin", "Base", "opts", "requestId", "ciHash", "UtilsMixin", "Base", "content", "opts", "EntityServerClient", "UtilsMixin", "IdentityMixin", "FileMixin", "PgMixin", "AlimtalkMixin", "SmtpMixin", "SmsMixin", "EmailMixin", "PushMixin", "EntityMixin", "AuthMixin", "EntityServerClientBase", "entityServer", "EntityServerClient"]
|
|
7
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { AlimtalkSendRequest, FriendtalkSendRequest } from "../types";
|
|
2
|
-
import type { GConstructor, EntityServerClientBase } from "../client/base";
|
|
3
|
-
export declare function AlimtalkMixin<TBase extends GConstructor<EntityServerClientBase>>(Base: TBase): {
|
|
4
|
-
new (...args: any[]): {
|
|
5
|
-
/** 알림톡(KakaoTalk 비즈 메시지)을 발송합니다. */
|
|
6
|
-
alimtalkSend(req: AlimtalkSendRequest): Promise<{
|
|
7
|
-
message: string;
|
|
8
|
-
}>;
|
|
9
|
-
/** 알림톡 발송 상태를 조회합니다. */
|
|
10
|
-
alimtalkStatus(seq: number): Promise<{
|
|
11
|
-
ok: boolean;
|
|
12
|
-
status: string;
|
|
13
|
-
}>;
|
|
14
|
-
/** 사용 가능한 알림톡 템플릿 목록을 조회합니다. */
|
|
15
|
-
alimtalkTemplates(): Promise<{
|
|
16
|
-
templates: Array<{
|
|
17
|
-
code: string;
|
|
18
|
-
name: string;
|
|
19
|
-
content: string;
|
|
20
|
-
}>;
|
|
21
|
-
count: number;
|
|
22
|
-
}>;
|
|
23
|
-
/** 친구톡(KakaoTalk 채널 메시지)을 발송합니다. */
|
|
24
|
-
friendtalkSend(req: FriendtalkSendRequest): Promise<{
|
|
25
|
-
message: string;
|
|
26
|
-
}>;
|
|
27
|
-
baseUrl: string;
|
|
28
|
-
token: string;
|
|
29
|
-
apiKey: string;
|
|
30
|
-
hmacSecret: string;
|
|
31
|
-
encryptRequests: boolean;
|
|
32
|
-
activeTxId: string | null;
|
|
33
|
-
keepSession: boolean;
|
|
34
|
-
refreshBuffer: number;
|
|
35
|
-
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
36
|
-
onSessionExpired?: (error: Error) => void;
|
|
37
|
-
_sessionRefreshToken: string | null;
|
|
38
|
-
_refreshTimer: ReturnType<typeof setTimeout> | null;
|
|
39
|
-
configure(options: Partial<import("..").EntityServerClientOptions>): void;
|
|
40
|
-
setToken(token: string): void;
|
|
41
|
-
setApiKey(apiKey: string): void;
|
|
42
|
-
setHmacSecret(secret: string): void;
|
|
43
|
-
setEncryptRequests(value: boolean): void;
|
|
44
|
-
_scheduleKeepSession(refreshToken: string, expiresIn: number, refreshFn: (rt: string) => Promise<{
|
|
45
|
-
access_token: string;
|
|
46
|
-
expires_in: number;
|
|
47
|
-
}>): void;
|
|
48
|
-
_clearRefreshTimer(): void;
|
|
49
|
-
stopKeepSession(): void;
|
|
50
|
-
readRequestBody<T = Record<string, unknown>>(body: ArrayBuffer | Uint8Array | string | T | null | undefined, contentType?: string, requireEncrypted?: boolean): T;
|
|
51
|
-
get _reqOpts(): import("../client/request").RequestOptions;
|
|
52
|
-
_request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
53
|
-
_requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
54
|
-
_requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
55
|
-
};
|
|
56
|
-
} & TBase;
|