entity-client 1.0.7 → 1.0.9
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 +362 -0
- package/dist/EntityAppServerApi.d.ts +1016 -0
- package/dist/EntityAppServerApi.js +2 -0
- package/dist/EntityAppServerApi.js.map +7 -0
- package/dist/{EntityServerClient.d.ts → EntityServerApi.d.ts} +160 -101
- package/dist/EntityServerApi.js +2 -0
- package/dist/EntityServerApi.js.map +7 -0
- package/dist/client/base.d.ts +29 -16
- package/dist/client/base.js +1 -1
- package/dist/client/base.js.map +3 -3
- package/dist/client/request.d.ts +2 -2
- package/dist/client/request.js +1 -1
- package/dist/client/request.js.map +3 -3
- package/dist/hooks/useEntityAppServer.d.ts +18 -0
- package/dist/hooks/useEntityAppServer.js +2 -0
- package/dist/hooks/useEntityAppServer.js.map +7 -0
- package/dist/hooks/useEntityClient.d.ts +74 -0
- package/dist/hooks/useEntityClient.js +2 -0
- package/dist/hooks/useEntityClient.js.map +7 -0
- package/dist/hooks/useEntityServer.d.ts +5 -88
- package/dist/hooks/useEntityServer.js +1 -1
- package/dist/hooks/useEntityServer.js.map +3 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +4 -4
- package/dist/mixins/app/index.d.ts +6 -6
- package/dist/mixins/app/index.js +1 -1
- package/dist/mixins/app/index.js.map +2 -2
- package/dist/mixins/app/plugins/alimtalk.d.ts +64 -0
- package/dist/mixins/app/plugins/alimtalk.js +2 -0
- package/dist/mixins/app/plugins/alimtalk.js.map +7 -0
- package/dist/mixins/app/plugins/friendtalk.d.ts +58 -0
- package/dist/mixins/app/plugins/friendtalk.js +2 -0
- package/dist/mixins/app/plugins/friendtalk.js.map +7 -0
- package/dist/mixins/app/plugins/holidays.d.ts +66 -0
- package/dist/mixins/app/plugins/holidays.js +2 -0
- package/dist/mixins/app/plugins/holidays.js.map +7 -0
- package/dist/mixins/app/plugins/identity.d.ts +64 -0
- package/dist/mixins/app/plugins/identity.js +2 -0
- package/dist/mixins/app/plugins/identity.js.map +7 -0
- package/dist/mixins/app/plugins/index.d.ts +10 -0
- package/dist/mixins/app/plugins/index.js +2 -0
- package/dist/mixins/app/plugins/index.js.map +7 -0
- package/dist/mixins/app/plugins/llm.d.ts +126 -0
- package/dist/mixins/app/plugins/llm.js +2 -0
- package/dist/mixins/app/plugins/llm.js.map +7 -0
- package/dist/mixins/app/plugins/ocr.d.ts +72 -0
- package/dist/mixins/app/plugins/ocr.js +2 -0
- package/dist/mixins/app/plugins/ocr.js.map +7 -0
- package/dist/mixins/app/plugins/pg.d.ts +70 -0
- package/dist/mixins/app/plugins/pg.js +2 -0
- package/dist/mixins/app/plugins/pg.js.map +7 -0
- package/dist/mixins/app/plugins/push.d.ts +66 -0
- package/dist/mixins/app/plugins/push.js +2 -0
- package/dist/mixins/app/plugins/push.js.map +7 -0
- package/dist/mixins/app/plugins/sms.d.ts +64 -0
- package/dist/mixins/app/plugins/sms.js +2 -0
- package/dist/mixins/app/plugins/sms.js.map +7 -0
- package/dist/mixins/app/plugins/taxinvoice.d.ts +68 -0
- package/dist/mixins/app/plugins/taxinvoice.js +2 -0
- package/dist/mixins/app/plugins/taxinvoice.js.map +7 -0
- package/dist/mixins/app/{account.d.ts → routes/account.d.ts} +17 -15
- package/dist/mixins/app/routes/account.js +2 -0
- package/dist/mixins/app/routes/account.js.map +7 -0
- package/dist/mixins/app/{board.d.ts → routes/board.d.ts} +17 -15
- package/dist/mixins/app/routes/board.js +2 -0
- package/dist/mixins/app/routes/board.js.map +7 -0
- package/dist/mixins/app/{email-verify.d.ts → routes/email-verify.d.ts} +17 -15
- package/dist/mixins/app/routes/email-verify.js +2 -0
- package/dist/mixins/app/routes/email-verify.js.map +7 -0
- package/dist/mixins/app/{oauth.d.ts → routes/oauth.d.ts} +17 -15
- package/dist/mixins/app/routes/oauth.js +2 -0
- package/dist/mixins/app/routes/oauth.js.map +7 -0
- package/dist/mixins/app/{password-reset.d.ts → routes/password-reset.d.ts} +17 -15
- package/dist/mixins/app/routes/password-reset.js +2 -0
- package/dist/mixins/app/routes/password-reset.js.map +7 -0
- package/dist/mixins/app/{two-factor.d.ts → routes/two-factor.d.ts} +17 -15
- package/dist/mixins/app/routes/two-factor.js +2 -0
- package/dist/mixins/app/routes/two-factor.js.map +7 -0
- package/dist/mixins/server/admin.d.ts +14 -12
- package/dist/mixins/server/admin.js +1 -1
- package/dist/mixins/server/admin.js.map +2 -2
- package/dist/mixins/{auth.d.ts → server/auth.d.ts} +18 -33
- package/dist/mixins/server/auth.js +2 -0
- package/dist/mixins/server/auth.js.map +7 -0
- package/dist/mixins/{entity.d.ts → server/entity.d.ts} +18 -16
- package/dist/mixins/server/entity.js +2 -0
- package/dist/mixins/server/entity.js.map +7 -0
- package/dist/mixins/{file.d.ts → server/file.d.ts} +18 -16
- package/dist/mixins/server/file.js.map +7 -0
- package/dist/mixins/server/index.d.ts +7 -6
- package/dist/mixins/server/index.js +1 -1
- package/dist/mixins/server/index.js.map +3 -3
- package/dist/mixins/{push.d.ts → server/push.d.ts} +18 -16
- package/dist/mixins/server/push.js.map +7 -0
- package/dist/mixins/{smtp.d.ts → server/smtp.d.ts} +20 -16
- package/dist/mixins/server/smtp.js +2 -0
- package/dist/mixins/server/smtp.js.map +7 -0
- package/dist/mixins/server/transaction.d.ts +62 -0
- package/dist/mixins/server/transaction.js +2 -0
- package/dist/mixins/server/transaction.js.map +7 -0
- package/dist/mixins/{utils.d.ts → server/utils.d.ts} +18 -16
- package/dist/mixins/server/utils.js +2 -0
- package/dist/mixins/server/utils.js.map +7 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +1 -1
- package/dist/react.js.map +4 -4
- package/dist/types.d.ts +17 -10
- package/package.json +2 -2
- package/dist/EntityAppServerClient.d.ts +0 -383
- package/dist/EntityAppServerClient.js +0 -2
- package/dist/EntityAppServerClient.js.map +0 -7
- package/dist/EntityServerClient.js +0 -2
- package/dist/EntityServerClient.js.map +0 -7
- package/dist/mixins/app/account.js +0 -2
- package/dist/mixins/app/account.js.map +0 -7
- package/dist/mixins/app/board.js +0 -2
- package/dist/mixins/app/board.js.map +0 -7
- package/dist/mixins/app/email-verify.js +0 -2
- package/dist/mixins/app/email-verify.js.map +0 -7
- package/dist/mixins/app/oauth.js +0 -2
- package/dist/mixins/app/oauth.js.map +0 -7
- package/dist/mixins/app/password-reset.js +0 -2
- package/dist/mixins/app/password-reset.js.map +0 -7
- package/dist/mixins/app/two-factor.js +0 -2
- package/dist/mixins/app/two-factor.js.map +0 -7
- package/dist/mixins/auth.js +0 -2
- package/dist/mixins/auth.js.map +0 -7
- package/dist/mixins/entity.js +0 -2
- package/dist/mixins/entity.js.map +0 -7
- package/dist/mixins/file.js.map +0 -7
- package/dist/mixins/push.js.map +0 -7
- package/dist/mixins/smtp.js +0 -2
- package/dist/mixins/smtp.js.map +0 -7
- package/dist/mixins/utils.js +0 -2
- package/dist/mixins/utils.js.map +0 -7
- /package/dist/mixins/{file.js → server/file.js} +0 -0
- /package/dist/mixins/{push.js → server/push.js} +0 -0
package/dist/client/base.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readEnv as
|
|
1
|
+
import{readEnv as c}from"./utils.js";import{derivePacketKey as f,parseRequestBody as u}from"./packet.js";import{entityRequest as h}from"./request.js";class y{baseUrl;token;anonymousPacketToken;apiKey;hmacSecret;encryptRequests;csrfEnabled;csrfHeaderName;csrfCookieName;_csrfRefresher=null;activeTxId=null;keepSession;refreshBuffer;onTokenRefreshed;onSessionExpired;_sessionRefreshToken=null;_refreshTimer=null;_healthTickTimer=null;_healthTickPromise=null;constructor(e={}){const r=c("VITE_ENTITY_SERVER_URL");this.baseUrl=(e.baseUrl??r??"").replace(/\/$/,""),this.token=e.token??"",this.anonymousPacketToken=e.anonymousPacketToken??"",this.apiKey=e.apiKey??"",this.hmacSecret=e.hmacSecret??"",this.encryptRequests=e.encryptRequests??!1,this.csrfEnabled=e.csrfEnabled??!1,this.csrfHeaderName=e.csrfHeaderName??"x-csrf-token",this.csrfCookieName=e.csrfCookieName??"_csrf",this.keepSession=e.keepSession??!1,this.refreshBuffer=e.refreshBuffer??60,this.onTokenRefreshed=e.onTokenRefreshed,this.onSessionExpired=e.onSessionExpired,typeof e.healthTickInterval=="number"&&e.healthTickInterval>0&&Promise.resolve().then(()=>this.startHealthTick(e.healthTickInterval))}configure(e){typeof e.baseUrl=="string"&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),typeof e.token=="string"&&(this.token=e.token),typeof e.anonymousPacketToken=="string"&&(this.anonymousPacketToken=e.anonymousPacketToken),typeof e.encryptRequests=="boolean"&&(this.encryptRequests=e.encryptRequests),typeof e.csrfEnabled=="boolean"&&(this.csrfEnabled=e.csrfEnabled),typeof e.csrfHeaderName=="string"&&(this.csrfHeaderName=e.csrfHeaderName),typeof e.csrfCookieName=="string"&&(this.csrfCookieName=e.csrfCookieName),typeof e.apiKey=="string"&&(this.apiKey=e.apiKey),typeof e.hmacSecret=="string"&&(this.hmacSecret=e.hmacSecret),typeof e.keepSession=="boolean"&&(this.keepSession=e.keepSession),typeof e.refreshBuffer=="number"&&(this.refreshBuffer=e.refreshBuffer),e.onTokenRefreshed&&(this.onTokenRefreshed=e.onTokenRefreshed),e.onSessionExpired&&(this.onSessionExpired=e.onSessionExpired),typeof e.healthTickInterval=="number"&&e.healthTickInterval>0&&Promise.resolve().then(()=>this.startHealthTick(e.healthTickInterval))}setToken(e){this.token=e}setAnonymousPacketToken(e){this.anonymousPacketToken=e}setApiKey(e){this.apiKey=e}setHmacSecret(e){this.hmacSecret=e}setEncryptRequests(e){this.encryptRequests=e}setCsrfEnabled(e){this.csrfEnabled=e}startHealthTick(e=300*1e3){this.stopHealthTick();const r=()=>{this._healthTickPromise||(this._healthTickPromise=(this._csrfRefresher?this._csrfRefresher():Promise.resolve()).catch(()=>{}).finally(()=>{this._healthTickPromise=null}))};r(),this._healthTickTimer=setInterval(r,e)}stopHealthTick(){this._healthTickTimer!==null&&(clearInterval(this._healthTickTimer),this._healthTickTimer=null),this._healthTickPromise=null}_scheduleKeepSession(e,r,s){this._clearRefreshTimer(),this._sessionRefreshToken=e;const i=Math.max((r-this.refreshBuffer)*1e3,0);this._refreshTimer=setTimeout(async()=>{if(this._sessionRefreshToken)try{const t=await s(this._sessionRefreshToken);this.onTokenRefreshed?.(t.access_token,t.expires_in),this._scheduleKeepSession(this._sessionRefreshToken,t.expires_in,s)}catch(t){this._clearRefreshTimer(),this.onSessionExpired?.(t instanceof Error?t:new Error(String(t)))}},i)}_clearRefreshTimer(){this._refreshTimer!==null&&(clearTimeout(this._refreshTimer),this._refreshTimer=null)}stopKeepSession(){this._clearRefreshTimer(),this._sessionRefreshToken=null}_applyCsrfHealth(){if(!(typeof document>"u")){for(const e of document.cookie.split(";")){const r=e.indexOf("=");if(!(r<0)&&e.substring(0,r).trim()===this.csrfCookieName){this.csrfEnabled=!!e.substring(r+1).trim();return}}this.csrfEnabled=!1}}readRequestBody(e,r="application/json",s=!1){const i=f(this.hmacSecret,this.token||this.anonymousPacketToken);return u(e,r,s,i)}get _reqOpts(){return{baseUrl:this.baseUrl,token:this.token,anonymousPacketToken:this.anonymousPacketToken,apiKey:this.apiKey,hmacSecret:this.hmacSecret,encryptRequests:this.encryptRequests,csrfEnabled:this.csrfEnabled,csrfHeaderName:this.csrfHeaderName,csrfCookieName:this.csrfCookieName,refreshCsrfCookie:this.csrfEnabled?this._csrfRefresher:null}}get http(){const e=this;return{get(r,s=!0,i){return h(e._reqOpts,"GET",r,void 0,s,i,!1)},post(r,s,i=!0,t){return h(e._reqOpts,"POST",r,s,i,t,!1)},put(r,s,i=!0,t){return h(e._reqOpts,"PUT",r,s,i,t,!1)},patch(r,s,i=!0,t){return h(e._reqOpts,"PATCH",r,s,i,t,!1)},delete(r,s,i=!0,t){return h(e._reqOpts,"DELETE",r,s,i,t,!1)}}}requestBinary(e,r,s,i=!0){return this._requestBinary(e,r,s,i)}requestForm(e,r,s,i=!0){return this._requestForm(e,r,s,i)}requestFormBinary(e,r,s,i=!0){return this._requestFormBinary(e,r,s,i)}_request(e,r,s,i=!0,t){return h(this._reqOpts,e,r,s,i,t,!0)}async _requestBinary(e,r,s,i=!0){const t={"Content-Type":"application/json"};i&&this.token&&(t.Authorization=`Bearer ${this.token}`),this.apiKey&&(t["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+r,{method:e,headers:t,...s!=null?{body:JSON.stringify(s)}:{},credentials:"include"});if(!n.ok){const o=await n.text(),a=new Error(`HTTP ${n.status}: ${o}`);throw a.status=n.status,a}return n.arrayBuffer()}async _requestForm(e,r,s,i=!0){const t={};i&&this.token&&(t.Authorization=`Bearer ${this.token}`),this.apiKey&&(t["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+r,{method:e,headers:t,body:s,credentials:"include"}),o=await n.json();if(!o.ok){const a=new Error(o.message??`EntityServer error (HTTP ${n.status})`);throw a.status=n.status,a}return o}async _requestFormBinary(e,r,s,i=!0){const t={};i&&this.token&&(t.Authorization=`Bearer ${this.token}`),this.apiKey&&(t["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+r,{method:e,headers:t,body:s,credentials:"include"});if(!n.ok){const o=await n.text(),a=new Error(`HTTP ${n.status}: ${o}`);throw a.status=n.status,a}return n.arrayBuffer()}}export{y as EntityServerClientBase};
|
|
2
2
|
//# sourceMappingURL=base.js.map
|
package/dist/client/base.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/client/base.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n EntityServerClientHealthCsrf,\n EntityServerClientOptions,\n} from \"../types.js\";\nimport { readEnv } from \"./utils.js\";\nimport { derivePacketKey, parseRequestBody } from \"./packet.js\";\nimport { entityRequest, type RequestOptions } from \"./request.js\";\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 anonymousPacketToken: string;\n apiKey: string;\n hmacSecret: string;\n encryptRequests: boolean;\n csrfEnabled: boolean;\n csrfToken: string;\n csrfHeaderName: string;\n csrfRefreshPath: string;\n csrfRefreshBuffer: number;\n activeTxId: string | null = null;\n\n // \uC138\uC158 \uC720\uC9C0 \uAD00\uB828\n keepSession: boolean;\n refreshBuffer: number;\n onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;\n onSessionExpired?: (error: Error) => void;\n _sessionRefreshToken: string | null = null;\n _refreshTimer: ReturnType<typeof setTimeout> | null = null;\n _csrfRefreshTimer: ReturnType<typeof setTimeout> | null = null;\n _csrfRefreshPromise: Promise<string> | 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 \uC0C1\uB300 \uACBD\uB85C(`\"\"`)\n */\n constructor(options: EntityServerClientOptions = {}) {\n const envBaseUrl = readEnv(\"VITE_ENTITY_SERVER_URL\");\n\n this.baseUrl = (options.baseUrl ?? envBaseUrl ?? \"\").replace(/\\/$/, \"\");\n this.token = options.token ?? \"\";\n this.anonymousPacketToken = options.anonymousPacketToken ?? \"\";\n this.apiKey = options.apiKey ?? \"\";\n this.hmacSecret = options.hmacSecret ?? \"\";\n this.encryptRequests = options.encryptRequests ?? false;\n this.csrfEnabled = options.csrfEnabled ?? false;\n this.csrfToken = options.csrfToken ?? \"\";\n this.csrfHeaderName = options.csrfHeaderName ?? \"x-csrf-token\";\n this.csrfRefreshPath = options.csrfRefreshPath ?? \"/v1/csrf-token\";\n this.csrfRefreshBuffer = options.csrfRefreshBuffer ?? 60;\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 (typeof options.baseUrl === \"string\") {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n }\n if (typeof options.token === \"string\") this.token = options.token;\n if (typeof options.anonymousPacketToken === \"string\") {\n this.anonymousPacketToken = options.anonymousPacketToken;\n }\n if (typeof options.encryptRequests === \"boolean\")\n this.encryptRequests = options.encryptRequests;\n if (typeof options.csrfEnabled === \"boolean\") {\n this.csrfEnabled = options.csrfEnabled;\n if (!options.csrfEnabled) {\n this.csrfToken = \"\";\n this.stopCsrfRefresh();\n }\n }\n if (typeof options.csrfToken === \"string\")\n this.csrfToken = options.csrfToken;\n if (typeof options.csrfHeaderName === \"string\") {\n this.csrfHeaderName = options.csrfHeaderName;\n }\n if (typeof options.csrfRefreshPath === \"string\") {\n this.csrfRefreshPath = options.csrfRefreshPath;\n }\n if (typeof options.csrfRefreshBuffer === \"number\") {\n this.csrfRefreshBuffer = options.csrfRefreshBuffer;\n }\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 /** \uC775\uBA85 \uD328\uD0B7 \uC554\uD638\uD654\uC6A9 \uD1A0\uD070\uC744 \uC124\uC815\uD569\uB2C8\uB2E4. */\n setAnonymousPacketToken(token: string): void {\n this.anonymousPacketToken = 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 setCsrfToken(token: string): void {\n this.csrfToken = token;\n }\n\n setCsrfEnabled(enabled: boolean): void {\n this.csrfEnabled = enabled;\n if (!enabled) {\n this.csrfToken = \"\";\n this.stopCsrfRefresh();\n }\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 _clearCsrfRefreshTimer(): void {\n if (this._csrfRefreshTimer !== null) {\n clearTimeout(this._csrfRefreshTimer);\n this._csrfRefreshTimer = null;\n }\n }\n\n stopCsrfRefresh(): void {\n this._clearCsrfRefreshTimer();\n this._csrfRefreshPromise = null;\n }\n\n _scheduleCsrfRefresh(expiresIn: number): void {\n this._clearCsrfRefreshTimer();\n if (!this.csrfEnabled || !this.csrfRefreshPath) {\n return;\n }\n\n const delayMs = Math.max(\n (expiresIn - this.csrfRefreshBuffer) * 1000,\n 0,\n );\n this._csrfRefreshTimer = setTimeout(() => {\n void this.refreshCsrfToken().catch(() => {\n this._clearCsrfRefreshTimer();\n });\n }, delayMs);\n }\n\n async refreshCsrfToken(): Promise<string> {\n if (!this.csrfEnabled || !this.csrfRefreshPath) {\n return \"\";\n }\n\n if (!this._csrfRefreshPromise) {\n this._csrfRefreshPromise = (async () => {\n const res = await fetch(\n `${this.baseUrl}${this.csrfRefreshPath}`,\n {\n method: \"GET\",\n credentials: \"include\",\n },\n );\n\n if (!res.ok) {\n const message = await res.text().catch(() => \"\");\n const err = new Error(message || `HTTP ${res.status}`);\n (err as { status?: number }).status = res.status;\n throw err;\n }\n\n const payload = (await res.json().catch(() => null)) as\n | { data?: EntityServerClientHealthCsrf | null }\n | EntityServerClientHealthCsrf\n | null;\n const csrf = (\n payload && typeof payload === \"object\" && \"data\" in payload\n ? (payload.data ?? null)\n : payload\n ) as EntityServerClientHealthCsrf | null;\n\n if (!csrf?.enabled || typeof csrf.token !== \"string\") {\n throw new Error(\"CSRF token refresh failed\");\n }\n\n this._applyCsrfHealth(csrf);\n return this.csrfToken;\n })().finally(() => {\n this._csrfRefreshPromise = null;\n });\n }\n\n return this._csrfRefreshPromise;\n }\n\n _applyCsrfHealth(csrf?: EntityServerClientHealthCsrf | null): void {\n if (!csrf?.enabled) {\n this.setCsrfEnabled(false);\n return;\n }\n\n this.csrfEnabled = true;\n if (typeof csrf.token === \"string\") {\n this.csrfToken = csrf.token;\n }\n if (typeof csrf.headerName === \"string\") {\n this.csrfHeaderName = csrf.headerName;\n }\n if (typeof csrf.refreshPath === \"string\") {\n this.csrfRefreshPath = csrf.refreshPath;\n }\n if (typeof csrf.expiresIn === \"number\" && csrf.expiresIn > 0) {\n this._scheduleCsrfRefresh(csrf.expiresIn);\n }\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(\n this.hmacSecret,\n this.token || this.anonymousPacketToken,\n );\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 anonymousPacketToken: this.anonymousPacketToken,\n apiKey: this.apiKey,\n hmacSecret: this.hmacSecret,\n encryptRequests: this.encryptRequests,\n csrfEnabled: this.csrfEnabled,\n csrfToken: this.csrfToken,\n csrfHeaderName: this.csrfHeaderName,\n refreshCsrfToken: this.csrfEnabled\n ? () => this.refreshCsrfToken()\n : null,\n };\n }\n\n /**\n * \uC784\uC758 \uACBD\uB85C\uC5D0 JSON \uC694\uCCAD\uC744 \uBCF4\uB0C5\uB2C8\uB2E4. \uC751\uB2F5\uC774 JSON\uC774\uBA74 \uD30C\uC2F1, octet-stream\uC774\uBA74 \uC790\uB3D9 \uBCF5\uD638\uD654\uD569\uB2C8\uB2E4.\n * `ok` \uD544\uB4DC\uB97C \uAC15\uC81C\uD558\uC9C0 \uC54A\uC544 go\uC11C\uBC84/\uC571\uC11C\uBC84 \uC2E0\uADDC \uB77C\uC6B0\uD2B8 \uB4F1 \uC790\uC720 \uC751\uB2F5 \uD3EC\uB9F7\uC5D0 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n * `encryptRequests: true`\uC774\uBA74 \uC694\uCCAD \uBC14\uB514\uB3C4 \uC790\uB3D9 \uC554\uD638\uD654\uB429\uB2C8\uB2E4.\n */\n requestJson<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 false,\n );\n }\n\n /**\n * \uC784\uC758 \uACBD\uB85C\uC5D0 \uC694\uCCAD\uC744 \uBCF4\uB0B4\uACE0 \uBC14\uC774\uB108\uB9AC(ArrayBuffer)\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n * \uC774\uBBF8\uC9C0, PDF, \uC555\uCD95 \uD30C\uC77C \uB4F1 \uBC14\uC774\uB108\uB9AC \uC751\uB2F5\uC774 \uC624\uB294 \uC5D4\uB4DC\uD3EC\uC778\uD2B8\uC5D0 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n */\n requestBinary(\n method: string,\n path: string,\n body?: unknown,\n withAuth = true,\n ): Promise<ArrayBuffer> {\n return this._requestBinary(method, path, body, withAuth);\n }\n\n /**\n * multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0C5\uB2C8\uB2E4. \uD30C\uC77C \uC5C5\uB85C\uB4DC \uB4F1\uC5D0 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n * \uC751\uB2F5\uC740 JSON\uC73C\uB85C \uD30C\uC2F1\uD558\uC5EC \uBC18\uD658\uD569\uB2C8\uB2E4.\n */\n requestForm<T>(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<T> {\n return this._requestForm<T>(method, path, form, withAuth);\n }\n\n /**\n * multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0B4\uACE0 \uBC14\uC774\uB108\uB9AC(ArrayBuffer)\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n */\n requestFormBinary(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<ArrayBuffer> {\n return this._requestFormBinary(method, path, form, withAuth);\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 true,\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 credentials: \"include\",\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 credentials: \"include\",\n });\n\n const data = (await res.json()) as { ok?: boolean; message?: string };\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 /** multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0B4\uACE0 \uBC14\uC774\uB108\uB9AC(ArrayBuffer)\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4. */\n async _requestFormBinary(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<ArrayBuffer> {\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 credentials: \"include\",\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"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["readEnv", "derivePacketKey", "parseRequestBody", "entityRequest", "EntityServerClientBase", "options", "envBaseUrl", "token", "apiKey", "secret", "value", "enabled", "
|
|
4
|
+
"sourcesContent": ["import type { EntityServerClientOptions } from \"../types.js\";\nimport { readEnv } from \"./utils.js\";\nimport { derivePacketKey, parseRequestBody } from \"./packet.js\";\nimport { entityRequest, type RequestOptions } from \"./request.js\";\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 anonymousPacketToken: string;\n apiKey: string;\n hmacSecret: string;\n encryptRequests: boolean;\n csrfEnabled: boolean;\n csrfHeaderName: string;\n csrfCookieName: string;\n /** @internal health \uC7AC\uD638\uCD9C\uB85C CSRF \uCFE0\uD0A4 \uAC31\uC2E0 (AuthMixin\uC5D0\uC11C \uC124\uC815) */\n _csrfRefresher: (() => Promise<void>) | null = null;\n activeTxId: string | null = null;\n\n // \uC138\uC158 \uC720\uC9C0 \uAD00\uB828\n keepSession: boolean;\n refreshBuffer: number;\n onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;\n onSessionExpired?: (error: Error) => void;\n _sessionRefreshToken: string | null = null;\n _refreshTimer: ReturnType<typeof setTimeout> | null = null;\n _healthTickTimer: ReturnType<typeof setInterval> | null = null;\n _healthTickPromise: Promise<unknown> | null = null;\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 \uC0C1\uB300 \uACBD\uB85C(`\"\"`)\n */\n constructor(options: EntityServerClientOptions = {}) {\n const envBaseUrl = readEnv(\"VITE_ENTITY_SERVER_URL\");\n\n this.baseUrl = (options.baseUrl ?? envBaseUrl ?? \"\").replace(/\\/$/, \"\");\n this.token = options.token ?? \"\";\n this.anonymousPacketToken = options.anonymousPacketToken ?? \"\";\n this.apiKey = options.apiKey ?? \"\";\n this.hmacSecret = options.hmacSecret ?? \"\";\n this.encryptRequests = options.encryptRequests ?? false;\n this.csrfEnabled = options.csrfEnabled ?? false;\n this.csrfHeaderName = options.csrfHeaderName ?? \"x-csrf-token\";\n this.csrfCookieName = options.csrfCookieName ?? \"_csrf\";\n this.keepSession = options.keepSession ?? false;\n this.refreshBuffer = options.refreshBuffer ?? 60;\n this.onTokenRefreshed = options.onTokenRefreshed;\n this.onSessionExpired = options.onSessionExpired;\n if (typeof options.healthTickInterval === \"number\" && options.healthTickInterval > 0) {\n // _csrfRefresher\uB294 AuthMixin\uC5D0\uC11C \uC124\uC815\uB418\uBBC0\uB85C \uB2E4\uC74C tick\uC5D0 \uC2DC\uC791\n Promise.resolve().then(() => this.startHealthTick(options.healthTickInterval));\n }\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 (typeof options.baseUrl === \"string\") {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n }\n if (typeof options.token === \"string\") this.token = options.token;\n if (typeof options.anonymousPacketToken === \"string\") {\n this.anonymousPacketToken = options.anonymousPacketToken;\n }\n if (typeof options.encryptRequests === \"boolean\")\n this.encryptRequests = options.encryptRequests;\n if (typeof options.csrfEnabled === \"boolean\") {\n this.csrfEnabled = options.csrfEnabled;\n }\n if (typeof options.csrfHeaderName === \"string\") {\n this.csrfHeaderName = options.csrfHeaderName;\n }\n if (typeof options.csrfCookieName === \"string\") {\n this.csrfCookieName = options.csrfCookieName;\n }\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 if (typeof options.healthTickInterval === \"number\" && options.healthTickInterval > 0) {\n Promise.resolve().then(() => this.startHealthTick(options.healthTickInterval));\n }\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 /** \uC775\uBA85 \uD328\uD0B7 \uC554\uD638\uD654\uC6A9 \uD1A0\uD070\uC744 \uC124\uC815\uD569\uB2C8\uB2E4. */\n setAnonymousPacketToken(token: string): void {\n this.anonymousPacketToken = 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 setCsrfEnabled(enabled: boolean): void {\n this.csrfEnabled = enabled;\n }\n\n /**\n * \uC8FC\uAE30\uC801\uC73C\uB85C health \uCCB4\uD06C\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.\n * CSRF \uCFE0\uD0A4 \uAC31\uC2E0\uACFC \uC11C\uBC84 \uC0C1\uD0DC \uD655\uC778\uC744 \uC790\uB3D9\uD654\uD569\uB2C8\uB2E4.\n *\n * @param intervalMs \uD638\uCD9C \uC8FC\uAE30(ms). \uAE30\uBCF8\uAC12: 5\uBD84\n */\n startHealthTick(intervalMs: number = 5 * 60 * 1000): void {\n this.stopHealthTick();\n const tick = (): void => {\n if (this._healthTickPromise) return;\n this._healthTickPromise = (this._csrfRefresher ? this._csrfRefresher() : Promise.resolve())\n .catch(() => {/* \uB124\uD2B8\uC6CC\uD06C \uC624\uB958 \uBB34\uC2DC */})\n .finally(() => { this._healthTickPromise = null; });\n };\n tick(); // \uC989\uC2DC 1\uD68C \uC2E4\uD589\n this._healthTickTimer = setInterval(tick, intervalMs);\n }\n\n /** health tick \uD0C0\uC774\uBA38\uB97C \uC911\uC9C0\uD569\uB2C8\uB2E4. */\n stopHealthTick(): void {\n if (this._healthTickTimer !== null) {\n clearInterval(this._healthTickTimer);\n this._healthTickTimer = null;\n }\n this._healthTickPromise = null;\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 _applyCsrfHealth(): void {\n if (typeof document === \"undefined\") return;\n for (const chunk of document.cookie.split(\";\")) {\n const idx = chunk.indexOf(\"=\");\n if (idx < 0) continue;\n if (chunk.substring(0, idx).trim() === this.csrfCookieName) {\n this.csrfEnabled = !!chunk.substring(idx + 1).trim();\n return;\n }\n }\n this.csrfEnabled = false;\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(\n this.hmacSecret,\n this.token || this.anonymousPacketToken,\n );\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 anonymousPacketToken: this.anonymousPacketToken,\n apiKey: this.apiKey,\n hmacSecret: this.hmacSecret,\n encryptRequests: this.encryptRequests,\n csrfEnabled: this.csrfEnabled,\n csrfHeaderName: this.csrfHeaderName,\n csrfCookieName: this.csrfCookieName,\n refreshCsrfCookie: this.csrfEnabled ? this._csrfRefresher : null,\n };\n }\n\n /**\n * \uCEE4\uC2A4\uD140 \uB77C\uC6B0\uD2B8 \uC9C1\uC811 \uD638\uCD9C\uC6A9 HTTP \uB124\uC784\uC2A4\uD398\uC774\uC2A4.\n * \uC778\uC99D\u00B7\uC554\uD638\uD654\u00B7HMAC \uB4F1 SDK \uC635\uC158\uC774 \uADF8\uB300\uB85C \uC801\uC6A9\uB429\uB2C8\uB2E4.\n *\n * @example\n * const res = await client.http.get<{ version: string }>(\"/api/v1/status\", false);\n * const res = await client.http.post<MyResponse>(\"/api/v1/custom\", { key: \"value\" });\n */\n get http() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return {\n get<T>(\n path: string,\n withAuth = true,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n return entityRequest<T>(\n self._reqOpts,\n \"GET\",\n path,\n undefined,\n withAuth,\n extraHeaders,\n false,\n );\n },\n post<T>(\n path: string,\n body?: unknown,\n withAuth = true,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n return entityRequest<T>(\n self._reqOpts,\n \"POST\",\n path,\n body,\n withAuth,\n extraHeaders,\n false,\n );\n },\n put<T>(\n path: string,\n body?: unknown,\n withAuth = true,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n return entityRequest<T>(\n self._reqOpts,\n \"PUT\",\n path,\n body,\n withAuth,\n extraHeaders,\n false,\n );\n },\n patch<T>(\n path: string,\n body?: unknown,\n withAuth = true,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n return entityRequest<T>(\n self._reqOpts,\n \"PATCH\",\n path,\n body,\n withAuth,\n extraHeaders,\n false,\n );\n },\n delete<T>(\n path: string,\n body?: unknown,\n withAuth = true,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n return entityRequest<T>(\n self._reqOpts,\n \"DELETE\",\n path,\n body,\n withAuth,\n extraHeaders,\n false,\n );\n },\n };\n }\n\n /**\n * \uC784\uC758 \uACBD\uB85C\uC5D0 \uC694\uCCAD\uC744 \uBCF4\uB0B4\uACE0 \uBC14\uC774\uB108\uB9AC(ArrayBuffer)\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n * \uC774\uBBF8\uC9C0, PDF, \uC555\uCD95 \uD30C\uC77C \uB4F1 \uBC14\uC774\uB108\uB9AC \uC751\uB2F5\uC774 \uC624\uB294 \uC5D4\uB4DC\uD3EC\uC778\uD2B8\uC5D0 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n */\n requestBinary(\n method: string,\n path: string,\n body?: unknown,\n withAuth = true,\n ): Promise<ArrayBuffer> {\n return this._requestBinary(method, path, body, withAuth);\n }\n\n /**\n * multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0C5\uB2C8\uB2E4. \uD30C\uC77C \uC5C5\uB85C\uB4DC \uB4F1\uC5D0 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n * \uC751\uB2F5\uC740 JSON\uC73C\uB85C \uD30C\uC2F1\uD558\uC5EC \uBC18\uD658\uD569\uB2C8\uB2E4.\n */\n requestForm<T>(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<T> {\n return this._requestForm<T>(method, path, form, withAuth);\n }\n\n /**\n * multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0B4\uACE0 \uBC14\uC774\uB108\uB9AC(ArrayBuffer)\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n */\n requestFormBinary(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<ArrayBuffer> {\n return this._requestFormBinary(method, path, form, withAuth);\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 true,\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 credentials: \"include\",\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 credentials: \"include\",\n });\n\n const data = (await res.json()) as { ok?: boolean; message?: string };\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 /** multipart/form-data \uC694\uCCAD\uC744 \uBCF4\uB0B4\uACE0 \uBC14\uC774\uB108\uB9AC(ArrayBuffer)\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4. */\n async _requestFormBinary(\n method: string,\n path: string,\n form: FormData,\n withAuth = true,\n ): Promise<ArrayBuffer> {\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 credentials: \"include\",\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["readEnv", "derivePacketKey", "parseRequestBody", "entityRequest", "EntityServerClientBase", "options", "envBaseUrl", "token", "apiKey", "secret", "value", "enabled", "intervalMs", "tick", "refreshToken", "expiresIn", "refreshFn", "delayMs", "result", "err", "chunk", "idx", "body", "contentType", "requireEncrypted", "key", "self", "path", "withAuth", "extraHeaders", "method", "form", "headers", "res", "text", "data"]
|
|
7
7
|
}
|
package/dist/client/request.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ export interface RequestOptions {
|
|
|
6
6
|
hmacSecret: string;
|
|
7
7
|
encryptRequests: boolean;
|
|
8
8
|
csrfEnabled: boolean;
|
|
9
|
-
csrfToken: string;
|
|
10
9
|
csrfHeaderName: string;
|
|
11
|
-
|
|
10
|
+
csrfCookieName: string;
|
|
11
|
+
refreshCsrfCookie: (() => Promise<void>) | null;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Entity Server에 HTTP 요청을 보냅니다.
|
package/dist/client/request.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{derivePacketKey as
|
|
1
|
+
import{derivePacketKey as C,encryptPacket as v,decryptPacket as B}from"./packet.js";import{buildHmacHeaders as I}from"./hmac.js";function K(e){return e.hmacSecret||e.token||e.anonymousPacketToken}function $(e){return e!=="GET"&&e!=="HEAD"&&e!=="OPTIONS"}function m(e){if(typeof document>"u")return"";for(const n of document.cookie.split(";")){const a=n.indexOf("=");if(!(a<0)&&n.substring(0,a).trim()===e)return decodeURIComponent(n.substring(a+1).trim())}return""}function D(e,n){return e===403&&/csrf/i.test(n)?!0:/csrf/i.test(n)&&/expired|token validation failed/i.test(n)}async function R(e){if((e.headers.get("Content-Type")??"").includes("application/json")){const o=await e.json().catch(()=>null);if(o?.error)return o.error;if(o?.message)return o.message}return await e.text().catch(()=>"")||`HTTP ${e.status}`}async function M(e,n,a,o,T=!0,h={},x=!0){const{baseUrl:H,token:c,apiKey:w,hmacSecret:f,encryptRequests:q,anonymousPacketToken:l,csrfEnabled:O,csrfHeaderName:S,csrfCookieName:p,refreshCsrfCookie:d}=e,g=T&&!!(w&&f),N=K(e),y=O&&$(n)&&!g;let u=y?m(p):"",b="application/json";const U=!c&&!g&&!!l;let i=null;if(o!=null)if(q&&!!N&&n!=="GET"&&n!=="HEAD"){const s=C(f,c||l);i=v(new TextEncoder().encode(JSON.stringify(o)),s),b="application/octet-stream"}else i=JSON.stringify(o);const j=t=>{const s={"Content-Type":b,...h};if(!g&&T&&c&&(s.Authorization=`Bearer ${c}`),U&&(s["X-Packet-Token"]=l),y&&t&&(s[S]=t),g){const A=i instanceof Uint8Array?i:typeof i=="string"?new TextEncoder().encode(i):new Uint8Array(0);Object.assign(s,I(n,a,A,w,f))}return s};y&&!u&&d&&(await d(),u=m(p));const E=t=>fetch(H+a,{method:n,headers:j(t),...i!=null?{body:i}:{},credentials:"include"});let r=await E(u);if(!r.ok){const t=await R(r.clone());if(y&&d&&D(r.status,t))await d(),u=m(p),r=await E(u);else{const s=new Error(t);throw s.status=r.status,s}}if(!r.ok){const t=new Error(await R(r));throw t.status=r.status,t}const P=r.headers.get("Content-Type")??"";if(P.includes("application/octet-stream")){const t=C(f,c||l);return B(await r.arrayBuffer(),t)}if(!P.includes("application/json"))return await r.text();const k=await r.json();if(x&&!k.ok){const t=new Error(k.message??`EntityServer error (HTTP ${r.status})`);throw t.status=r.status,t}return k}export{M as entityRequest};
|
|
2
2
|
//# sourceMappingURL=request.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/client/request.ts"],
|
|
4
|
-
"sourcesContent": ["import { derivePacketKey, encryptPacket, decryptPacket } from \"./packet.js\";\nimport { buildHmacHeaders } from \"./hmac.js\";\n\nexport interface RequestOptions {\n baseUrl: string;\n token: string;\n anonymousPacketToken: string;\n apiKey: string;\n hmacSecret: string;\n encryptRequests: boolean;\n csrfEnabled: boolean;\n
|
|
5
|
-
"mappings": "AAAA,OAAS,mBAAAA,EAAiB,iBAAAC,EAAe,iBAAAC,MAAqB,cAC9D,OAAS,oBAAAC,MAAwB,YAejC,SAASC,EAAoBC,EAA8B,CACvD,OAAOA,EAAK,YAAcA,EAAK,OAASA,EAAK,oBACjD,CAEA,SAASC,EAAaC,EAAyB,CAC3C,OAAOA,IAAW,OAASA,IAAW,QAAUA,IAAW,SAC/D,CAEA,SAASC,EAAYC,EAAgBC,EAA0B,CAC3D,OAAID,IAAW,KAAO,QAAQ,KAAKC,CAAO,EAC/B,GAIP,QAAQ,KAAKA,CAAO,GACpB,mCAAmC,KAAKA,CAAO,CAEvD,CAEA,eAAeC,EAAiBC,EAAgC,CAE5D,IADoBA,EAAI,QAAQ,IAAI,cAAc,GAAK,IACvC,SAAS,kBAAkB,EAAG,CAC1C,MAAMC,EAAQ,MAAMD,EAAI,KAAK,EAAE,MAAM,IAAM,IAAI,EAI/C,GAAIC,GAAM,MAAO,OAAOA,EAAK,MAC7B,GAAIA,GAAM,QAAS,OAAOA,EAAK,OACnC,CAGA,OADa,MAAMD,EAAI,KAAK,EAAE,MAAM,IAAM,EAAE,GAC7B,QAAQA,EAAI,MAAM,EACrC,CASA,eAAsBE,
|
|
6
|
-
"names": ["derivePacketKey", "encryptPacket", "decryptPacket", "buildHmacHeaders", "resolvePacketSource", "opts", "requiresCsrf", "method", "isCsrfError", "status", "message", "readErrorMessage", "res", "data", "entityRequest", "path", "body", "withAuth", "extraHeaders", "requireOkShape", "baseUrl", "token", "apiKey", "hmacSecret", "encryptRequests", "anonymousPacketToken", "csrfEnabled", "csrfHeaderName", "
|
|
4
|
+
"sourcesContent": ["import { derivePacketKey, encryptPacket, decryptPacket } from \"./packet.js\";\nimport { buildHmacHeaders } from \"./hmac.js\";\n\nexport interface RequestOptions {\n baseUrl: string;\n token: string;\n anonymousPacketToken: string;\n apiKey: string;\n hmacSecret: string;\n encryptRequests: boolean;\n csrfEnabled: boolean;\n csrfHeaderName: string;\n csrfCookieName: string;\n refreshCsrfCookie: (() => Promise<void>) | null;\n}\n\nfunction resolvePacketSource(opts: RequestOptions): string {\n return opts.hmacSecret || opts.token || opts.anonymousPacketToken;\n}\n\nfunction requiresCsrf(method: string): boolean {\n return method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\";\n}\n\nfunction readCsrfCookie(name: string): string {\n if (typeof document === \"undefined\") return \"\";\n for (const chunk of document.cookie.split(\";\")) {\n const idx = chunk.indexOf(\"=\");\n if (idx < 0) continue;\n if (chunk.substring(0, idx).trim() === name) {\n return decodeURIComponent(chunk.substring(idx + 1).trim());\n }\n }\n return \"\";\n}\n\nfunction isCsrfError(status: number, message: string): boolean {\n if (status === 403 && /csrf/i.test(message)) {\n return true;\n }\n\n return (\n /csrf/i.test(message) &&\n /expired|token validation failed/i.test(message)\n );\n}\n\nasync function readErrorMessage(res: Response): Promise<string> {\n const contentType = res.headers.get(\"Content-Type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const data = (await res.json().catch(() => null)) as {\n error?: string;\n message?: string;\n } | null;\n if (data?.error) return data.error;\n if (data?.message) return data.message;\n }\n\n const text = await res.text().catch(() => \"\");\n return text || `HTTP ${res.status}`;\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 requireOkShape = true,\n): Promise<T> {\n const {\n baseUrl,\n token,\n apiKey,\n hmacSecret,\n encryptRequests,\n anonymousPacketToken,\n csrfEnabled,\n csrfHeaderName,\n csrfCookieName,\n refreshCsrfCookie,\n } = opts;\n const isHmacMode = withAuth && !!(apiKey && hmacSecret);\n const packetSource = resolvePacketSource(opts);\n const shouldUseCsrf = csrfEnabled && requiresCsrf(method) && !isHmacMode;\n let csrfToken = shouldUseCsrf ? readCsrfCookie(csrfCookieName) : \"\";\n let requestContentType = \"application/json\";\n const includeAnonymousPacketHeader =\n !token && !isHmacMode && !!anonymousPacketToken;\n\n let fetchBody: string | Uint8Array | null = null;\n if (body != null) {\n const shouldEncrypt =\n encryptRequests &&\n !!packetSource &&\n method !== \"GET\" &&\n method !== \"HEAD\";\n\n if (shouldEncrypt) {\n const key = derivePacketKey(\n hmacSecret,\n token || anonymousPacketToken,\n );\n fetchBody = encryptPacket(\n new TextEncoder().encode(JSON.stringify(body)),\n key,\n );\n requestContentType = \"application/octet-stream\";\n } else {\n fetchBody = JSON.stringify(body);\n }\n }\n\n const buildHeaders = (\n resolvedCsrfToken: string,\n ): Record<string, string> => {\n const headers: Record<string, string> = {\n \"Content-Type\": requestContentType,\n ...extraHeaders,\n };\n if (!isHmacMode && withAuth && token) {\n headers.Authorization = `Bearer ${token}`;\n }\n if (includeAnonymousPacketHeader) {\n headers[\"X-Packet-Token\"] = anonymousPacketToken;\n }\n if (shouldUseCsrf && resolvedCsrfToken) {\n headers[csrfHeaderName] = resolvedCsrfToken;\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 return headers;\n };\n\n if (shouldUseCsrf && !csrfToken && refreshCsrfCookie) {\n await refreshCsrfCookie();\n csrfToken = readCsrfCookie(csrfCookieName);\n }\n\n const executeRequest = (resolvedCsrfToken: string): Promise<Response> =>\n fetch(baseUrl + path, {\n method,\n headers: buildHeaders(resolvedCsrfToken),\n ...(fetchBody != null\n ? { body: fetchBody as RequestInit[\"body\"] }\n : {}),\n credentials: \"include\",\n });\n\n let res = await executeRequest(csrfToken);\n\n if (!res.ok) {\n const message = await readErrorMessage(res.clone());\n if (\n shouldUseCsrf &&\n refreshCsrfCookie &&\n isCsrfError(res.status, message)\n ) {\n await refreshCsrfCookie();\n csrfToken = readCsrfCookie(csrfCookieName);\n res = await executeRequest(csrfToken);\n } else {\n const err = new Error(message);\n (err as { status?: number }).status = res.status;\n throw err;\n }\n }\n\n if (!res.ok) {\n const err = new Error(await readErrorMessage(res));\n (err as { status?: number }).status = res.status;\n throw err;\n }\n\n const contentType = res.headers.get(\"Content-Type\") ?? \"\";\n if (contentType.includes(\"application/octet-stream\")) {\n const key = derivePacketKey(hmacSecret, token || anonymousPacketToken);\n return decryptPacket<T>(await res.arrayBuffer(), key);\n }\n\n if (!contentType.includes(\"application/json\")) {\n return (await res.text()) as T;\n }\n\n const data = (await res.json()) as { ok?: boolean; message?: string };\n if (requireOkShape && !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\n return data as T;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["derivePacketKey", "encryptPacket", "decryptPacket", "buildHmacHeaders", "resolvePacketSource", "opts", "requiresCsrf", "method", "readCsrfCookie", "name", "chunk", "idx", "isCsrfError", "status", "message", "readErrorMessage", "res", "data", "entityRequest", "path", "body", "withAuth", "extraHeaders", "requireOkShape", "baseUrl", "token", "apiKey", "hmacSecret", "encryptRequests", "anonymousPacketToken", "csrfEnabled", "csrfHeaderName", "csrfCookieName", "refreshCsrfCookie", "isHmacMode", "packetSource", "shouldUseCsrf", "csrfToken", "requestContentType", "includeAnonymousPacketHeader", "fetchBody", "key", "buildHeaders", "resolvedCsrfToken", "headers", "bodyBytes", "executeRequest", "err", "contentType"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EntityAppServerApi } from "../index.js";
|
|
2
|
+
import { type UseEntityClientResult, type UseEntityServerOptions } from "./useEntityClient.js";
|
|
3
|
+
export interface UseEntityAppServerOptions extends UseEntityServerOptions {
|
|
4
|
+
}
|
|
5
|
+
export interface UseEntityAppServerResult extends UseEntityClientResult<EntityAppServerApi> {
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* React 환경에서 EntityAppServerApi 인스턴스와 mutation 상태를 반환합니다.
|
|
9
|
+
*
|
|
10
|
+
* - `singleton=true`(기본): 패키지 전역 `entityAppServer` 인스턴스를 사용합니다.
|
|
11
|
+
* - `singleton=false`: 컴포넌트 스코프의 새 인스턴스를 생성합니다.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const { submit, del, isPending, error } = useEntityAppServer();
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function useEntityAppServer(options?: UseEntityAppServerOptions): UseEntityAppServerResult;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useEntityAppServer.ts"],
|
|
4
|
+
"sourcesContent": ["import { EntityAppServerApi, entityAppServer } from \"../index.js\";\nimport {\n useEntityClient,\n type UseEntityClientResult,\n type UseEntityServerOptions,\n} from \"./useEntityClient.js\";\n\nexport interface UseEntityAppServerOptions extends UseEntityServerOptions {}\n\nexport interface UseEntityAppServerResult extends UseEntityClientResult<EntityAppServerApi> {}\n\n/**\n * React \uD658\uACBD\uC5D0\uC11C EntityAppServerApi \uC778\uC2A4\uD134\uC2A4\uC640 mutation \uC0C1\uD0DC\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n *\n * - `singleton=true`(\uAE30\uBCF8): \uD328\uD0A4\uC9C0 \uC804\uC5ED `entityAppServer` \uC778\uC2A4\uD134\uC2A4\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n * - `singleton=false`: \uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCF54\uD504\uC758 \uC0C8 \uC778\uC2A4\uD134\uC2A4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n *\n * @example\n * ```tsx\n * const { submit, del, isPending, error } = useEntityAppServer();\n * ```\n */\nexport function useEntityAppServer(\n options: UseEntityAppServerOptions = {},\n): UseEntityAppServerResult {\n return useEntityClient(options, {\n singletonInstance: entityAppServer,\n ClientClass: EntityAppServerApi,\n });\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,sBAAAA,EAAoB,mBAAAC,MAAuB,cACpD,OACI,mBAAAC,MAGG,uBAiBA,SAASC,EACZC,EAAqC,CAAC,EACd,CACxB,OAAOF,EAAgBE,EAAS,CAC5B,kBAAmBH,EACnB,YAAaD,CACjB,CAAC,CACL",
|
|
6
|
+
"names": ["EntityAppServerApi", "entityAppServer", "useEntityClient", "useEntityAppServer", "options"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type EntityQueryRequest, type EntityServerClientOptions } from "../index.js";
|
|
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
|
+
/** useEntityClient가 요구하는 최소 클라이언트 인터페이스 */
|
|
14
|
+
export interface EntityClientShape {
|
|
15
|
+
configure(options: Partial<EntityServerClientOptions>): void;
|
|
16
|
+
setToken(token: string): void;
|
|
17
|
+
refreshToken(refreshToken: string): Promise<unknown>;
|
|
18
|
+
submit(entity: string, data: Record<string, unknown>, opts?: {
|
|
19
|
+
transactionId?: string;
|
|
20
|
+
skipHooks?: boolean;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
ok: boolean;
|
|
23
|
+
seq: number;
|
|
24
|
+
}>;
|
|
25
|
+
delete(entity: string, seq: number, opts?: {
|
|
26
|
+
transactionId?: string;
|
|
27
|
+
hard?: boolean;
|
|
28
|
+
skipHooks?: boolean;
|
|
29
|
+
}): Promise<{
|
|
30
|
+
ok: boolean;
|
|
31
|
+
deleted: number;
|
|
32
|
+
}>;
|
|
33
|
+
query<T = unknown>(entity: string, req: EntityQueryRequest): Promise<{
|
|
34
|
+
ok: boolean;
|
|
35
|
+
data: {
|
|
36
|
+
items: T[];
|
|
37
|
+
count: number;
|
|
38
|
+
};
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
type ClientConstructor<TClient extends EntityClientShape> = new (options?: EntityServerClientOptions) => TClient;
|
|
42
|
+
export interface UseEntityClientResult<TClient extends EntityClientShape> {
|
|
43
|
+
client: TClient;
|
|
44
|
+
isPending: boolean;
|
|
45
|
+
error: Error | null;
|
|
46
|
+
reset: () => void;
|
|
47
|
+
submit: (entity: string, data: Record<string, unknown>, opts?: {
|
|
48
|
+
transactionId?: string;
|
|
49
|
+
skipHooks?: boolean;
|
|
50
|
+
}) => Promise<{
|
|
51
|
+
ok: boolean;
|
|
52
|
+
seq: number;
|
|
53
|
+
}>;
|
|
54
|
+
del: (entity: string, seq: number, opts?: {
|
|
55
|
+
transactionId?: string;
|
|
56
|
+
hard?: boolean;
|
|
57
|
+
skipHooks?: boolean;
|
|
58
|
+
}) => Promise<{
|
|
59
|
+
ok: boolean;
|
|
60
|
+
deleted: number;
|
|
61
|
+
}>;
|
|
62
|
+
query: <T = unknown>(entity: string, req: EntityQueryRequest) => Promise<{
|
|
63
|
+
ok: boolean;
|
|
64
|
+
data: {
|
|
65
|
+
items: T[];
|
|
66
|
+
count: number;
|
|
67
|
+
};
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
export declare function useEntityClient<TClient extends EntityClientShape>(options: UseEntityServerOptions, config: {
|
|
71
|
+
singletonInstance: TClient;
|
|
72
|
+
ClientClass: ClientConstructor<TClient>;
|
|
73
|
+
}): UseEntityClientResult<TClient>;
|
|
74
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useCallback as i,useEffect as m,useMemo as P,useRef as k,useState as p}from"react";function x(b,l){const{singleton:u=!0,tokenResolver:C,baseUrl:a,token:c,resumeSession:f}=b,[T,y]=p(!1),[g,d]=p(null),o=k(!0);m(()=>(o.current=!0,()=>{o.current=!1}),[]);const n=P(()=>{const e=u?l.singletonInstance:new l.ClientClass({baseUrl:a,token:c});u&&e.configure({baseUrl:a,token:c});const t=C?.();return typeof t=="string"&&e.setToken(t),e},[u,C,a,c,l.ClientClass,l.singletonInstance]),E=k(f);m(()=>{const e=E.current;e&&n.refreshToken(e).catch(()=>{})},[n]);const r=i(async e=>{o.current&&(y(!0),d(null));try{return await e()}catch(t){const s=t instanceof Error?t:new Error(String(t));throw o.current&&d(s),s}finally{o.current&&y(!1)}},[]),R=i((e,t,s)=>r(()=>n.submit(e,t,s)),[n,r]),q=i((e,t,s)=>r(()=>n.delete(e,t,s)),[n,r]),S=i((e,t)=>r(()=>n.query(e,t)),[n,r]),h=i(()=>{y(!1),d(null)},[]);return{client:n,isPending:T,error:g,reset:h,submit:R,del:q,query:S}}export{x as useEntityClient};
|
|
2
|
+
//# sourceMappingURL=useEntityClient.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/hooks/useEntityClient.ts"],
|
|
4
|
+
"sourcesContent": ["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n type EntityQueryRequest,\n type EntityServerClientOptions,\n} from \"../index.js\";\n\nexport interface UseEntityServerOptions extends EntityServerClientOptions {\n singleton?: boolean;\n tokenResolver?: () => string | undefined | null;\n /**\n * \uD398\uC774\uC9C0 \uC0C8\uB85C\uACE0\uCE68 \uD6C4 \uB85C\uADF8\uC778 \uC0C1\uD0DC\uB97C \uBCF5\uC6D0\uD560 \uB54C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n * \uC774 \uAC12\uC774 \uC788\uC73C\uBA74 \uB9C8\uC6B4\uD2B8 \uC2DC `client.refreshToken()`\uC744 \uD638\uCD9C\uD574 \uC0C8 access_token\uC744 \uBC1C\uAE09\uBC1B\uC2B5\uB2C8\uB2E4.\n * `keepSession: true`\uC640 \uD568\uAED8 \uC0AC\uC6A9\uD558\uBA74 \uC138\uC158 \uC720\uC9C0 \uD0C0\uC774\uBA38\uB3C4 \uC7AC\uC2DC\uC791\uB429\uB2C8\uB2E4.\n * \uAC31\uC2E0 \uC131\uACF5 \uC2DC `onTokenRefreshed` \uCF5C\uBC31\uC774 \uD638\uCD9C\uB429\uB2C8\uB2E4.\n */\n resumeSession?: string;\n}\n\n/** useEntityClient\uAC00 \uC694\uAD6C\uD558\uB294 \uCD5C\uC18C \uD074\uB77C\uC774\uC5B8\uD2B8 \uC778\uD130\uD398\uC774\uC2A4 */\nexport interface EntityClientShape {\n configure(options: Partial<EntityServerClientOptions>): void;\n setToken(token: string): void;\n refreshToken(refreshToken: string): Promise<unknown>;\n submit(\n entity: string,\n data: Record<string, unknown>,\n opts?: { transactionId?: string; skipHooks?: boolean },\n ): Promise<{ ok: boolean; seq: number }>;\n delete(\n entity: string,\n seq: number,\n opts?: { transactionId?: string; hard?: boolean; skipHooks?: boolean },\n ): Promise<{ ok: boolean; deleted: number }>;\n query<T = unknown>(\n entity: string,\n req: EntityQueryRequest,\n ): Promise<{ ok: boolean; data: { items: T[]; count: number } }>;\n}\n\ntype ClientConstructor<TClient extends EntityClientShape> = new (\n options?: EntityServerClientOptions,\n) => TClient;\n\nexport interface UseEntityClientResult<TClient extends EntityClientShape> {\n client: TClient;\n isPending: boolean;\n error: Error | null;\n reset: () => void;\n submit: (\n entity: string,\n data: Record<string, unknown>,\n opts?: { transactionId?: string; skipHooks?: boolean },\n ) => Promise<{ ok: boolean; seq: number }>;\n del: (\n entity: string,\n seq: number,\n opts?: { transactionId?: string; hard?: boolean; skipHooks?: boolean },\n ) => Promise<{ ok: boolean; deleted: number }>;\n query: <T = unknown>(\n entity: string,\n req: EntityQueryRequest,\n ) => Promise<{ ok: boolean; data: { items: T[]; count: number } }>;\n}\n\nexport function useEntityClient<TClient extends EntityClientShape>(\n options: UseEntityServerOptions,\n config: {\n singletonInstance: TClient;\n ClientClass: ClientConstructor<TClient>;\n },\n): UseEntityClientResult<TClient> {\n const {\n singleton = true,\n tokenResolver,\n baseUrl,\n token,\n resumeSession,\n } = options;\n\n const [isPending, setIsPending] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const client = useMemo(() => {\n const instance = singleton\n ? config.singletonInstance\n : new config.ClientClass({ baseUrl, token });\n\n if (singleton) {\n instance.configure({ baseUrl, token });\n }\n\n const resolvedToken = tokenResolver?.();\n if (typeof resolvedToken === \"string\") {\n instance.setToken(resolvedToken);\n }\n\n return instance;\n }, [\n singleton,\n tokenResolver,\n baseUrl,\n token,\n config.ClientClass,\n config.singletonInstance,\n ]);\n\n const resumeTokenRef = useRef(resumeSession);\n useEffect(() => {\n const storedRefreshToken = resumeTokenRef.current;\n if (!storedRefreshToken) return;\n client.refreshToken(storedRefreshToken).catch(() => {\n // refresh_token \uB9CC\uB8CC \uB4F1 \u2014 onSessionExpired \uCF5C\uBC31\uC774 \uC774\uBBF8 \uCC98\uB9AC\n });\n }, [client]);\n\n const run = useCallback(async <T>(fn: () => Promise<T>): Promise<T> => {\n if (mountedRef.current) {\n setIsPending(true);\n setError(null);\n }\n try {\n const result = await fn();\n return result;\n } catch (err) {\n const wrapped = err instanceof Error ? err : new Error(String(err));\n if (mountedRef.current) setError(wrapped);\n throw wrapped;\n } finally {\n if (mountedRef.current) setIsPending(false);\n }\n }, []);\n\n const submit = useCallback<UseEntityClientResult<TClient>[\"submit\"]>(\n (entity, data, opts) => run(() => client.submit(entity, data, opts)),\n [client, run],\n );\n\n const del = useCallback<UseEntityClientResult<TClient>[\"del\"]>(\n (entity, seq, opts) => run(() => client.delete(entity, seq, opts)),\n [client, run],\n );\n\n const query = useCallback<UseEntityClientResult<TClient>[\"query\"]>(\n (entity, req) => run(() => client.query(entity, req)),\n [client, run],\n );\n\n const reset = useCallback(() => {\n setIsPending(false);\n setError(null);\n }, []);\n\n return { client, isPending, error, reset, submit, del, query };\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,eAAAA,EAAa,aAAAC,EAAW,WAAAC,EAAS,UAAAC,EAAQ,YAAAC,MAAgB,QAgE3D,SAASC,EACZC,EACAC,EAI8B,CAC9B,KAAM,CACF,UAAAC,EAAY,GACZ,cAAAC,EACA,QAAAC,EACA,MAAAC,EACA,cAAAC,CACJ,EAAIN,EAEE,CAACO,EAAWC,CAAY,EAAIV,EAAS,EAAK,EAC1C,CAACW,EAAOC,CAAQ,EAAIZ,EAAuB,IAAI,EAE/Ca,EAAad,EAAO,EAAI,EAC9BF,EAAU,KACNgB,EAAW,QAAU,GACd,IAAM,CACTA,EAAW,QAAU,EACzB,GACD,CAAC,CAAC,EAEL,MAAMC,EAAShB,EAAQ,IAAM,CACzB,MAAMiB,EAAWX,EACXD,EAAO,kBACP,IAAIA,EAAO,YAAY,CAAE,QAAAG,EAAS,MAAAC,CAAM,CAAC,EAE3CH,GACAW,EAAS,UAAU,CAAE,QAAAT,EAAS,MAAAC,CAAM,CAAC,EAGzC,MAAMS,EAAgBX,IAAgB,EACtC,OAAI,OAAOW,GAAkB,UACzBD,EAAS,SAASC,CAAa,EAG5BD,CACX,EAAG,CACCX,EACAC,EACAC,EACAC,EACAJ,EAAO,YACPA,EAAO,iBACX,CAAC,EAEKc,EAAiBlB,EAAOS,CAAa,EAC3CX,EAAU,IAAM,CACZ,MAAMqB,EAAqBD,EAAe,QACrCC,GACLJ,EAAO,aAAaI,CAAkB,EAAE,MAAM,IAAM,CAEpD,CAAC,CACL,EAAG,CAACJ,CAAM,CAAC,EAEX,MAAMK,EAAMvB,EAAY,MAAUwB,GAAqC,CAC/DP,EAAW,UACXH,EAAa,EAAI,EACjBE,EAAS,IAAI,GAEjB,GAAI,CAEA,OADe,MAAMQ,EAAG,CAE5B,OAASC,EAAK,CACV,MAAMC,EAAUD,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,EAClE,MAAIR,EAAW,SAASD,EAASU,CAAO,EAClCA,CACV,QAAE,CACMT,EAAW,SAASH,EAAa,EAAK,CAC9C,CACJ,EAAG,CAAC,CAAC,EAECa,EAAS3B,EACX,CAAC4B,EAAQC,EAAMC,IAASP,EAAI,IAAML,EAAO,OAAOU,EAAQC,EAAMC,CAAI,CAAC,EACnE,CAACZ,EAAQK,CAAG,CAChB,EAEMQ,EAAM/B,EACR,CAAC4B,EAAQI,EAAKF,IAASP,EAAI,IAAML,EAAO,OAAOU,EAAQI,EAAKF,CAAI,CAAC,EACjE,CAACZ,EAAQK,CAAG,CAChB,EAEMU,EAAQjC,EACV,CAAC4B,EAAQM,IAAQX,EAAI,IAAML,EAAO,MAAMU,EAAQM,CAAG,CAAC,EACpD,CAAChB,EAAQK,CAAG,CAChB,EAEMY,EAAQnC,EAAY,IAAM,CAC5Bc,EAAa,EAAK,EAClBE,EAAS,IAAI,CACjB,EAAG,CAAC,CAAC,EAEL,MAAO,CAAE,OAAAE,EAAQ,UAAAL,EAAW,MAAAE,EAAO,MAAAoB,EAAO,OAAAR,EAAQ,IAAAI,EAAK,MAAAE,CAAM,CACjE",
|
|
6
|
+
"names": ["useCallback", "useEffect", "useMemo", "useRef", "useState", "useEntityClient", "options", "config", "singleton", "tokenResolver", "baseUrl", "token", "resumeSession", "isPending", "setIsPending", "error", "setError", "mountedRef", "client", "instance", "resolvedToken", "resumeTokenRef", "storedRefreshToken", "run", "fn", "err", "wrapped", "submit", "entity", "data", "opts", "del", "seq", "query", "req", "reset"]
|
|
7
|
+
}
|
|
@@ -1,85 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 페이지 새로고침 후 로그인 상태를 복원할 때 사용합니다.
|
|
7
|
-
* 이 값이 있으면 마운트 시 `client.refreshToken()`을 호출해 새 access_token을 발급받습니다.
|
|
8
|
-
* `keepSession: true`와 함께 사용하면 세션 유지 타이머도 재시작됩니다.
|
|
9
|
-
* 갱신 성공 시 `onTokenRefreshed` 콜백이 호출됩니다.
|
|
10
|
-
*/
|
|
11
|
-
resumeSession?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface UseEntityAppServerOptions extends UseEntityServerOptions {
|
|
14
|
-
}
|
|
15
|
-
type BaseClient = EntityServerClient | EntityAppServerClient;
|
|
16
|
-
interface UseEntityClientResult<TClient extends BaseClient> {
|
|
17
|
-
client: TClient;
|
|
18
|
-
isPending: boolean;
|
|
19
|
-
error: Error | null;
|
|
20
|
-
reset: () => void;
|
|
21
|
-
submit: (entity: string, data: Record<string, unknown>, opts?: {
|
|
22
|
-
transactionId?: string;
|
|
23
|
-
skipHooks?: boolean;
|
|
24
|
-
}) => Promise<{
|
|
25
|
-
ok: boolean;
|
|
26
|
-
seq: number;
|
|
27
|
-
}>;
|
|
28
|
-
del: (entity: string, seq: number, opts?: {
|
|
29
|
-
transactionId?: string;
|
|
30
|
-
hard?: boolean;
|
|
31
|
-
skipHooks?: boolean;
|
|
32
|
-
}) => Promise<{
|
|
33
|
-
ok: boolean;
|
|
34
|
-
deleted: number;
|
|
35
|
-
}>;
|
|
36
|
-
query: <T = unknown>(entity: string, req: EntityQueryRequest) => Promise<{
|
|
37
|
-
ok: boolean;
|
|
38
|
-
data: {
|
|
39
|
-
items: T[];
|
|
40
|
-
count: number;
|
|
41
|
-
};
|
|
42
|
-
}>;
|
|
43
|
-
}
|
|
44
|
-
export interface UseEntityServerResult {
|
|
45
|
-
/** EntityServerClient 인스턴스 (read 전용 메서드 직접 호출 시 사용) */
|
|
46
|
-
client: EntityServerClient;
|
|
47
|
-
/** submit 또는 delete 진행 중 여부 */
|
|
48
|
-
isPending: boolean;
|
|
49
|
-
/** 마지막 mutation 에러 (없으면 null) */
|
|
50
|
-
error: Error | null;
|
|
51
|
-
/** 에러·결과 상태 초기화 */
|
|
52
|
-
reset: () => void;
|
|
53
|
-
/** entity 데이터 생성/수정 (seq 없으면 INSERT, 있으면 UPDATE) */
|
|
54
|
-
submit: (entity: string, data: Record<string, unknown>, opts?: {
|
|
55
|
-
transactionId?: string;
|
|
56
|
-
skipHooks?: boolean;
|
|
57
|
-
}) => Promise<{
|
|
58
|
-
ok: boolean;
|
|
59
|
-
seq: number;
|
|
60
|
-
}>;
|
|
61
|
-
/** entity 데이터 삭제 */
|
|
62
|
-
del: (entity: string, seq: number, opts?: {
|
|
63
|
-
transactionId?: string;
|
|
64
|
-
hard?: boolean;
|
|
65
|
-
skipHooks?: boolean;
|
|
66
|
-
}) => Promise<{
|
|
67
|
-
ok: boolean;
|
|
68
|
-
deleted: number;
|
|
69
|
-
}>;
|
|
70
|
-
/** 커스텀 SQL 조회 */
|
|
71
|
-
query: <T = unknown>(entity: string, req: EntityQueryRequest) => Promise<{
|
|
72
|
-
ok: boolean;
|
|
73
|
-
data: {
|
|
74
|
-
items: T[];
|
|
75
|
-
count: number;
|
|
76
|
-
};
|
|
77
|
-
}>;
|
|
78
|
-
}
|
|
79
|
-
export interface UseEntityAppServerResult extends UseEntityClientResult<EntityAppServerClient> {
|
|
1
|
+
import { EntityServerApi } from "../index.js";
|
|
2
|
+
import { type UseEntityClientResult, type UseEntityServerOptions } from "./useEntityClient.js";
|
|
3
|
+
export type { UseEntityServerOptions };
|
|
4
|
+
export interface UseEntityServerResult extends UseEntityClientResult<EntityServerApi> {
|
|
80
5
|
}
|
|
81
6
|
/**
|
|
82
|
-
* React 환경에서
|
|
7
|
+
* React 환경에서 EntityServerApi 인스턴스와 mutation 상태를 반환합니다.
|
|
83
8
|
*
|
|
84
9
|
* - `singleton=true`(기본): 패키지 전역 `entityServer` 인스턴스를 사용합니다.
|
|
85
10
|
* - `singleton=false`: 컴포넌트 스코프의 새 인스턴스를 생성합니다.
|
|
@@ -94,11 +19,3 @@ export interface UseEntityAppServerResult extends UseEntityClientResult<EntityAp
|
|
|
94
19
|
* ```
|
|
95
20
|
*/
|
|
96
21
|
export declare function useEntityServer(options?: UseEntityServerOptions): UseEntityServerResult;
|
|
97
|
-
/**
|
|
98
|
-
* React 환경에서 EntityAppServerClient 인스턴스와 mutation 상태를 반환합니다.
|
|
99
|
-
*
|
|
100
|
-
* - `singleton=true`(기본): 패키지 전역 `entityAppServer` 인스턴스를 사용합니다.
|
|
101
|
-
* - `singleton=false`: 컴포넌트 스코프의 새 인스턴스를 생성합니다.
|
|
102
|
-
*/
|
|
103
|
-
export declare function useEntityAppServer(options?: UseEntityAppServerOptions): UseEntityAppServerResult;
|
|
104
|
-
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{EntityServerApi as t,entityServer as n}from"../index.js";import{useEntityClient as r}from"./useEntityClient.js";function y(e={}){return r(e,{singletonInstance:n,ClientClass:t})}export{y as useEntityServer};
|
|
2
2
|
//# sourceMappingURL=useEntityServer.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/hooks/useEntityServer.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "AAAA,OAAS,
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import { EntityServerApi, entityServer } from \"../index.js\";\nimport {\n useEntityClient,\n type UseEntityClientResult,\n type UseEntityServerOptions,\n} from \"./useEntityClient.js\";\n\nexport type { UseEntityServerOptions };\n\nexport interface UseEntityServerResult extends UseEntityClientResult<EntityServerApi> {}\n\n/**\n * React \uD658\uACBD\uC5D0\uC11C EntityServerApi \uC778\uC2A4\uD134\uC2A4\uC640 mutation \uC0C1\uD0DC\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n *\n * - `singleton=true`(\uAE30\uBCF8): \uD328\uD0A4\uC9C0 \uC804\uC5ED `entityServer` \uC778\uC2A4\uD134\uC2A4\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\n * - `singleton=false`: \uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCF54\uD504\uC758 \uC0C8 \uC778\uC2A4\uD134\uC2A4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n *\n * @example\n * ```tsx\n * const { submit, del, isPending, error, reset } = useEntityServer();\n *\n * const handleSave = async () => {\n * await submit(\"account\", { name: \"\uD64D\uAE38\uB3D9\" });\n * };\n * ```\n */\nexport function useEntityServer(\n options: UseEntityServerOptions = {},\n): UseEntityServerResult {\n return useEntityClient(options, {\n singletonInstance: entityServer,\n ClientClass: EntityServerApi,\n });\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAS,mBAAAA,EAAiB,gBAAAC,MAAoB,cAC9C,OACI,mBAAAC,MAGG,uBAqBA,SAASC,EACZC,EAAkC,CAAC,EACd,CACrB,OAAOF,EAAgBE,EAAS,CAC5B,kBAAmBH,EACnB,YAAaD,CACjB,CAAC,CACL",
|
|
6
|
+
"names": ["EntityServerApi", "entityServer", "useEntityClient", "useEntityServer", "options"]
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from "./types.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
2
|
+
export * from "./EntityServerApi.js";
|
|
3
|
+
export * from "./EntityAppServerApi.js";
|
|
4
4
|
export * from "./mixins/server/index.js";
|
|
5
5
|
export * from "./mixins/app/index.js";
|
|
6
6
|
export * from "./packet.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
export declare const entityServer:
|
|
10
|
-
export declare const entityAppServer:
|
|
7
|
+
import { EntityServerApi } from "./EntityServerApi.js";
|
|
8
|
+
import { EntityAppServerApi } from "./EntityAppServerApi.js";
|
|
9
|
+
export declare const entityServer: EntityServerApi;
|
|
10
|
+
export declare const entityAppServer: EntityAppServerApi;
|