entity-client 1.0.14 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EntityAppServerApi.d.ts +368 -416
- package/dist/EntityServerApi.d.ts +193 -216
- package/dist/client/base.d.ts +26 -40
- package/dist/client/base.js +1 -1
- package/dist/client/base.js.map +3 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/dist/mixins/app/plugins/alimtalk.d.ts +23 -26
- package/dist/mixins/app/plugins/friendtalk.d.ts +23 -26
- package/dist/mixins/app/plugins/holidays.d.ts +23 -26
- package/dist/mixins/app/plugins/identity.d.ts +23 -26
- package/dist/mixins/app/plugins/llm.d.ts +23 -26
- package/dist/mixins/app/plugins/ocr.d.ts +23 -26
- package/dist/mixins/app/plugins/pg.d.ts +23 -26
- package/dist/mixins/app/plugins/push.d.ts +23 -26
- package/dist/mixins/app/plugins/sms.d.ts +23 -26
- package/dist/mixins/app/plugins/taxinvoice.d.ts +23 -26
- package/dist/mixins/app/routes/account.d.ts +23 -26
- package/dist/mixins/app/routes/board.d.ts +23 -26
- package/dist/mixins/app/routes/email-verify.d.ts +23 -26
- package/dist/mixins/app/routes/oauth.d.ts +23 -26
- package/dist/mixins/app/routes/password-reset.d.ts +23 -26
- package/dist/mixins/app/routes/two-factor.d.ts +23 -26
- package/dist/mixins/server/admin.d.ts +29 -32
- package/dist/mixins/server/admin.js +1 -1
- package/dist/mixins/server/admin.js.map +2 -2
- package/dist/mixins/server/auth.d.ts +26 -28
- package/dist/mixins/server/auth.js +1 -1
- package/dist/mixins/server/auth.js.map +2 -2
- package/dist/mixins/server/entity.d.ts +23 -26
- package/dist/mixins/server/entity.js +1 -1
- package/dist/mixins/server/entity.js.map +2 -2
- package/dist/mixins/server/file.d.ts +23 -26
- package/dist/mixins/server/file.js +1 -1
- package/dist/mixins/server/file.js.map +2 -2
- package/dist/mixins/server/push.d.ts +23 -26
- package/dist/mixins/server/smtp.d.ts +23 -26
- package/dist/mixins/server/smtp.js +1 -1
- package/dist/mixins/server/smtp.js.map +2 -2
- package/dist/mixins/server/transaction.d.ts +23 -26
- package/dist/mixins/server/transaction.js +1 -1
- package/dist/mixins/server/transaction.js.map +2 -2
- package/dist/mixins/server/utils.d.ts +23 -26
- package/dist/mixins/server/utils.js +1 -1
- package/dist/mixins/server/utils.js.map +2 -2
- package/dist/react.js +1 -1
- package/dist/react.js.map +3 -3
- package/package.json +1 -1
|
@@ -33,7 +33,7 @@ export type AuthLoginResponse = AuthLoginSuccessResponse | AuthLoginRequiresTwoF
|
|
|
33
33
|
export declare function isAuthLoginSuccessResponse(response: AuthLoginResponse): response is AuthLoginSuccessResponse;
|
|
34
34
|
export declare function AuthMixin<TBase extends GConstructor<EntityServerClientBase>>(Base: TBase): {
|
|
35
35
|
new (...args: any[]): {
|
|
36
|
-
|
|
36
|
+
csrfRefresher: () => Promise<void>;
|
|
37
37
|
/**
|
|
38
38
|
* 서버 헬스 체크를 수행하고 패킷 암호화 활성 여부를 자동으로 감지합니다.
|
|
39
39
|
*
|
|
@@ -47,10 +47,11 @@ export declare function AuthMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
47
47
|
checkHealth(bootstrapAuth?: boolean): Promise<{
|
|
48
48
|
status: string;
|
|
49
49
|
authenticated?: boolean;
|
|
50
|
+
packet_encryption?: boolean;
|
|
50
51
|
}>;
|
|
51
52
|
/** document.cookie 또는 Node 환경에서 쿠키 값 읽기 (SSR 대응) */
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
readCookie(name: string): string | null;
|
|
54
|
+
ensurePublicAuthBootstrap(): Promise<void>;
|
|
54
55
|
/** 로그인 응답을 반환합니다. 성공 시에만 `access_token`을 내부 상태에 저장합니다. */
|
|
55
56
|
login(email: string, password: string): Promise<AuthLoginResponse>;
|
|
56
57
|
/** HttpOnly refresh cookie로 Access Token을 재발급받아 내부 토큰을 교체합니다. */
|
|
@@ -96,23 +97,23 @@ export declare function AuthMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
96
97
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
97
98
|
onSessionExpired?: (error: Error) => void;
|
|
98
99
|
onHealthChange?: (online: boolean) => void;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
sessionRefreshToken: string | null;
|
|
101
|
+
refreshTimer: ReturnType<typeof setTimeout> | null;
|
|
102
|
+
healthTickTimer: ReturnType<typeof setInterval> | null;
|
|
103
|
+
healthTickPromise: Promise<unknown> | null;
|
|
103
104
|
realtimeEnabled: boolean;
|
|
104
105
|
realtimePath: string;
|
|
105
106
|
realtimeAutoConnect: boolean;
|
|
106
107
|
realtimeAutoReconnect: boolean;
|
|
107
108
|
realtimeReconnectDelayMs: number;
|
|
108
109
|
realtimeStatus: import("../../types.js").RealtimeConnectionStatus;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
realtimeSocket: WebSocket | null;
|
|
111
|
+
realtimeConnectPromise: Promise<void> | null;
|
|
112
|
+
realtimeReconnectTimer: ReturnType<typeof setTimeout> | null;
|
|
113
|
+
realtimeShouldReconnect: boolean;
|
|
114
|
+
realtimeMessageListeners: Set<import("../../types.js").RealtimeMessageListener>;
|
|
115
|
+
realtimeStatusListeners: Set<import("../../types.js").RealtimeStatusListener>;
|
|
116
|
+
realtimeEventListeners: Map<string, Set<import("../../types.js").RealtimeMessageListener>>;
|
|
116
117
|
configure(options: Partial<import("../../types.js").EntityServerClientOptions>): void;
|
|
117
118
|
setToken(token: string): void;
|
|
118
119
|
setAnonymousPacketToken(token: string): void;
|
|
@@ -133,21 +134,21 @@ export declare function AuthMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
133
134
|
unsubscribeRealtime(subscriptions: string[]): boolean;
|
|
134
135
|
startHealthTick(intervalMs?: number): void;
|
|
135
136
|
stopHealthTick(): void;
|
|
136
|
-
|
|
137
|
+
scheduleKeepSession(refreshToken: string, expiresIn: number, refreshFn: (rt: string) => Promise<{
|
|
137
138
|
access_token: string;
|
|
138
139
|
expires_in: number;
|
|
139
140
|
}>): void;
|
|
140
|
-
|
|
141
|
+
clearRefreshTimer(): void;
|
|
141
142
|
stopKeepSession(): void;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
applyRealtimeOptions(options?: boolean | import("../../types.js").RealtimeClientOptions): void;
|
|
144
|
+
buildRealtimeUrl(): string;
|
|
145
|
+
handleRealtimeMessage(payload: unknown): void;
|
|
146
|
+
scheduleRealtimeReconnect(reason: string): void;
|
|
147
|
+
clearRealtimeReconnectTimer(): void;
|
|
148
|
+
setRealtimeStatus(status: import("../../types.js").RealtimeConnectionStatus, reason?: string, error?: Error): void;
|
|
149
|
+
applyCsrfHealth(): void;
|
|
149
150
|
readRequestBody<T = Record<string, unknown>>(body: ArrayBuffer | Uint8Array | string | T | null | undefined, contentType?: string, requireEncrypted?: boolean): T;
|
|
150
|
-
get
|
|
151
|
+
get reqOpts(): import("../../client/request.js").RequestOptions;
|
|
151
152
|
get http(): {
|
|
152
153
|
get<T>(path: string, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
153
154
|
post<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
@@ -155,12 +156,9 @@ export declare function AuthMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
155
156
|
patch<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
156
157
|
delete<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
157
158
|
};
|
|
159
|
+
request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
158
160
|
requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
159
161
|
requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
160
162
|
requestFormBinary(method: string, path: string, form: FormData, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
161
|
-
_request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
162
|
-
_requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
163
|
-
_requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
164
|
-
_requestFormBinary(method: string, path: string, form: FormData, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
165
163
|
};
|
|
166
164
|
} & TBase;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{entityRequest as c}from"../../client/request.js";function h(n){return n.ok===!0&&n.requires_2fa!==!0&&typeof n.data=="object"&&n.data!==null&&"access_token"in n.data}function
|
|
1
|
+
import{entityRequest as c}from"../../client/request.js";function h(n){return n.ok===!0&&n.requires_2fa!==!0&&typeof n.data=="object"&&n.data!==null&&"access_token"in n.data}function d(n){return class extends n{csrfRefresher=()=>this.checkHealth(this.keepSession).then(()=>{});async checkHealth(e=!1){const t=this.token,s={};e&&(s["X-Session-Bootstrap"]="1");const r=await fetch(`${this.baseUrl}/v1/health`,{signal:AbortSignal.timeout(3e3),credentials:"include",headers:s}),i=await r.json(),o=r.headers.get("X-Access-Token");o&&(this.token=o,e&&o!==t&&this.onTokenRefreshed?.(o,0),e&&i.authenticated===!0&&this.realtimeEnabled&&this.realtimeAutoConnect&&this.connectRealtime().catch(()=>{}));const a=this.readCookie("anon_token");return i.packet_encryption===!0&&a&&(this.anonymousPacketToken=a,this.encryptRequests=!0),this.applyCsrfHealth(),e&&i.authenticated===!1&&t&&(this.disconnectRealtime("session_expired"),this.onSessionExpired?.(new Error("Session expired"))),i}readCookie(e){if(typeof document>"u")return null;const t=document.cookie.split(";").map(s=>s.trim()).find(s=>s.startsWith(`${e}=`));if(!t)return null;try{return decodeURIComponent(t.slice(e.length+1))}catch{return t.slice(e.length+1)}}async ensurePublicAuthBootstrap(){if(typeof document>"u"||this.apiKey&&this.hmacSecret)return;const e=!!this.anonymousPacketToken||!!this.readCookie("anon_token"),t=!!this.readCookie(this.csrfCookieName);e&&t&&this.csrfEnabled||await this.checkHealth(!1)}async login(e,t){await this.ensurePublicAuthBootstrap();const s=await c(this.reqOpts,"POST","/v1/auth/login",{email:e,passwd:t},!1,{},{requireOkShape:!1,allowStatuses:[403]});return h(s)&&(this.token=s.data.access_token,this.applyCsrfHealth(),this.keepSession&&this.healthTickTimer===null&&this.startHealthTick(),this.realtimeEnabled&&this.realtimeAutoConnect&&this.connectRealtime().catch(()=>{})),s}async tokenRefresh(){const e=await this.request("POST","/v1/auth/token_refresh",void 0,!1);return this.token=e.data.access_token,this.applyCsrfHealth(),e.data}async refreshToken(e){if(!e)return this.tokenRefresh();const t=await this.request("POST","/v1/auth/refresh",{refresh_token:e},!1);return this.token=t.data.access_token,this.applyCsrfHealth(),t.data}async logout(e){this.stopKeepSession(),this.stopHealthTick(),this.disconnectRealtime("logout");const t=await this.request("POST","/v1/auth/logout",e?{refresh_token:e}:void 0,!1);return this.token="",this.applyCsrfHealth(),t}me(){return this.request("GET","/v1/auth/me")}withdraw(e){return this.request("POST","/v1/auth/withdraw",e?{passwd:e}:{})}}}export{d as AuthMixin,h as isAuthLoginSuccessResponse};
|
|
2
2
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/mixins/server/auth.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n GConstructor,\n EntityServerClientBase,\n} from \"../../client/base.js\";\nimport { entityRequest } from \"../../client/request.js\";\n\nexport interface AuthLoginSuccessData {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n force_password_change?: boolean;\n password_expired?: boolean;\n password_expires_in_days?: number;\n}\n\nexport interface AuthLoginSuccessResponse {\n ok: true;\n data: AuthLoginSuccessData;\n requires_2fa?: false;\n}\n\nexport interface AuthLoginRequiresTwoFactorResponse {\n ok: true;\n requires_2fa: true;\n data: {\n two_factor_token: string;\n expires_in: number;\n };\n}\n\nexport interface AuthLoginSetupRequiredResponse {\n ok: false;\n error: \"2fa_setup_required\";\n message: string;\n data: {\n setup_token: string;\n expires_in: number;\n };\n}\n\nexport type AuthLoginResponse =\n | AuthLoginSuccessResponse\n | AuthLoginRequiresTwoFactorResponse\n | AuthLoginSetupRequiredResponse;\n\nexport function isAuthLoginSuccessResponse(\n response: AuthLoginResponse,\n): response is AuthLoginSuccessResponse {\n return (\n response.ok === true &&\n response.requires_2fa !== true &&\n typeof response.data === \"object\" &&\n response.data !== null &&\n \"access_token\" in response.data\n );\n}\n\nexport function AuthMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class AuthMixinClass extends Base {\n // health tick\uC774 \uCF1C\uC838 \uC788\uC73C\uBA74 keepSession \uC5EC\uBD80\uC5D0 \uB530\uB77C \uC138\uC158 \uBD80\uD2B8\uC2A4\uD2B8\uB7A9\uAE4C\uC9C0 \uD568\uAED8 \uCC98\uB9AC\uD569\uB2C8\uB2E4.\n _csrfRefresher = (): Promise<void> =>\n this.checkHealth(this.keepSession).then(() => {});\n\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(\n bootstrapAuth = false,\n ): Promise<{ status: string; authenticated?: boolean }> {\n const previousToken = this.token;\n const headers: Record<string, string> = {};\n if (bootstrapAuth) {\n headers[\"X-Session-Bootstrap\"] = \"1\";\n }\n\n const res = await fetch(`${this.baseUrl}/v1/health`, {\n signal: AbortSignal.timeout(3000),\n credentials: \"include\",\n headers,\n });\n const data = (await res.json()) as {\n status: string;\n authenticated?: boolean;\n };\n\n const accessToken = res.headers.get(\"X-Access-Token\");\n if (accessToken) {\n this.token = accessToken;\n if (bootstrapAuth && accessToken !== previousToken) {\n this.onTokenRefreshed?.(accessToken, 0);\n }\n if (\n bootstrapAuth &&\n data.authenticated === true &&\n this.realtimeEnabled &&\n this.realtimeAutoConnect\n ) {\n this.connectRealtime().catch(() => {});\n }\n }\n\n // anon_token \uCFE0\uD0A4\uC5D0\uC11C \uC775\uBA85 \uD328\uD0B7 \uD1A0\uD070 \uC77D\uAE30 \u2014 \uC874\uC7AC\uD558\uBA74 \uC11C\uBC84 \uD328\uD0B7 \uC554\uD638\uD654 \uD65C\uC131 \uC0C1\uD0DC\n const anonToken = this._readCookie(\"anon_token\");\n if (anonToken) {\n this.anonymousPacketToken = anonToken;\n this.encryptRequests = true;\n }\n\n this._applyCsrfHealth();\n if (\n bootstrapAuth &&\n data.authenticated === false &&\n previousToken\n ) {\n this.disconnectRealtime(\"session_expired\");\n this.onSessionExpired?.(new Error(\"Session expired\"));\n }\n return data;\n }\n\n /** document.cookie \uB610\uB294 Node \uD658\uACBD\uC5D0\uC11C \uCFE0\uD0A4 \uAC12 \uC77D\uAE30 (SSR \uB300\uC751) */\n _readCookie(name: string): string | null {\n if (typeof document === \"undefined\") return null;\n const match = document.cookie\n .split(\";\")\n .map((c) => c.trim())\n .find((c) => c.startsWith(`${name}=`));\n if (!match) return null;\n try {\n return decodeURIComponent(match.slice(name.length + 1));\n } catch {\n return match.slice(name.length + 1);\n }\n }\n\n async _ensurePublicAuthBootstrap(): Promise<void> {\n if (typeof document === \"undefined\") {\n return;\n }\n\n if (this.apiKey && this.hmacSecret) {\n return;\n }\n\n const hasAnonymousPacketToken =\n !!this.anonymousPacketToken || !!this._readCookie(\"anon_token\");\n const hasCsrfCookie = !!this._readCookie(this.csrfCookieName);\n\n if (hasAnonymousPacketToken && hasCsrfCookie && this.csrfEnabled) {\n return;\n }\n\n await this.checkHealth(false);\n }\n\n /** \uB85C\uADF8\uC778 \uC751\uB2F5\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. \uC131\uACF5 \uC2DC\uC5D0\uB9CC `access_token`\uC744 \uB0B4\uBD80 \uC0C1\uD0DC\uC5D0 \uC800\uC7A5\uD569\uB2C8\uB2E4. */\n async login(\n email: string,\n password: string,\n ): Promise<AuthLoginResponse> {\n await this._ensurePublicAuthBootstrap();\n\n const response = await entityRequest<AuthLoginResponse>(\n this._reqOpts,\n \"POST\",\n \"/v1/auth/login\",\n { email, passwd: password },\n false,\n {},\n { requireOkShape: false, allowStatuses: [403] },\n );\n\n if (isAuthLoginSuccessResponse(response)) {\n this.token = response.data.access_token;\n this._applyCsrfHealth();\n if (this.keepSession && this._healthTickTimer === null) {\n this.startHealthTick();\n }\n if (this.realtimeEnabled && this.realtimeAutoConnect) {\n this.connectRealtime().catch(() => {});\n }\n }\n\n return response;\n }\n\n /** HttpOnly refresh cookie\uB85C Access Token\uC744 \uC7AC\uBC1C\uAE09\uBC1B\uC544 \uB0B4\uBD80 \uD1A0\uD070\uC744 \uAD50\uCCB4\uD569\uB2C8\uB2E4. */\n async tokenRefresh(): 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/token_refresh\", undefined, false);\n this.token = data.data.access_token;\n this._applyCsrfHealth();\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(refreshToken?: string): Promise<{\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n }> {\n if (!refreshToken) {\n return this.tokenRefresh();\n }\n\n const data = await this._request<{\n data: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n }>(\n \"POST\",\n \"/v1/auth/refresh\",\n { refresh_token: refreshToken },\n false,\n );\n this.token = data.data.access_token;\n this._applyCsrfHealth();\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 this.stopHealthTick();\n this.disconnectRealtime(\"logout\");\n const data = await this._request<{ ok: boolean }>(\n \"POST\",\n \"/v1/auth/logout\",\n refreshToken ? { refresh_token: refreshToken } : undefined,\n false,\n );\n this.token = \"\";\n this._applyCsrfHealth();\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 /** \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"],
|
|
5
|
-
"mappings": "AAIA,OAAS,iBAAAA,MAAqB,0BAyCvB,SAASC,EACZC,EACoC,CACpC,OACIA,EAAS,KAAO,IAChBA,EAAS,eAAiB,IAC1B,OAAOA,EAAS,MAAS,UACzBA,EAAS,OAAS,MAClB,iBAAkBA,EAAS,IAEnC,CAEO,SAASC,EACZC,EACF,CACE,OAAO,cAA6BA,CAAK,CAErC,
|
|
4
|
+
"sourcesContent": ["import type {\n GConstructor,\n EntityServerClientBase,\n} from \"../../client/base.js\";\nimport { entityRequest } from \"../../client/request.js\";\n\nexport interface AuthLoginSuccessData {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n force_password_change?: boolean;\n password_expired?: boolean;\n password_expires_in_days?: number;\n}\n\nexport interface AuthLoginSuccessResponse {\n ok: true;\n data: AuthLoginSuccessData;\n requires_2fa?: false;\n}\n\nexport interface AuthLoginRequiresTwoFactorResponse {\n ok: true;\n requires_2fa: true;\n data: {\n two_factor_token: string;\n expires_in: number;\n };\n}\n\nexport interface AuthLoginSetupRequiredResponse {\n ok: false;\n error: \"2fa_setup_required\";\n message: string;\n data: {\n setup_token: string;\n expires_in: number;\n };\n}\n\nexport type AuthLoginResponse =\n | AuthLoginSuccessResponse\n | AuthLoginRequiresTwoFactorResponse\n | AuthLoginSetupRequiredResponse;\n\nexport function isAuthLoginSuccessResponse(\n response: AuthLoginResponse,\n): response is AuthLoginSuccessResponse {\n return (\n response.ok === true &&\n response.requires_2fa !== true &&\n typeof response.data === \"object\" &&\n response.data !== null &&\n \"access_token\" in response.data\n );\n}\n\nexport function AuthMixin<TBase extends GConstructor<EntityServerClientBase>>(\n Base: TBase,\n) {\n return class AuthMixinClass extends Base {\n // health tick\uC774 \uCF1C\uC838 \uC788\uC73C\uBA74 keepSession \uC5EC\uBD80\uC5D0 \uB530\uB77C \uC138\uC158 \uBD80\uD2B8\uC2A4\uD2B8\uB7A9\uAE4C\uC9C0 \uD568\uAED8 \uCC98\uB9AC\uD569\uB2C8\uB2E4.\n csrfRefresher = (): Promise<void> =>\n this.checkHealth(this.keepSession).then(() => {});\n\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(bootstrapAuth = false): Promise<{\n status: string;\n authenticated?: boolean;\n packet_encryption?: boolean;\n }> {\n const previousToken = this.token;\n const headers: Record<string, string> = {};\n if (bootstrapAuth) {\n headers[\"X-Session-Bootstrap\"] = \"1\";\n }\n\n const res = await fetch(`${this.baseUrl}/v1/health`, {\n signal: AbortSignal.timeout(3000),\n credentials: \"include\",\n headers,\n });\n const data = (await res.json()) as {\n status: string;\n authenticated?: boolean;\n packet_encryption?: boolean;\n };\n\n const accessToken = res.headers.get(\"X-Access-Token\");\n if (accessToken) {\n this.token = accessToken;\n if (bootstrapAuth && accessToken !== previousToken) {\n this.onTokenRefreshed?.(accessToken, 0);\n }\n if (\n bootstrapAuth &&\n data.authenticated === true &&\n this.realtimeEnabled &&\n this.realtimeAutoConnect\n ) {\n this.connectRealtime().catch(() => {});\n }\n }\n\n // \uD328\uD0B7 \uC554\uD638\uD654\uB294 health \uC751\uB2F5\uC774 \uBA85\uC2DC\uC801\uC73C\uB85C \uD65C\uC131\uC774\uB77C\uACE0 \uC54C\uB824\uC904 \uB54C\uB9CC \uC790\uB3D9 \uD65C\uC131\uD654\uD55C\uB2E4.\n const anonToken = this.readCookie(\"anon_token\");\n if (data.packet_encryption === true && anonToken) {\n this.anonymousPacketToken = anonToken;\n this.encryptRequests = true;\n }\n\n this.applyCsrfHealth();\n if (\n bootstrapAuth &&\n data.authenticated === false &&\n previousToken\n ) {\n this.disconnectRealtime(\"session_expired\");\n this.onSessionExpired?.(new Error(\"Session expired\"));\n }\n return data;\n }\n\n /** document.cookie \uB610\uB294 Node \uD658\uACBD\uC5D0\uC11C \uCFE0\uD0A4 \uAC12 \uC77D\uAE30 (SSR \uB300\uC751) */\n readCookie(name: string): string | null {\n if (typeof document === \"undefined\") return null;\n const match = document.cookie\n .split(\";\")\n .map((c) => c.trim())\n .find((c) => c.startsWith(`${name}=`));\n if (!match) return null;\n try {\n return decodeURIComponent(match.slice(name.length + 1));\n } catch {\n return match.slice(name.length + 1);\n }\n }\n\n async ensurePublicAuthBootstrap(): Promise<void> {\n if (typeof document === \"undefined\") {\n return;\n }\n\n if (this.apiKey && this.hmacSecret) {\n return;\n }\n\n const hasAnonymousPacketToken =\n !!this.anonymousPacketToken || !!this.readCookie(\"anon_token\");\n const hasCsrfCookie = !!this.readCookie(this.csrfCookieName);\n\n if (hasAnonymousPacketToken && hasCsrfCookie && this.csrfEnabled) {\n return;\n }\n\n await this.checkHealth(false);\n }\n\n /** \uB85C\uADF8\uC778 \uC751\uB2F5\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. \uC131\uACF5 \uC2DC\uC5D0\uB9CC `access_token`\uC744 \uB0B4\uBD80 \uC0C1\uD0DC\uC5D0 \uC800\uC7A5\uD569\uB2C8\uB2E4. */\n async login(\n email: string,\n password: string,\n ): Promise<AuthLoginResponse> {\n await this.ensurePublicAuthBootstrap();\n\n const response = await entityRequest<AuthLoginResponse>(\n this.reqOpts,\n \"POST\",\n \"/v1/auth/login\",\n { email, passwd: password },\n false,\n {},\n { requireOkShape: false, allowStatuses: [403] },\n );\n\n if (isAuthLoginSuccessResponse(response)) {\n this.token = response.data.access_token;\n this.applyCsrfHealth();\n if (this.keepSession && this.healthTickTimer === null) {\n this.startHealthTick();\n }\n if (this.realtimeEnabled && this.realtimeAutoConnect) {\n this.connectRealtime().catch(() => {});\n }\n }\n\n return response;\n }\n\n /** HttpOnly refresh cookie\uB85C Access Token\uC744 \uC7AC\uBC1C\uAE09\uBC1B\uC544 \uB0B4\uBD80 \uD1A0\uD070\uC744 \uAD50\uCCB4\uD569\uB2C8\uB2E4. */\n async tokenRefresh(): 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/token_refresh\", undefined, false);\n this.token = data.data.access_token;\n this.applyCsrfHealth();\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(refreshToken?: string): Promise<{\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n }> {\n if (!refreshToken) {\n return this.tokenRefresh();\n }\n\n const data = await this.request<{\n data: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n }>(\n \"POST\",\n \"/v1/auth/refresh\",\n { refresh_token: refreshToken },\n false,\n );\n this.token = data.data.access_token;\n this.applyCsrfHealth();\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 this.stopHealthTick();\n this.disconnectRealtime(\"logout\");\n const data = await this.request<{ ok: boolean }>(\n \"POST\",\n \"/v1/auth/logout\",\n refreshToken ? { refresh_token: refreshToken } : undefined,\n false,\n );\n this.token = \"\";\n this.applyCsrfHealth();\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 /** \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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["entityRequest", "isAuthLoginSuccessResponse", "response", "AuthMixin", "Base", "bootstrapAuth", "previousToken", "headers", "res", "data", "accessToken", "anonToken", "name", "match", "c", "hasAnonymousPacketToken", "hasCsrfCookie", "email", "password", "refreshToken", "passwd"]
|
|
7
7
|
}
|
|
@@ -103,30 +103,30 @@ export declare function EntityMixin<TBase extends GConstructor<EntityServerClien
|
|
|
103
103
|
csrfEnabled: boolean;
|
|
104
104
|
csrfHeaderName: string;
|
|
105
105
|
csrfCookieName: string;
|
|
106
|
-
|
|
106
|
+
csrfRefresher: (() => Promise<void>) | null;
|
|
107
107
|
activeTxId: string | null;
|
|
108
108
|
keepSession: boolean;
|
|
109
109
|
refreshBuffer: number;
|
|
110
110
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
111
111
|
onSessionExpired?: (error: Error) => void;
|
|
112
112
|
onHealthChange?: (online: boolean) => void;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
sessionRefreshToken: string | null;
|
|
114
|
+
refreshTimer: ReturnType<typeof setTimeout> | null;
|
|
115
|
+
healthTickTimer: ReturnType<typeof setInterval> | null;
|
|
116
|
+
healthTickPromise: Promise<unknown> | null;
|
|
117
117
|
realtimeEnabled: boolean;
|
|
118
118
|
realtimePath: string;
|
|
119
119
|
realtimeAutoConnect: boolean;
|
|
120
120
|
realtimeAutoReconnect: boolean;
|
|
121
121
|
realtimeReconnectDelayMs: number;
|
|
122
122
|
realtimeStatus: import("../../types.js").RealtimeConnectionStatus;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
realtimeSocket: WebSocket | null;
|
|
124
|
+
realtimeConnectPromise: Promise<void> | null;
|
|
125
|
+
realtimeReconnectTimer: ReturnType<typeof setTimeout> | null;
|
|
126
|
+
realtimeShouldReconnect: boolean;
|
|
127
|
+
realtimeMessageListeners: Set<import("../../types.js").RealtimeMessageListener>;
|
|
128
|
+
realtimeStatusListeners: Set<import("../../types.js").RealtimeStatusListener>;
|
|
129
|
+
realtimeEventListeners: Map<string, Set<import("../../types.js").RealtimeMessageListener>>;
|
|
130
130
|
configure(options: Partial<import("../../types.js").EntityServerClientOptions>): void;
|
|
131
131
|
setToken(token: string): void;
|
|
132
132
|
setAnonymousPacketToken(token: string): void;
|
|
@@ -147,21 +147,21 @@ export declare function EntityMixin<TBase extends GConstructor<EntityServerClien
|
|
|
147
147
|
unsubscribeRealtime(subscriptions: string[]): boolean;
|
|
148
148
|
startHealthTick(intervalMs?: number): void;
|
|
149
149
|
stopHealthTick(): void;
|
|
150
|
-
|
|
150
|
+
scheduleKeepSession(refreshToken: string, expiresIn: number, refreshFn: (rt: string) => Promise<{
|
|
151
151
|
access_token: string;
|
|
152
152
|
expires_in: number;
|
|
153
153
|
}>): void;
|
|
154
|
-
|
|
154
|
+
clearRefreshTimer(): void;
|
|
155
155
|
stopKeepSession(): void;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
applyRealtimeOptions(options?: boolean | import("../../types.js").RealtimeClientOptions): void;
|
|
157
|
+
buildRealtimeUrl(): string;
|
|
158
|
+
handleRealtimeMessage(payload: unknown): void;
|
|
159
|
+
scheduleRealtimeReconnect(reason: string): void;
|
|
160
|
+
clearRealtimeReconnectTimer(): void;
|
|
161
|
+
setRealtimeStatus(status: import("../../types.js").RealtimeConnectionStatus, reason?: string, error?: Error): void;
|
|
162
|
+
applyCsrfHealth(): void;
|
|
163
163
|
readRequestBody<T = Record<string, unknown>>(body: ArrayBuffer | Uint8Array | string | T | null | undefined, contentType?: string, requireEncrypted?: boolean): T;
|
|
164
|
-
get
|
|
164
|
+
get reqOpts(): import("../../client/request.js").RequestOptions;
|
|
165
165
|
get http(): {
|
|
166
166
|
get<T>(path: string, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
167
167
|
post<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
@@ -169,12 +169,9 @@ export declare function EntityMixin<TBase extends GConstructor<EntityServerClien
|
|
|
169
169
|
patch<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
170
170
|
delete<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
171
171
|
};
|
|
172
|
+
request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
172
173
|
requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
173
174
|
requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
174
175
|
requestFormBinary(method: string, path: string, form: FormData, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
175
|
-
_request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
176
|
-
_requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
177
|
-
_requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
178
|
-
_requestFormBinary(method: string, path: string, form: FormData, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
179
176
|
};
|
|
180
177
|
} & TBase;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{buildQuery as u}from"../../client/utils.js";function m(c){return class extends c{async transStart(){const t=await this.
|
|
1
|
+
import{buildQuery as u}from"../../client/utils.js";function m(c){return class extends c{async transStart(){const t=await this.request("POST","/v1/transaction/start",void 0,!1);return this.activeTxId=t.transaction_id,this.activeTxId}transRollback(t){const n=t??this.activeTxId;return n?(this.activeTxId=null,this.request("POST",`/v1/transaction/rollback/${n}`)):Promise.reject(new Error("No active transaction. Call transStart() first."))}transCommit(t){const n=t??this.activeTxId;return n?(this.activeTxId=null,this.request("POST",`/v1/transaction/commit/${n}`)):Promise.reject(new Error("No active transaction. Call transStart() first."))}meta(t){return this.request("POST",`/v1/entity/${t}/meta`,{})}validate(t,n){return this.http.post(`/v1/entity/${t}/validate`,n)}get(t,n,e={}){const r=e.skipHooks?"?skipHooks=true":"";return this.request("GET",`/v1/entity/${t}/${n}${r}`)}find(t,n,e={}){const r=e.skipHooks?"?skipHooks=true":"";return this.request("POST",`/v1/entity/${t}/find${r}`,n??{})}list(t,n={}){const{conditions:e,fields:r,orderDir:i,orderBy:s,...o}=n,a={page:1,limit:20,...o};return s&&(a.orderBy=i==="DESC"?`-${s}`:s),r?.length&&(a.fields=r.join(",")),this.request("POST",`/v1/entity/${t}/list?${u(a)}`,e??{})}count(t,n){return this.request("POST",`/v1/entity/${t}/count`,n??{})}query(t,n){return this.request("POST",`/v1/entity/${t}/query`,n)}submit(t,n,e={}){const r=e.transactionId??this.activeTxId,i=r?{"X-Transaction-ID":r}:void 0,s=e.skipHooks?"?skipHooks=true":"";return this.request("POST",`/v1/entity/${t}/submit${s}`,n,!0,i)}delete(t,n,e={}){const r=new URLSearchParams;e.hard&&r.set("hard","true"),e.skipHooks&&r.set("skipHooks","true");const i=r.size?`?${r}`:"",s=e.transactionId??this.activeTxId,o=s?{"X-Transaction-ID":s}:void 0;return this.request("POST",`/v1/entity/${t}/delete/${n}${i}`,void 0,!0,o)}history(t,n,e={}){return this.request("GET",`/v1/entity/${t}/history/${n}?${u({page:1,limit:50,...e})}`)}rollback(t,n){return this.request("POST",`/v1/entity/${t}/rollback/${n}`)}}}export{m as EntityMixin};
|
|
2
2
|
//# sourceMappingURL=entity.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/mixins/server/entity.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n EntityHistoryRecord,\n EntityListParams,\n EntityListResult,\n EntityQueryRequest,\n} from \"../../types.js\";\nimport { buildQuery } from \"../../client/utils.js\";\nimport type {\n GConstructor,\n EntityServerClientBase,\n} from \"../../client/base.js\";\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 /** \uC5D4\uD2F0\uD2F0 \uC124\uC815 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n meta<T = unknown>(entity: string): Promise<{ ok: boolean; data: T }> {\n return this._request(\"POST\", `/v1/entity/${entity}/meta`, {});\n }\n\n /** \uC5D4\uD2F0\uD2F0 \uB370\uC774\uD130\uB97C \uC800\uC7A5 \uC5C6\uC774 \uAC80\uC99D\uD569\uB2C8\uB2E4. */\n validate<T = unknown>(\n entity: string,\n data: Record<string, unknown>,\n ): Promise<T> {\n return this.http.post(`/v1/entity/${entity}/validate`, data);\n }\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"],
|
|
5
|
-
"mappings": "AAMA,OAAS,cAAAA,MAAkB,wBAMpB,SAASC,EACZC,EACF,CACE,OAAO,cAA+BA,CAAK,CAIvC,MAAM,YAA8B,CAChC,MAAMC,EAAM,MAAM,KAAK,
|
|
4
|
+
"sourcesContent": ["import type {\n EntityHistoryRecord,\n EntityListParams,\n EntityListResult,\n EntityQueryRequest,\n} from \"../../types.js\";\nimport { buildQuery } from \"../../client/utils.js\";\nimport type {\n GConstructor,\n EntityServerClientBase,\n} from \"../../client/base.js\";\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 /** \uC5D4\uD2F0\uD2F0 \uC124\uC815 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. */\n meta<T = unknown>(entity: string): Promise<{ ok: boolean; data: T }> {\n return this.request(\"POST\", `/v1/entity/${entity}/meta`, {});\n }\n\n /** \uC5D4\uD2F0\uD2F0 \uB370\uC774\uD130\uB97C \uC800\uC7A5 \uC5C6\uC774 \uAC80\uC99D\uD569\uB2C8\uB2E4. */\n validate<T = unknown>(\n entity: string,\n data: Record<string, unknown>,\n ): Promise<T> {\n return this.http.post(`/v1/entity/${entity}/validate`, data);\n }\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["buildQuery", "EntityMixin", "Base", "res", "transactionId", "txId", "entity", "data", "seq", "opts", "q", "conditions", "params", "fields", "orderDir", "orderBy", "rest", "queryObj", "req", "extraHeaders", "historySeq"]
|
|
7
7
|
}
|
|
@@ -59,30 +59,30 @@ export declare function FileMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
59
59
|
csrfEnabled: boolean;
|
|
60
60
|
csrfHeaderName: string;
|
|
61
61
|
csrfCookieName: string;
|
|
62
|
-
|
|
62
|
+
csrfRefresher: (() => Promise<void>) | null;
|
|
63
63
|
activeTxId: string | null;
|
|
64
64
|
keepSession: boolean;
|
|
65
65
|
refreshBuffer: number;
|
|
66
66
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
67
67
|
onSessionExpired?: (error: Error) => void;
|
|
68
68
|
onHealthChange?: (online: boolean) => void;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
sessionRefreshToken: string | null;
|
|
70
|
+
refreshTimer: ReturnType<typeof setTimeout> | null;
|
|
71
|
+
healthTickTimer: ReturnType<typeof setInterval> | null;
|
|
72
|
+
healthTickPromise: Promise<unknown> | null;
|
|
73
73
|
realtimeEnabled: boolean;
|
|
74
74
|
realtimePath: string;
|
|
75
75
|
realtimeAutoConnect: boolean;
|
|
76
76
|
realtimeAutoReconnect: boolean;
|
|
77
77
|
realtimeReconnectDelayMs: number;
|
|
78
78
|
realtimeStatus: import("../../types.js").RealtimeConnectionStatus;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
realtimeSocket: WebSocket | null;
|
|
80
|
+
realtimeConnectPromise: Promise<void> | null;
|
|
81
|
+
realtimeReconnectTimer: ReturnType<typeof setTimeout> | null;
|
|
82
|
+
realtimeShouldReconnect: boolean;
|
|
83
|
+
realtimeMessageListeners: Set<import("../../types.js").RealtimeMessageListener>;
|
|
84
|
+
realtimeStatusListeners: Set<import("../../types.js").RealtimeStatusListener>;
|
|
85
|
+
realtimeEventListeners: Map<string, Set<import("../../types.js").RealtimeMessageListener>>;
|
|
86
86
|
configure(options: Partial<import("../../types.js").EntityServerClientOptions>): void;
|
|
87
87
|
setToken(token: string): void;
|
|
88
88
|
setAnonymousPacketToken(token: string): void;
|
|
@@ -103,21 +103,21 @@ export declare function FileMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
103
103
|
unsubscribeRealtime(subscriptions: string[]): boolean;
|
|
104
104
|
startHealthTick(intervalMs?: number): void;
|
|
105
105
|
stopHealthTick(): void;
|
|
106
|
-
|
|
106
|
+
scheduleKeepSession(refreshToken: string, expiresIn: number, refreshFn: (rt: string) => Promise<{
|
|
107
107
|
access_token: string;
|
|
108
108
|
expires_in: number;
|
|
109
109
|
}>): void;
|
|
110
|
-
|
|
110
|
+
clearRefreshTimer(): void;
|
|
111
111
|
stopKeepSession(): void;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
applyRealtimeOptions(options?: boolean | import("../../types.js").RealtimeClientOptions): void;
|
|
113
|
+
buildRealtimeUrl(): string;
|
|
114
|
+
handleRealtimeMessage(payload: unknown): void;
|
|
115
|
+
scheduleRealtimeReconnect(reason: string): void;
|
|
116
|
+
clearRealtimeReconnectTimer(): void;
|
|
117
|
+
setRealtimeStatus(status: import("../../types.js").RealtimeConnectionStatus, reason?: string, error?: Error): void;
|
|
118
|
+
applyCsrfHealth(): void;
|
|
119
119
|
readRequestBody<T = Record<string, unknown>>(body: ArrayBuffer | Uint8Array | string | T | null | undefined, contentType?: string, requireEncrypted?: boolean): T;
|
|
120
|
-
get
|
|
120
|
+
get reqOpts(): import("../../client/request.js").RequestOptions;
|
|
121
121
|
get http(): {
|
|
122
122
|
get<T>(path: string, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
123
123
|
post<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
@@ -125,12 +125,9 @@ export declare function FileMixin<TBase extends GConstructor<EntityServerClientB
|
|
|
125
125
|
patch<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
126
126
|
delete<T>(path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
127
127
|
};
|
|
128
|
+
request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
128
129
|
requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
129
130
|
requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
130
131
|
requestFormBinary(method: string, path: string, form: FormData, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
131
|
-
_request<T>(method: string, path: string, body?: unknown, withAuth?: boolean, extraHeaders?: Record<string, string>): Promise<T>;
|
|
132
|
-
_requestBinary(method: string, path: string, body?: unknown, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
133
|
-
_requestForm<T>(method: string, path: string, form: FormData, withAuth?: boolean): Promise<T>;
|
|
134
|
-
_requestFormBinary(method: string, path: string, form: FormData, withAuth?: boolean): Promise<ArrayBuffer>;
|
|
135
132
|
};
|
|
136
133
|
} & TBase;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function o(s){return class extends s{async fileUpload(e,i,t={}){const r=new FormData;return r.append("file",i,i instanceof File?i.name:"upload"),t.refSeq!=null&&r.append("ref_seq",String(t.refSeq)),t.isPublic!=null&&r.append("is_public",t.isPublic?"true":"false"),this.
|
|
1
|
+
function o(s){return class extends s{async fileUpload(e,i,t={}){const r=new FormData;return r.append("file",i,i instanceof File?i.name:"upload"),t.refSeq!=null&&r.append("ref_seq",String(t.refSeq)),t.isPublic!=null&&r.append("is_public",t.isPublic?"true":"false"),this.requestForm("POST",`/v1/files/${e}/upload`,r)}fileDownload(e,i){return this.requestBinary("POST",`/v1/files/${e}/download/${i}`,{})}fileDelete(e,i){return this.request("POST",`/v1/files/${e}/delete/${i}`,{})}fileList(e,i={}){return this.request("POST",`/v1/files/${e}/list`,i.refSeq?{ref_seq:i.refSeq}:{})}fileMeta(e,i){return this.request("POST",`/v1/files/${e}/meta/${i}`,{})}fileToken(e){return this.request("POST",`/v1/files/token/${e}`,{})}fileViewUrl(e,i={}){const t=i.download?"?download=true":"";return`${this.baseUrl}/v1/files/${e}${t}`}fileUrl(e){return`${this.baseUrl}/v1/files/${e}`}}}export{o as FileMixin};
|
|
2
2
|
//# sourceMappingURL=file.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/mixins/server/file.ts"],
|
|
4
|
-
"sourcesContent": ["import type { FileMeta, FileUploadOptions } from \"../../types.js\";\nimport type { GConstructor, EntityServerClientBase } from \"../../client/base.js\";\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.
|
|
5
|
-
"mappings": "AAGO,SAASA,EACZC,EACF,CACE,OAAO,cAA6BA,CAAK,CAYrC,MAAM,WACFC,EACAC,EACAC,EAA0B,CAAC,EAC2B,CACtD,MAAMC,EAAO,IAAI,SACjB,OAAAA,EAAK,OACD,OACAF,EACAA,aAAgB,KAAOA,EAAK,KAAO,QACvC,EACIC,EAAK,QAAU,MACfC,EAAK,OAAO,UAAW,OAAOD,EAAK,MAAM,CAAC,EAC1CA,EAAK,UAAY,MACjBC,EAAK,OAAO,YAAaD,EAAK,SAAW,OAAS,OAAO,EACtD,KAAK,
|
|
4
|
+
"sourcesContent": ["import type { FileMeta, FileUploadOptions } from \"../../types.js\";\nimport type { GConstructor, EntityServerClientBase } from \"../../client/base.js\";\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/\uB2E4\uC6B4\uB85C\uB4DC URL\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. */\n fileViewUrl(uuid: string, opts: { download?: boolean } = {}): string {\n const qs = opts.download ? \"?download=true\" : \"\";\n return `${this.baseUrl}/v1/files/${uuid}${qs}`;\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"],
|
|
5
|
+
"mappings": "AAGO,SAASA,EACZC,EACF,CACE,OAAO,cAA6BA,CAAK,CAYrC,MAAM,WACFC,EACAC,EACAC,EAA0B,CAAC,EAC2B,CACtD,MAAMC,EAAO,IAAI,SACjB,OAAAA,EAAK,OACD,OACAF,EACAA,aAAgB,KAAOA,EAAK,KAAO,QACvC,EACIC,EAAK,QAAU,MACfC,EAAK,OAAO,UAAW,OAAOD,EAAK,MAAM,CAAC,EAC1CA,EAAK,UAAY,MACjBC,EAAK,OAAO,YAAaD,EAAK,SAAW,OAAS,OAAO,EACtD,KAAK,YACR,OACA,aAAaF,CAAM,UACnBG,CACJ,CACJ,CAGA,aAAaH,EAAgBI,EAAoC,CAC7D,OAAO,KAAK,cACR,OACA,aAAaJ,CAAM,aAAaI,CAAI,GACpC,CAAC,CACL,CACJ,CAGA,WACIJ,EACAI,EACwD,CACxD,OAAO,KAAK,QACR,OACA,aAAaJ,CAAM,WAAWI,CAAI,GAClC,CAAC,CACL,CACJ,CAGA,SACIJ,EACAE,EAA4B,CAAC,EAI9B,CACC,OAAO,KAAK,QACR,OACA,aAAaF,CAAM,QACnBE,EAAK,OAAS,CAAE,QAASA,EAAK,MAAO,EAAI,CAAC,CAC9C,CACJ,CAGA,SACIF,EACAI,EACwC,CACxC,OAAO,KAAK,QACR,OACA,aAAaJ,CAAM,SAASI,CAAI,GAChC,CAAC,CACL,CACJ,CAGA,UAAUA,EAAuD,CAC7D,OAAO,KAAK,QAAQ,OAAQ,mBAAmBA,CAAI,GAAI,CAAC,CAAC,CAC7D,CAGA,YAAYA,EAAcF,EAA+B,CAAC,EAAW,CACjE,MAAMG,EAAKH,EAAK,SAAW,iBAAmB,GAC9C,MAAO,GAAG,KAAK,OAAO,aAAaE,CAAI,GAAGC,CAAE,EAChD,CAGA,QAAQD,EAAsB,CAC1B,MAAO,GAAG,KAAK,OAAO,aAAaA,CAAI,EAC3C,CACJ,CACJ",
|
|
6
6
|
"names": ["FileMixin", "Base", "entity", "file", "opts", "form", "uuid", "qs"]
|
|
7
7
|
}
|