@cartanova/qgrid-cli 1.5.5 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/dist/application/qgrid/oauth.js +1 -1
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +166 -0
- package/bundle/dist/application/qgrid/qgrid.frame.js +28 -36
- package/bundle/dist/application/qgrid/qgrid.types.js +5 -16
- package/bundle/dist/application/queries.generated.js +1 -1
- package/bundle/dist/application/sonamu.generated.js +1 -1
- package/bundle/dist/application/sonamu.generated.sso.js +1 -1
- package/bundle/dist/sonamu.config.js +6 -9
- package/bundle/src/application/qgrid/oauth.ts +1 -1
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +184 -0
- package/bundle/src/application/qgrid/qgrid.frame.ts +28 -50
- package/bundle/src/application/qgrid/qgrid.types.ts +2 -14
- package/bundle/src/application/queries.generated.ts +1 -0
- package/bundle/src/application/sonamu.generated.http +2 -1
- package/bundle/src/application/sonamu.generated.sso.ts +6 -5
- package/bundle/src/application/sonamu.generated.ts +1 -0
- package/bundle/src/sonamu.config.ts +4 -7
- package/bundle/web-dist/client/assets/index-BRZCFaFz.css +1 -0
- package/bundle/web-dist/client/assets/index-D8eEjsZj.js +78 -0
- package/bundle/web-dist/client/assets/{logs-CQDBOCud.js → logs-CKnJzuH6.js} +1 -1
- package/bundle/web-dist/client/assets/{routes-MR1DKizN.js → routes-DQKecVGa.js} +1 -1
- package/bundle/web-dist/client/assets/sd.generated-NHYHS_-0.js +47 -0
- package/bundle/web-dist/client/assets/services.generated-DDVXMid7.js +1 -0
- package/bundle/web-dist/client/assets/{show--z3WxDb0.js → show-D2z1qxJ5.js} +1 -1
- package/bundle/web-dist/client/assets/tokens-BaywaQkm.js +1 -0
- package/bundle/web-dist/client/assets/vendor-tanstack-DJRQAbrY.js +1 -0
- package/bundle/web-dist/client/index.html +4 -4
- package/bundle/web-dist/server/assets/{copy-GKsNP-2_.js → copy-BVWDOV2T.js} +1 -1
- package/bundle/web-dist/server/assets/{lazyRouteComponent-B78WDGgM.js → lazyRouteComponent-BJmwxFyJ.js} +2 -128
- package/bundle/web-dist/server/assets/{logs-BV6gEe15.js → logs-DgIbufNf.js} +4 -4
- package/bundle/web-dist/server/assets/{routes-B5FkWLUe.js → routes-x7-hqUm0.js} +3 -3
- package/bundle/web-dist/server/assets/{sd.generated-Mnbmi4YR.js → sd.generated-BZPIp4uL.js} +122 -1
- package/bundle/web-dist/server/assets/{services.generated-DjdxFvCg.js → services.generated-BA0gbdmd.js} +134 -20
- package/bundle/web-dist/server/assets/shim-DGrmZkac.js +129 -0
- package/bundle/web-dist/server/assets/{show-BqSxVXai.js → show-Bk3NayMH.js} +4 -4
- package/bundle/web-dist/server/assets/{tokens-BGaTdsEb.js → tokens-CVSwt0x0.js} +13 -24
- package/bundle/web-dist/server/entry-server.generated.js +19679 -17705
- package/package.json +2 -2
- package/bundle/dist/application/qgrid/pool.js +0 -128
- package/bundle/dist/application/qgrid/worker.js +0 -189
- package/bundle/src/application/qgrid/pool.ts +0 -165
- package/bundle/src/application/qgrid/worker.ts +0 -240
- package/bundle/web-dist/client/assets/index-DLrkHIo2.js +0 -116
- package/bundle/web-dist/client/assets/index-kQRqXaWM.css +0 -1
- package/bundle/web-dist/client/assets/sd.generated-DXtkTTGn.js +0 -47
- package/bundle/web-dist/client/assets/services.generated-C0OpNm5q.js +0 -1
- package/bundle/web-dist/client/assets/tokens-Bch6XO9K.js +0 -1
- package/bundle/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +0 -1
- /package/bundle/web-dist/server/assets/{cost-D0Ta7MJa.js → cost-DdHTzQDR.js} +0 -0
|
@@ -103,4 +103,4 @@ const TokenSubsetKey = z.enum(["A"]);
|
|
|
103
103
|
//#endregion
|
|
104
104
|
export { RequestLogBaseListParams, RequestLogBaseSchema, RequestLogOrderBy, RequestLogOrderByLabel, RequestLogSearchField, RequestLogSearchFieldLabel, RequestLogSubsetA, RequestLogSubsetKey, TokenBaseListParams, TokenBaseSchema, TokenOrderBy, TokenOrderByLabel, TokenSearchField, TokenSearchFieldLabel, TokenSubsetA, TokenSubsetKey };
|
|
105
105
|
|
|
106
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
106
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmdlbmVyYXRlZC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwbGljYXRpb24vc29uYW11LmdlbmVyYXRlZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBnZW5lcmF0ZWRcbiAqIOyngeygkSDsiJjsoJXtlZjsp4Ag66eI7IS47JqULlxuICovXG5cbi8qIG94bGludC1kaXNhYmxlICovXG5cbmltcG9ydCB7IHpBcnJheWFibGUsIFNvbmFtdVF1ZXJ5TW9kZSwgQXBwbHlTb25hbXVGaWx0ZXIgfSBmcm9tIFwic29uYW11XCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG4vLyBFbnVtczogUmVxdWVzdExvZ1xuZXhwb3J0IGNvbnN0IFJlcXVlc3RMb2dPcmRlckJ5ID0gei5lbnVtKFtcImlkLWRlc2NcIl0pLmRlc2NyaWJlKFwiUmVxdWVzdExvZ09yZGVyQnlcIik7XG5leHBvcnQgdHlwZSBSZXF1ZXN0TG9nT3JkZXJCeSA9IHouaW5mZXI8dHlwZW9mIFJlcXVlc3RMb2dPcmRlckJ5PjtcbmV4cG9ydCBjb25zdCBSZXF1ZXN0TG9nT3JkZXJCeUxhYmVsID0geyBcImlkLWRlc2NcIjogXCJJROy1nOyLoOyInFwiIH07XG5leHBvcnQgY29uc3QgUmVxdWVzdExvZ1NlYXJjaEZpZWxkID0gelxuICAuZW51bShbXCJpZFwiLCBcInRva2VuX25hbWVcIiwgXCJxdWVyeVwiXSlcbiAgLmRlc2NyaWJlKFwiUmVxdWVzdExvZ1NlYXJjaEZpZWxkXCIpO1xuZXhwb3J0IHR5cGUgUmVxdWVzdExvZ1NlYXJjaEZpZWxkID0gei5pbmZlcjx0eXBlb2YgUmVxdWVzdExvZ1NlYXJjaEZpZWxkPjtcbmV4cG9ydCBjb25zdCBSZXF1ZXN0TG9nU2VhcmNoRmllbGRMYWJlbCA9IHsgaWQ6IFwiSURcIiwgdG9rZW5fbmFtZTogXCLthqDtgbDsnbTrpoRcIiwgcXVlcnk6IFwi7L+866asXCIgfTtcblxuLy8gRW51bXM6IFRva2VuXG5leHBvcnQgY29uc3QgVG9rZW5PcmRlckJ5ID0gei5lbnVtKFtcImlkLWRlc2NcIiwgXCJvcmQtYXNjXCJdKS5kZXNjcmliZShcIlRva2VuT3JkZXJCeVwiKTtcbmV4cG9ydCB0eXBlIFRva2VuT3JkZXJCeSA9IHouaW5mZXI8dHlwZW9mIFRva2VuT3JkZXJCeT47XG5leHBvcnQgY29uc3QgVG9rZW5PcmRlckJ5TGFiZWwgPSB7IFwiaWQtZGVzY1wiOiBcIklE7LWc7Iug7IicXCIsIFwib3JkLWFzY1wiOiBcIuyInOyEnOyInFwiIH07XG5leHBvcnQgY29uc3QgVG9rZW5TZWFyY2hGaWVsZCA9IHouZW51bShbXCJpZFwiLCBcIm5hbWVcIl0pLmRlc2NyaWJlKFwiVG9rZW5TZWFyY2hGaWVsZFwiKTtcbmV4cG9ydCB0eXBlIFRva2VuU2VhcmNoRmllbGQgPSB6LmluZmVyPHR5cGVvZiBUb2tlblNlYXJjaEZpZWxkPjtcbmV4cG9ydCBjb25zdCBUb2tlblNlYXJjaEZpZWxkTGFiZWwgPSB7IGlkOiBcIklEXCIsIG5hbWU6IFwi7J2066aEXCIgfTtcblxuLy8gQmFzZVNjaGVtYTogUmVxdWVzdExvZ1xuZXhwb3J0IGNvbnN0IFJlcXVlc3RMb2dCYXNlU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogei5pbnQoKSxcbiAgY3JlYXRlZF9hdDogei5kYXRlKCksXG4gIHRva2VuX25hbWU6IHouc3RyaW5nKCkubWF4KDEwMCksXG4gIHF1ZXJ5OiB6LnN0cmluZygpLFxuICByZXNwb25zZTogei5zdHJpbmcoKSxcbiAgaW5wdXRfdG9rZW5zOiB6LmludCgpLFxuICBvdXRwdXRfdG9rZW5zOiB6LmludCgpLFxuICBjYWNoZV9yZWFkX3Rva2Vuczogei5pbnQoKSxcbiAgY2FjaGVfY3JlYXRpb25fdG9rZW5zOiB6LmludCgpLFxuICBkdXJhdGlvbl9tczogei5pbnQoKSxcbiAgY29zdF91c2Q6IHouaW50KCkubnVsbGFibGUoKSxcbn0pO1xuZXhwb3J0IHR5cGUgUmVxdWVzdExvZ0Jhc2VTY2hlbWEgPSB6LmluZmVyPHR5cGVvZiBSZXF1ZXN0TG9nQmFzZVNjaGVtYT4gJiB7XG4gIHJlYWRvbmx5IF9faGFzRGVmYXVsdF9fOiByZWFkb25seSBbXCJjcmVhdGVkX2F0XCIsIFwiY29zdF91c2RcIiwgXCJpZFwiXTtcbn07XG5cbi8vIEJhc2VTY2hlbWE6IFRva2VuXG5leHBvcnQgY29uc3QgVG9rZW5CYXNlU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogei5pbnQoKSxcbiAgY3JlYXRlZF9hdDogei5kYXRlKCksXG4gIHRva2VuOiB6LnN0cmluZygpLFxuICBuYW1lOiB6LnN0cmluZygpLFxuICByZWZyZXNoX3Rva2VuOiB6LnN0cmluZygpLm51bGxhYmxlKCksXG4gIGV4cGlyZXNfYXQ6IHouYmlnaW50KCkubnVsbGFibGUoKSxcbiAgYWNjb3VudF91dWlkOiB6LnN0cmluZygpLm51bGxhYmxlKCksXG4gIGFjdGl2ZTogei5ib29sZWFuKCksXG4gIG9yZDogei5pbnQoKSxcbn0pO1xuZXhwb3J0IHR5cGUgVG9rZW5CYXNlU2NoZW1hID0gei5pbmZlcjx0eXBlb2YgVG9rZW5CYXNlU2NoZW1hPiAmIHtcbiAgcmVhZG9ubHkgX19oYXNEZWZhdWx0X186IHJlYWRvbmx5IFtcbiAgICBcImNyZWF0ZWRfYXRcIixcbiAgICBcInJlZnJlc2hfdG9rZW5cIixcbiAgICBcImV4cGlyZXNfYXRcIixcbiAgICBcImFjY291bnRfdXVpZFwiLFxuICAgIFwiYWN0aXZlXCIsXG4gICAgXCJvcmRcIixcbiAgICBcImlkXCIsXG4gIF07XG59O1xuXG4vLyBCYXNlTGlzdFBhcmFtczogUmVxdWVzdExvZ1xuZXhwb3J0IGNvbnN0IFJlcXVlc3RMb2dCYXNlTGlzdFBhcmFtcyA9IHpcbiAgLm9iamVjdCh7XG4gICAgbnVtOiB6Lm51bWJlcigpLmludCgpLm5vbm5lZ2F0aXZlKCksXG4gICAgcGFnZTogei5udW1iZXIoKS5pbnQoKS5taW4oMSksXG4gICAgc2VhcmNoOiBSZXF1ZXN0TG9nU2VhcmNoRmllbGQsXG4gICAga2V5d29yZDogei5zdHJpbmcoKSxcbiAgICBvcmRlckJ5OiBSZXF1ZXN0TG9nT3JkZXJCeSxcbiAgICBxdWVyeU1vZGU6IFNvbmFtdVF1ZXJ5TW9kZSxcbiAgICBpZDogekFycmF5YWJsZSh6Lm51bWJlcigpLmludCgpLnBvc2l0aXZlKCkpLFxuICAgIHNvbmFtdUZpbHRlcjogei5jdXN0b208QXBwbHlTb25hbXVGaWx0ZXI8UmVxdWVzdExvZ0Jhc2VTY2hlbWEsIG5ldmVyLCBuZXZlcj4+KCksXG4gICAgdG9rZW5fbmFtZTogei5zdHJpbmcoKS5tYXgoMTAwKSxcbiAgfSlcbiAgLnBhcnRpYWwoKTtcbmV4cG9ydCB0eXBlIFJlcXVlc3RMb2dCYXNlTGlzdFBhcmFtcyA9IHouaW5mZXI8dHlwZW9mIFJlcXVlc3RMb2dCYXNlTGlzdFBhcmFtcz47XG5cbi8vIEJhc2VMaXN0UGFyYW1zOiBUb2tlblxuZXhwb3J0IGNvbnN0IFRva2VuQmFzZUxpc3RQYXJhbXMgPSB6XG4gIC5vYmplY3Qoe1xuICAgIG51bTogei5udW1iZXIoKS5pbnQoKS5ub25uZWdhdGl2ZSgpLFxuICAgIHBhZ2U6IHoubnVtYmVyKCkuaW50KCkubWluKDEpLFxuICAgIHNlYXJjaDogVG9rZW5TZWFyY2hGaWVsZCxcbiAgICBrZXl3b3JkOiB6LnN0cmluZygpLFxuICAgIG9yZGVyQnk6IFRva2VuT3JkZXJCeSxcbiAgICBxdWVyeU1vZGU6IFNvbmFtdVF1ZXJ5TW9kZSxcbiAgICBpZDogekFycmF5YWJsZSh6Lm51bWJlcigpLmludCgpLnBvc2l0aXZlKCkpLFxuICAgIHNvbmFtdUZpbHRlcjogei5jdXN0b208QXBwbHlTb25hbXVGaWx0ZXI8VG9rZW5CYXNlU2NoZW1hLCBuZXZlciwgbmV2ZXI+PigpLFxuICAgIHRva2VuOiB6LnN0cmluZygpLFxuICB9KVxuICAucGFydGlhbCgpO1xuZXhwb3J0IHR5cGUgVG9rZW5CYXNlTGlzdFBhcmFtcyA9IHouaW5mZXI8dHlwZW9mIFRva2VuQmFzZUxpc3RQYXJhbXM+O1xuXG4vLyBTdWJzZXRzOiBSZXF1ZXN0TG9nXG5leHBvcnQgY29uc3QgUmVxdWVzdExvZ1N1YnNldEEgPSB6Lm9iamVjdCh7XG4gIGlkOiB6LmludCgpLFxuICBjcmVhdGVkX2F0OiB6LmRhdGUoKSxcbiAgdG9rZW5fbmFtZTogei5zdHJpbmcoKS5tYXgoMTAwKSxcbiAgcXVlcnk6IHouc3RyaW5nKCksXG4gIHJlc3BvbnNlOiB6LnN0cmluZygpLFxuICBpbnB1dF90b2tlbnM6IHouaW50KCksXG4gIG91dHB1dF90b2tlbnM6IHouaW50KCksXG4gIGNhY2hlX3JlYWRfdG9rZW5zOiB6LmludCgpLFxuICBjYWNoZV9jcmVhdGlvbl90b2tlbnM6IHouaW50KCksXG4gIGR1cmF0aW9uX21zOiB6LmludCgpLFxuICBjb3N0X3VzZDogei5pbnQoKS5udWxsYWJsZSgpLFxufSk7XG5leHBvcnQgdHlwZSBSZXF1ZXN0TG9nU3Vic2V0QSA9IHouaW5mZXI8dHlwZW9mIFJlcXVlc3RMb2dTdWJzZXRBPjtcbmV4cG9ydCB0eXBlIFJlcXVlc3RMb2dTdWJzZXRNYXBwaW5nID0ge1xuICBBOiBSZXF1ZXN0TG9nU3Vic2V0QTtcbn07XG5leHBvcnQgY29uc3QgUmVxdWVzdExvZ1N1YnNldEtleSA9IHouZW51bShbXCJBXCJdKTtcbmV4cG9ydCB0eXBlIFJlcXVlc3RMb2dTdWJzZXRLZXkgPSB6LmluZmVyPHR5cGVvZiBSZXF1ZXN0TG9nU3Vic2V0S2V5PjtcblxuLy8gU3Vic2V0czogVG9rZW5cbmV4cG9ydCBjb25zdCBUb2tlblN1YnNldEEgPSB6Lm9iamVjdCh7XG4gIGlkOiB6LmludCgpLFxuICBjcmVhdGVkX2F0OiB6LmRhdGUoKSxcbiAgdG9rZW46IHouc3RyaW5nKCksXG4gIG5hbWU6IHouc3RyaW5nKCksXG4gIHJlZnJlc2hfdG9rZW46IHouc3RyaW5nKCkubnVsbGFibGUoKSxcbiAgZXhwaXJlc19hdDogei5iaWdpbnQoKS5udWxsYWJsZSgpLFxuICBhY2NvdW50X3V1aWQ6IHouc3RyaW5nKCkubnVsbGFibGUoKSxcbiAgYWN0aXZlOiB6LmJvb2xlYW4oKSxcbiAgb3JkOiB6LmludCgpLFxufSk7XG5leHBvcnQgdHlwZSBUb2tlblN1YnNldEEgPSB6LmluZmVyPHR5cGVvZiBUb2tlblN1YnNldEE+O1xuZXhwb3J0IHR5cGUgVG9rZW5TdWJzZXRNYXBwaW5nID0ge1xuICBBOiBUb2tlblN1YnNldEE7XG59O1xuZXhwb3J0IGNvbnN0IFRva2VuU3Vic2V0S2V5ID0gei5lbnVtKFtcIkFcIl0pO1xuZXhwb3J0IHR5cGUgVG9rZW5TdWJzZXRLZXkgPSB6LmluZmVyPHR5cGVvZiBUb2tlblN1YnNldEtleT47XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBV0EsTUFBYSxvQkFBb0IsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsU0FBUyxvQkFBb0I7QUFFbEYsTUFBYSx5QkFBeUIsRUFBRSxXQUFXLFNBQVM7QUFDNUQsTUFBYSx3QkFBd0IsRUFDbEMsS0FBSztDQUFDO0NBQU07Q0FBYztDQUFRLENBQUMsQ0FDbkMsU0FBUyx3QkFBd0I7QUFFcEMsTUFBYSw2QkFBNkI7Q0FBRSxJQUFJO0NBQU0sWUFBWTtDQUFRLE9BQU87Q0FBTTtBQUd2RixNQUFhLGVBQWUsRUFBRSxLQUFLLENBQUMsV0FBVyxVQUFVLENBQUMsQ0FBQyxTQUFTLGVBQWU7QUFFbkYsTUFBYSxvQkFBb0I7Q0FBRSxXQUFXO0NBQVMsV0FBVztDQUFPO0FBQ3pFLE1BQWEsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLE1BQU0sT0FBTyxDQUFDLENBQUMsU0FBUyxtQkFBbUI7QUFFbkYsTUFBYSx3QkFBd0I7Q0FBRSxJQUFJO0NBQU0sTUFBTTtDQUFNO0FBRzdELE1BQWEsdUJBQXVCLEVBQUUsT0FBTztDQUMzQyxJQUFJLEVBQUUsS0FBSztDQUNYLFlBQVksRUFBRSxNQUFNO0NBQ3BCLFlBQVksRUFBRSxRQUFRLENBQUMsSUFBSSxJQUFJO0NBQy9CLE9BQU8sRUFBRSxRQUFRO0NBQ2pCLFVBQVUsRUFBRSxRQUFRO0NBQ3BCLGNBQWMsRUFBRSxLQUFLO0NBQ3JCLGVBQWUsRUFBRSxLQUFLO0NB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
|
|
@@ -33,4 +33,4 @@ const tokenLoaderQueries = { A: [] };
|
|
|
33
33
|
//#endregion
|
|
34
34
|
export { requestLogLoaderQueries, requestLogSubsetQueries, tokenLoaderQueries, tokenSubsetQueries };
|
|
35
35
|
|
|
36
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
36
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmdlbmVyYXRlZC5zc28uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3NvbmFtdS5nZW5lcmF0ZWQuc3NvLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGdlbmVyYXRlZFxuICog7KeB7KCRIOyImOygle2VmOyngCDrp4jshLjsmpQuXG4gKi9cblxuaW1wb3J0IHsgdHlwZSBQdXJpV3JhcHBlciwgdHlwZSBEYXRhYmFzZVNjaGVtYUV4dGVuZCwgdHlwZSBQdXJpTG9hZGVyUXVlcmllcyB9IGZyb20gXCJzb25hbXVcIjtcblxuaW1wb3J0IHtcbiAgdHlwZSBSZXF1ZXN0TG9nU3Vic2V0S2V5LFxuICB0eXBlIFRva2VuU3Vic2V0S2V5LFxuICB0eXBlIFJlcXVlc3RMb2dCYXNlU2NoZW1hLFxuICB0eXBlIFRva2VuQmFzZVNjaGVtYSxcbn0gZnJvbSBcIi4vc29uYW11LmdlbmVyYXRlZFwiO1xuXG4vLyBTdWJzZXRRdWVyeTogUmVxdWVzdExvZ1xuZXhwb3J0IGNvbnN0IHJlcXVlc3RMb2dTdWJzZXRRdWVyaWVzID0ge1xuICBBOiAocWJXcmFwcGVyOiBQdXJpV3JhcHBlcjxEYXRhYmFzZVNjaGVtYUV4dGVuZD4pID0+IHtcbiAgICByZXR1cm4gcWJXcmFwcGVyLmZyb20oXCJyZXF1ZXN0X2xvZ3NcIikuc2VsZWN0KHtcbiAgICAgIGlkOiBcInJlcXVlc3RfbG9ncy5pZFwiLFxuICAgICAgY3JlYXRlZF9hdDogXCJyZXF1ZXN0X2xvZ3MuY3JlYXRlZF9hdFwiLFxuICAgICAgdG9rZW5fbmFtZTogXCJyZXF1ZXN0X2xvZ3MudG9rZW5fbmFtZVwiLFxuICAgICAgcXVlcnk6IFwicmVxdWVzdF9sb2dzLnF1ZXJ5XCIsXG4gICAgICByZXNwb25zZTogXCJyZXF1ZXN0X2xvZ3MucmVzcG9uc2VcIixcbiAgICAgIGlucHV0X3Rva2VuczogXCJyZXF1ZXN0X2xvZ3MuaW5wdXRfdG9rZW5zXCIsXG4gICAgICBvdXRwdXRfdG9rZW5zOiBcInJlcXVlc3RfbG9ncy5vdXRwdXRfdG9rZW5zXCIsXG4gICAgICBjYWNoZV9yZWFkX3Rva2VuczogXCJyZXF1ZXN0X2xvZ3MuY2FjaGVfcmVhZF90b2tlbnNcIixcbiAgICAgIGNhY2hlX2NyZWF0aW9uX3Rva2VuczogXCJyZXF1ZXN0X2xvZ3MuY2FjaGVfY3JlYXRpb25fdG9rZW5zXCIsXG4gICAgICBkdXJhdGlvbl9tczogXCJyZXF1ZXN0X2xvZ3MuZHVyYXRpb25fbXNcIixcbiAgICAgIGNvc3RfdXNkOiBcInJlcXVlc3RfbG9ncy5jb3N0X3VzZFwiLFxuICAgIH0pO1xuICB9LFxufTtcblxuLy8gTG9hZGVyUXVlcnk6IFJlcXVlc3RMb2dcbmV4cG9ydCBjb25zdCByZXF1ZXN0TG9nTG9hZGVyUXVlcmllcyA9IHtcbiAgQTogW10sXG59IGFzIGNvbnN0IHNhdGlzZmllcyBQdXJpTG9hZGVyUXVlcmllczxSZXF1ZXN0TG9nU3Vic2V0S2V5PjtcblxuLy8gU3Vic2V0UXVlcnk6IFRva2VuXG5leHBvcnQgY29uc3QgdG9rZW5TdWJzZXRRdWVyaWVzID0ge1xuICBBOiAocWJXcmFwcGVyOiBQdXJpV3JhcHBlcjxEYXRhYmFzZVNjaGVtYUV4dGVuZD4pID0+IHtcbiAgICByZXR1cm4gcWJXcmFwcGVyLmZyb20oXCJ0b2tlbnNcIikuc2VsZWN0KHtcbiAgICAgIGlkOiBcInRva2Vucy5pZFwiLFxuICAgICAgY3JlYXRlZF9hdDogXCJ0b2tlbnMuY3JlYXRlZF9hdFwiLFxuICAgICAgdG9rZW46IFwidG9rZW5zLnRva2VuXCIsXG4gICAgICBuYW1lOiBcInRva2Vucy5uYW1lXCIsXG4gICAgICByZWZyZXNoX3Rva2VuOiBcInRva2Vucy5yZWZyZXNoX3Rva2VuXCIsXG4gICAgICBleHBpcmVzX2F0OiBcInRva2Vucy5leHBpcmVzX2F0XCIsXG4gICAgICBhY2NvdW50X3V1aWQ6IFwidG9rZW5zLmFjY291bnRfdXVpZFwiLFxuICAgICAgYWN0aXZlOiBcInRva2Vucy5hY3RpdmVcIixcbiAgICAgIG9yZDogXCJ0b2tlbnMub3JkXCIsXG4gICAgfSk7XG4gIH0sXG59O1xuXG4vLyBMb2FkZXJRdWVyeTogVG9rZW5cbmV4cG9ydCBjb25zdCB0b2tlbkxvYWRlclF1ZXJpZXMgPSB7XG4gIEE6IFtdLFxufSBhcyBjb25zdCBzYXRpc2ZpZXMgUHVyaUxvYWRlclF1ZXJpZXM8VG9rZW5TdWJzZXRLZXk+O1xuXG4vLyBEYXRhYmFzZVNjaGVtYVxuZGVjbGFyZSBtb2R1bGUgXCJzb25hbXVcIiB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YWJhc2VTY2hlbWFFeHRlbmQge1xuICAgIHJlcXVlc3RfbG9nczogUmVxdWVzdExvZ0Jhc2VTY2hlbWE7XG4gICAgdG9rZW5zOiBUb2tlbkJhc2VTY2hlbWE7XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIERhdGFiYXNlRm9yZWlnbktleXMge31cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7QUFlQSxNQUFhLDBCQUEwQixFQUNyQyxJQUFJLGNBQWlEO0FBQ25ELFFBQU8sVUFBVSxLQUFLLGVBQWUsQ0FBQyxPQUFPO0VBQzNDLElBQUk7RUFDSixZQUFZO0VBQ1osWUFBWTtFQUNaLE9BQU87RUFDUCxVQUFVO0VBQ1YsY0FBYztFQUNkLGVBQWU7RUFDZixtQkFBbUI7RUFDbkIsdUJBQXVCO0VBQ3ZCLGFBQWE7RUFDYixVQUFVO0VBQ1gsQ0FBQztHQUVMO0FBR0QsTUFBYSwwQkFBMEIsRUFDckMsR0FBRyxFQUFFLEVBQ047QUFHRCxNQUFhLHFCQUFxQixFQUNoQyxJQUFJLGNBQWlEO0FBQ25ELFFBQU8sVUFBVSxLQUFLLFNBQVMsQ0FBQyxPQUFPO0VBQ3JDLElBQUk7RUFDSixZQUFZO0VBQ1osT0FBTztFQUNQLE1BQU07RUFDTixlQUFlO0VBQ2YsWUFBWTtFQUNaLGNBQWM7RUFDZCxRQUFRO0VBQ1IsS0FBSztFQUNOLENBQUM7R0FFTDtBQUdELE1BQWEscUJBQXFCLEVBQ2hDLEdBQUcsRUFBRSxFQUNOIn0=
|
|
@@ -168,17 +168,14 @@ var sonamu_config_default = defineConfig({
|
|
|
168
168
|
} catch (e) {
|
|
169
169
|
console.warn(`⚠ Migration skipped: ${e.message}`);
|
|
170
170
|
}
|
|
171
|
-
const {
|
|
171
|
+
const { QgridDispatcher } = await import("./application/qgrid/qgrid.dispatcher.js");
|
|
172
172
|
try {
|
|
173
173
|
const { TokenModel } = await import("./application/token/token.model.js");
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
})));
|
|
178
|
-
console.log(`🌲 Server listening on http://${host}:${port} (${pool.workers.size} tokens loaded)`);
|
|
174
|
+
const entries = await TokenModel.findActive("A");
|
|
175
|
+
for (const e of entries) QgridDispatcher.addToken(e.token, e.name);
|
|
176
|
+
console.log(`🌲 Server listening on http://${host}:${port} (${QgridDispatcher.tokens.size} tokens loaded)`);
|
|
179
177
|
} catch (e) {
|
|
180
|
-
console.warn(`⚠
|
|
181
|
-
initPool([]);
|
|
178
|
+
console.warn(`⚠ Dispatcher init failed: ${e.message}`);
|
|
182
179
|
console.log(`🌲 Server listening on http://${host}:${port} (no tokens)`);
|
|
183
180
|
}
|
|
184
181
|
},
|
|
@@ -198,4 +195,4 @@ var sonamu_config_default = defineConfig({
|
|
|
198
195
|
//#endregion
|
|
199
196
|
export { sonamu_config_default as default };
|
|
200
197
|
|
|
201
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmNvbmZpZy5qcyIsIm5hbWVzIjpbImRyaXZlcnMiLCJjYWNoZURyaXZlcnMiXSwic291cmNlcyI6WyIuLi9zcmMvc29uYW11LmNvbmZpZy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyBnZXRDb25zb2xlU2luayB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyBnZXRQcmV0dHlGb3JtYXR0ZXIgfSBmcm9tIFwiQGxvZ3RhcGUvcHJldHR5XCI7XG5pbXBvcnQgZG90ZW52IGZyb20gXCJkb3RlbnZcIjtcbmltcG9ydCB7IENhY2hlUHJlc2V0cywgZGVmaW5lQ29uZmlnIH0gZnJvbSBcInNvbmFtdVwiO1xuaW1wb3J0IHsgZHJpdmVycyBhcyBjYWNoZURyaXZlcnMsIHN0b3JlIH0gZnJvbSBcInNvbmFtdS9jYWNoZVwiO1xuaW1wb3J0IHsgZHJpdmVycyB9IGZyb20gXCJzb25hbXUvc3RvcmFnZVwiO1xuXG5kb3RlbnYuY29uZmlnKHsgcGF0aDogcGF0aC5qb2luKGltcG9ydC5tZXRhLmRpcm5hbWUsIFwiLi4vLmVudlwiKSB9KTtcblxuY29uc3QgaG9zdCA9IHByb2Nlc3MuZW52LkhPU1QgPz8gXCJsb2NhbGhvc3RcIjtcbmNvbnN0IHBvcnQgPSBOdW1iZXIocHJvY2Vzcy5lbnYuUE9SVCA/PyA0NDkwMCk7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG4gIHByb2plY3ROYW1lOiBwcm9jZXNzLmVudi5QUk9KRUNUX05BTUUgPz8gXCJTb25hbXVQcm9qZWN0XCIsXG4gIGRhdGFiYXNlOiB7XG4gICAgbmFtZTogcHJvY2Vzcy5lbnYuUUdSSURfREJfTkFNRSA/PyBcInFncmlkXCIsXG4gICAgZGVmYXVsdE9wdGlvbnM6IHtcbiAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgaG9zdDogcHJvY2Vzcy5lbnYuUUdSSURfREJfSE9TVCA/PyBcImxvY2FsaG9zdFwiLFxuICAgICAgICBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuUUdSSURfREJfUE9SVCA/PyA0NDkwMSksXG4gICAgICAgIHVzZXI6IHByb2Nlc3MuZW52LlFHUklEX0RCX1VTRVIgPz8gXCJwb3N0Z3Jlc1wiLFxuICAgICAgICBwYXNzd29yZDogcHJvY2Vzcy5lbnYuUUdSSURfREJfUEFTU1dPUkQgPz8gXCJwb3N0Z3Jlc1wiLFxuICAgICAgICBrZWVwQWxpdmU6IHRydWUsXG4gICAgICAgIGtlZXBBbGl2ZUluaXRpYWxEZWxheU1pbGxpczogMTAwMDAsXG4gICAgICB9LFxuICAgIH0sXG4gICAgZW52aXJvbm1lbnRzOiB7XG4gICAgICBmaXh0dXJlOiB7XG4gICAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgICBob3N0OiBwcm9jZXNzLmVudi5ERVYwX0RCX0hPU1QsXG4gICAgICAgICAgcG9ydDogTnVtYmVyKHByb2Nlc3MuZW52LkRFVjBfREJfUE9SVCksXG4gICAgICAgICAgZGF0YWJhc2U6IHByb2Nlc3MuZW52LlFHUklEX0RCX05BTUUgKyBcIl9maXh0dXJlXCIsXG4gICAgICAgICAgdXNlcjogcHJvY2Vzcy5lbnYuREVWMF9EQl9VU0VSLFxuICAgICAgICAgIHBhc3N3b3JkOiBwcm9jZXNzLmVudi5ERVYwX0RCX1BBU1NXT1JELFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHRlc3Q6IHtcbiAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgIGhvc3Q6IFwiMC4wLjAuMFwiLFxuICAgICAgICAgIHBvcnQ6IDU0MzIxLFxuICAgICAgICAgIGRhdGFiYXNlOiBcInFncmlkX3Rlc3RcIixcbiAgICAgICAgICB1c2VyOiBcInBvc3RncmVzXCIsXG4gICAgICAgICAgcGFzc3dvcmQ6IFwicG9zdGdyZXNcIixcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAgYXBpOiB7XG4gICAgZGlyOiBcImFwaVwiLFxuICAgIHRpbWV6b25lOiBcIkFzaWEvU2VvdWxcIixcbiAgICByb3V0ZToge1xuICAgICAgcHJlZml4OiBcIi9hcGlcIixcbiAgICB9LFxuICB9LFxuICBpMThuOiB7XG4gICAgZGVmYXVsdExvY2FsZTogXCJrb1wiLFxuICAgIHN1cHBvcnRlZExvY2FsZXM6IFtcImtvXCIsIFwiZW5cIl0sXG4gIH0sXG4gIHN5bmM6IHtcbiAgICB0YXJnZXRzOiBbXCJ3ZWJcIl0sXG4gIH0sXG4gIHNsYWNrQ29uZmlybTpcbiAgICBwcm9jZXNzLmVudi5TTEFDS19CT1RfVE9LRU4gJiYgcHJvY2Vzcy5lbnYuU0xBQ0tfQ0hBTk5FTF9JRFxuICAgICAgPyB7XG4gICAgICAgICAgdGFyZ2V0czogW1wiZGV2ZWxvcG1lbnRfbWFzdGVyXCIsIFwicHJvZHVjdGlvbl9tYXN0ZXJcIl0sXG4gICAgICAgICAgYm90VG9rZW46IHByb2Nlc3MuZW52LlNMQUNLX0JPVF9UT0tFTiA/PyBcIlwiLFxuICAgICAgICAgIGNoYW5uZWxJZDogcHJvY2Vzcy5lbnYuU0xBQ0tfQ0hBTk5FTF9JRCA/PyBcIlwiLFxuICAgICAgICB9XG4gICAgICA6IHVuZGVmaW5lZCxcbiAgdGVzdDoge1xuICAgIHBhcmFsbGVsOiB0cnVlLFxuICAgIG1heFdvcmtlcnM6IDQsXG4gICAgZGV2UnVubmVyOiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgfSxcbiAgbG9nZ2luZzoge1xuICAgIHNpbmtzOiB7XG4gICAgICBjb25zb2xlOiBnZXRDb25zb2xlU2luayh7XG4gICAgICAgIGZvcm1hdHRlcjogZ2V0UHJldHR5Rm9ybWF0dGVyKHtcbiAgICAgICAgICB0aW1lc3RhbXA6IFwidGltZVwiLFxuICAgICAgICAgIGNhdGVnb3J5V2lkdGg6IDIwLFxuICAgICAgICAgIGNhdGVnb3J5VHJ1bmNhdGU6IFwibWlkZGxlXCIsXG4gICAgICAgIH0pLFxuICAgICAgfSksXG4gICAgfSxcbiAgICBsb2dnZXJzOiBbXG4gICAgICB7XG4gICAgICAgIGNhdGVnb3J5OiBbXCJzb25hbXVcIl0sXG4gICAgICAgIHNpbmtzOiBbXCJjb25zb2xlXCJdLFxuICAgICAgICBsb3dlc3RMZXZlbDogcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiID8gXCJ3YXJuaW5nXCIgOiBcImRlYnVnXCIsXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG4gIHNlcnZlcjoge1xuICAgIGxpc3RlbjogeyBwb3J0LCBob3N0IH0sXG4gICAgcGx1Z2luczoge1xuICAgICAgZm9ybWJvZHk6IHRydWUsXG4gICAgICBxczogdHJ1ZSxcbiAgICAgIG11bHRpcGFydDogeyBsaW1pdHM6IHsgZmlsZVNpemU6IDEwMjQgKiAxMDI0ICogMzAgfSB9LFxuICAgICAgc3RhdGljOiB7XG4gICAgICAgIHJvb3Q6IHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi8uLi9cIiwgXCJwdWJsaWNcIiksXG4gICAgICAgIHByZWZpeDogXCIvYXBpL3B1YmxpY1wiLFxuICAgICAgfSxcbiAgICAgIGN1c3RvbTogKHNlcnZlcikgPT4ge1xuICAgICAgICAvLyBPQXV0aCDsvZzrsLEg4oCUIEFudGhyb3BpY+ydtCAvY2FsbGJhY2vsnLzroZwg66as64uk7J2066CJ7Yq4XG4gICAgICAgIHNlcnZlci5nZXQoXCIvY2FsbGJhY2tcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBjb2RlLCBzdGF0ZSB9ID0gcmVxdWVzdC5xdWVyeSBhcyB7IGNvZGU/OiBzdHJpbmc7IHN0YXRlPzogc3RyaW5nIH07XG4gICAgICAgICAgaWYgKCFjb2RlIHx8ICFzdGF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlcGx5LnJlZGlyZWN0KFwiLz9vYXV0aD1lcnJvciZyZWFzb249bWlzc2luZ19wYXJhbXNcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEZyYW1l7J2YIG9hdXRoQ2FsbGJhY2vsnLzroZwg7JyE7J6EXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgUWdyaWRGcmFtZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9hcHBsaWNhdGlvbi9xZ3JpZC9xZ3JpZC5mcmFtZVwiKTtcbiAgICAgICAgICAgIGF3YWl0IFFncmlkRnJhbWUuaGFuZGxlT0F1dGhDYWxsYmFjayhjb2RlLCBzdGF0ZSwgcmVwbHkpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcbiAgICAgICAgICAgICAgYC8/b2F1dGg9ZXJyb3ImcmVhc29uPSR7ZW5jb2RlVVJJQ29tcG9uZW50KChlIGFzIEVycm9yKS5tZXNzYWdlKX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9LFxuICAgIGFwaUNvbmZpZzoge1xuICAgICAgY29udGV4dFByb3ZpZGVyOiAoZGVmYXVsdENvbnRleHQsIHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5kZWZhdWx0Q29udGV4dCxcbiAgICAgICAgICBpcDogcmVxdWVzdC5pcCxcbiAgICAgICAgICBib2R5OiByZXF1ZXN0LmJvZHksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZ3VhcmRIYW5kbGVyOiAoX2d1YXJkLCBfcmVxdWVzdCwgX2FwaSkgPT4ge1xuICAgICAgICBpZiAoX2d1YXJkID09PSBcInVzZXJcIikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwidXNlciBndWFyZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhcIk5PVEhJTkcgWUVUXCIpO1xuICAgICAgfSxcbiAgICAgIGNhY2hlQ29udHJvbEhhbmRsZXI6IChyZXEpID0+IHtcbiAgICAgICAgc3dpdGNoIChyZXEudHlwZSkge1xuICAgICAgICAgIGNhc2UgXCJhc3NldHNcIjpcbiAgICAgICAgICAgIC8vIEhhc2gg7Y+s7ZWo65CcIO2MjOydvDog7JiB6rWsIOy6kOyLnFxuICAgICAgICAgICAgaWYgKHJlcS5wYXRoLm1hdGNoKC8tW2EtZjAtOV0rXFwuLykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5pbW11dGFibGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLmxvbmdMaXZlZDtcblxuICAgICAgICAgIGNhc2UgXCJhcGlcIjpcbiAgICAgICAgICAgIC8vIEdFVCDsmpTssq3rp4wg7LqQ7IuxIOqzoOugpFxuICAgICAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgICAgICAgLy8g7Yq57KCVIOqyveuhnOuKlCDsp6fsnYAg7LqQ7IucXG4gICAgICAgICAgICAgIGlmIChyZXEucGF0aC5zdGFydHNXaXRoKFwiL2FwaS9zdGF0aWMtZGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuc2hvcnRMaXZlZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVxLnBhdGguc3RhcnRzV2l0aChcIi9hcGkvdGVybXNcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLm1lZGl1bUxpdmVkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDquLDrs7g6IOy6kOyLnCDsl4bsnYxcbiAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMubm9DYWNoZTtcblxuICAgICAgICAgIGNhc2UgXCJzc3JcIjpcbiAgICAgICAgICAgIC8vIFNTUiDtjpjsnbTsp4A6IDEw7LSIIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zc3I7XG5cbiAgICAgICAgICBjYXNlIFwiY3NyXCI6XG4gICAgICAgICAgICAvLyBDU1IgZmFsbGJhY2sgKGluZGV4Lmh0bWwpOiAx67aEIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zaG9ydExpdmVkO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAgc3RvcmFnZToge1xuICAgICAgZHJpdmVyczoge1xuICAgICAgICBmczogZHJpdmVycy5mcyh7XG4gICAgICAgICAgbG9jYXRpb246IHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi8uLi9wdWJsaWMvdXBsb2FkZWRcIiksXG4gICAgICAgICAgdmlzaWJpbGl0eTogXCJwdWJsaWNcIixcbiAgICAgICAgICB1cmxCdWlsZGVyOiB7XG4gICAgICAgICAgICBhc3luYyBnZW5lcmF0ZVVSTChrZXkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGAvYXBpL3B1YmxpYy91cGxvYWRlZC8ke2tleX1gO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIGdlbmVyYXRlU2lnbmVkVVJMKGtleSkge1xuICAgICAgICAgICAgICByZXR1cm4gYC9hcGkvcHVibGljL3VwbG9hZGVkLyR7a2V5fWA7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBzMzogZHJpdmVycy5zMyh7XG4gICAgICAgICAgY3JlZGVudGlhbHM6IHtcbiAgICAgICAgICAgIGFjY2Vzc0tleUlkOiBwcm9jZXNzLmVudi5BV1NfQUNDRVNTX0tFWV9JRCA/PyBcIlwiLFxuICAgICAgICAgICAgc2VjcmV0QWNjZXNzS2V5OiBwcm9jZXNzLmVudi5BV1NfU0VDUkVUX0FDQ0VTU19LRVkgPz8gXCJcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlZ2lvbjogcHJvY2Vzcy5lbnYuUzNfUkVHSU9OID8/IFwiYXAtbm9ydGhlYXN0LTJcIixcbiAgICAgICAgICBidWNrZXQ6IHByb2Nlc3MuZW52LlMzX0JVQ0tFVCA/PyBcInNvbmFtdV9kZWZhdWx0X2J1Y2tldFwiLFxuICAgICAgICAgIHZpc2liaWxpdHk6IFwicHJpdmF0ZVwiLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBjYWNoZToge1xuICAgICAgZGVmYXVsdDogXCJtYWluXCIsXG4gICAgICBzdG9yZXM6IHtcbiAgICAgICAgbWFpbjogc3RvcmUoKS51c2VMMUxheWVyKGNhY2hlRHJpdmVycy5tZW1vcnkoeyBtYXhTaXplOiBcIjUwbWJcIiB9KSksXG4gICAgICB9LFxuICAgICAgdHRsOiBcIjVtXCIsXG4gICAgICBwcmVmaXg6IFwiXCIsXG4gICAgfSxcbiAgICBsaWZlY3ljbGU6IHtcbiAgICAgIG9uU3RhcnQ6IGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gREIg66eI7J206re466CI7J207IWYIOyekOuPmSDsi6TtlokgKO2FjOydtOu4lCDsl4bsnLzrqbQg7IOd7ISxKVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgVG9rZW5Nb2RlbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi9hcHBsaWNhdGlvbi90b2tlbi90b2tlbi5tb2RlbFwiKTtcbiAgICAgICAgICBjb25zdCBrbmV4ID0gVG9rZW5Nb2RlbC5nZXREQihcIndcIik7XG4gICAgICAgICAgY29uc3QgbWlncmF0aW9uc0RpciA9IHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi4uL3NyYy9taWdyYXRpb25zXCIpO1xuICAgICAgICAgIGNvbnN0IFtiYXRjaCwgbG9nXSA9IGF3YWl0IGtuZXgubWlncmF0ZS5sYXRlc3Qoe1xuICAgICAgICAgICAgZGlyZWN0b3J5OiBtaWdyYXRpb25zRGlyLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChsb2cubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYOKckyBNaWdyYXRpb246ICR7bG9nLmxlbmd0aH0gYXBwbGllZCAoYmF0Y2ggJHtiYXRjaH0pYCk7XG4gICAgICAgICAgICBsb2cuZm9yRWFjaCgobmFtZTogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhgICDinJMgJHtuYW1lfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYOKaoCBNaWdyYXRpb24gc2tpcHBlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvb2wg7LSI6riw7ZmUXG4gICAgICAgIGNvbnN0IHsgaW5pdFBvb2wgfSA9IGF3YWl0IGltcG9ydChcIi4vYXBwbGljYXRpb24vcWdyaWQvcG9vbFwiKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IFRva2VuTW9kZWwgfSA9IGF3YWl0IGltcG9ydChcIi4vYXBwbGljYXRpb24vdG9rZW4vdG9rZW4ubW9kZWxcIik7XG4gICAgICAgICAgY29uc3QgZW50cmllcyA9IGF3YWl0IFRva2VuTW9kZWwuZmluZEFjdGl2ZShcIkFcIik7XG4gICAgICAgICAgY29uc3QgdG9rZW5zID0gZW50cmllcy5tYXAoKGUpID0+ICh7IHRva2VuOiBlLnRva2VuLCBuYW1lOiBlLm5hbWUgfSkpO1xuICAgICAgICAgIGNvbnN0IHBvb2wgPSBpbml0UG9vbCh0b2tlbnMpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgYPCfjLIgU2VydmVyIGxpc3RlbmluZyBvbiBodHRwOi8vJHtob3N0fToke3BvcnR9ICgke3Bvb2wud29ya2Vycy5zaXplfSB0b2tlbnMgbG9hZGVkKWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnNvbGUud2Fybihg4pqgIFBvb2wgaW5pdCBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgaW5pdFBvb2woW10pO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGDwn4yyIFNlcnZlciBsaXN0ZW5pbmcgb24gaHR0cDovLyR7aG9zdH06JHtwb3J0fSAobm8gdG9rZW5zKWApO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgb25TaHV0ZG93bjogKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhcImdyYWNlZnVsIHNodXRkb3duXCIpO1xuICAgICAgfSxcbiAgICAgIG9uRXJyb3I6IChlcnJvciwgX3JlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICByZXBseS5zdGF0dXMoNTAwKS5zZW5kKHtcbiAgICAgICAgICBuYW1lOiBlcnJvci5uYW1lLFxuICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9LFxuICB9LFxufSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQVNBLE9BQU8sT0FBTyxFQUFFLE1BQU0sS0FBSyxLQUFLLE9BQU8sS0FBSyxTQUFTLFVBQVUsRUFBRSxDQUFDO0FBRWxFLE1BQU0sT0FBTyxRQUFRLElBQUksUUFBUTtBQUNqQyxNQUFNLE9BQU8sT0FBTyxRQUFRLElBQUksUUFBUSxNQUFNO0FBRTlDLElBQUEsd0JBQWUsYUFBYTtDQUMxQixhQUFhLFFBQVEsSUFBSSxnQkFBZ0I7Q0FDekMsVUFBVTtFQUNSLE1BQU0sUUFBUSxJQUFJLGlCQUFpQjtFQUNuQyxnQkFBZ0IsRUFDZCxZQUFZO0dBQ1YsTUFBTSxRQUFRLElBQUksaUJBQWlCO0dBQ25DLE1BQU0sT0FBTyxRQUFRLElBQUksaUJBQWlCLE1BQU07R0FDaEQsTUFBTSxRQUFRLElBQUksaUJBQWlCO0dBQ25DLFVBQVUsUUFBUSxJQUFJLHFCQUFxQjtHQUMzQyxXQUFXO0dBQ1gsNkJBQTZCO0dBQzlCLEVBQ0Y7RUFDRCxjQUFjO0dBQ1osU0FBUyxFQUNQLFlBQVk7SUFDVixNQUFNLFFBQVEsSUFBSTtJQUNsQixNQUFNLE9BQU8sUUFBUSxJQUFJLGFBQWE7SUFDdEMsVUFBVSxRQUFRLElBQUksZ0JBQWdCO0lBQ3RDLE1BQU0sUUFBUSxJQUFJO0lBQ2xCLFVBQVUsUUFBUSxJQUFJO0lBQ3ZCLEVBQ0Y7R0FDRCxNQUFNLEVBQ0osWUFBWTtJQUNWLE1BQU07SUFDTixNQUFNO0lBQ04sVUFBVTtJQUNWLE1BQU07SUFDTixVQUFVO0lBQ1gsRUFDRjtHQUNGO0VBQ0Y7Q0FDRCxLQUFLO0VBQ0gsS0FBSztFQUNMLFVBQVU7RUFDVixP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
|
|
198
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmNvbmZpZy5qcyIsIm5hbWVzIjpbImRyaXZlcnMiLCJjYWNoZURyaXZlcnMiXSwic291cmNlcyI6WyIuLi9zcmMvc29uYW11LmNvbmZpZy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyBnZXRDb25zb2xlU2luayB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyBnZXRQcmV0dHlGb3JtYXR0ZXIgfSBmcm9tIFwiQGxvZ3RhcGUvcHJldHR5XCI7XG5pbXBvcnQgZG90ZW52IGZyb20gXCJkb3RlbnZcIjtcbmltcG9ydCB7IENhY2hlUHJlc2V0cywgZGVmaW5lQ29uZmlnIH0gZnJvbSBcInNvbmFtdVwiO1xuaW1wb3J0IHsgZHJpdmVycyBhcyBjYWNoZURyaXZlcnMsIHN0b3JlIH0gZnJvbSBcInNvbmFtdS9jYWNoZVwiO1xuaW1wb3J0IHsgZHJpdmVycyB9IGZyb20gXCJzb25hbXUvc3RvcmFnZVwiO1xuXG5kb3RlbnYuY29uZmlnKHsgcGF0aDogcGF0aC5qb2luKGltcG9ydC5tZXRhLmRpcm5hbWUsIFwiLi4vLmVudlwiKSB9KTtcblxuY29uc3QgaG9zdCA9IHByb2Nlc3MuZW52LkhPU1QgPz8gXCJsb2NhbGhvc3RcIjtcbmNvbnN0IHBvcnQgPSBOdW1iZXIocHJvY2Vzcy5lbnYuUE9SVCA/PyA0NDkwMCk7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XG4gIHByb2plY3ROYW1lOiBwcm9jZXNzLmVudi5QUk9KRUNUX05BTUUgPz8gXCJTb25hbXVQcm9qZWN0XCIsXG4gIGRhdGFiYXNlOiB7XG4gICAgbmFtZTogcHJvY2Vzcy5lbnYuUUdSSURfREJfTkFNRSA/PyBcInFncmlkXCIsXG4gICAgZGVmYXVsdE9wdGlvbnM6IHtcbiAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgaG9zdDogcHJvY2Vzcy5lbnYuUUdSSURfREJfSE9TVCA/PyBcImxvY2FsaG9zdFwiLFxuICAgICAgICBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuUUdSSURfREJfUE9SVCA/PyA0NDkwMSksXG4gICAgICAgIHVzZXI6IHByb2Nlc3MuZW52LlFHUklEX0RCX1VTRVIgPz8gXCJwb3N0Z3Jlc1wiLFxuICAgICAgICBwYXNzd29yZDogcHJvY2Vzcy5lbnYuUUdSSURfREJfUEFTU1dPUkQgPz8gXCJwb3N0Z3Jlc1wiLFxuICAgICAgICBrZWVwQWxpdmU6IHRydWUsXG4gICAgICAgIGtlZXBBbGl2ZUluaXRpYWxEZWxheU1pbGxpczogMTAwMDAsXG4gICAgICB9LFxuICAgIH0sXG4gICAgZW52aXJvbm1lbnRzOiB7XG4gICAgICBmaXh0dXJlOiB7XG4gICAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgICBob3N0OiBwcm9jZXNzLmVudi5ERVYwX0RCX0hPU1QsXG4gICAgICAgICAgcG9ydDogTnVtYmVyKHByb2Nlc3MuZW52LkRFVjBfREJfUE9SVCksXG4gICAgICAgICAgZGF0YWJhc2U6IHByb2Nlc3MuZW52LlFHUklEX0RCX05BTUUgKyBcIl9maXh0dXJlXCIsXG4gICAgICAgICAgdXNlcjogcHJvY2Vzcy5lbnYuREVWMF9EQl9VU0VSLFxuICAgICAgICAgIHBhc3N3b3JkOiBwcm9jZXNzLmVudi5ERVYwX0RCX1BBU1NXT1JELFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHRlc3Q6IHtcbiAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgIGhvc3Q6IFwiMC4wLjAuMFwiLFxuICAgICAgICAgIHBvcnQ6IDU0MzIxLFxuICAgICAgICAgIGRhdGFiYXNlOiBcInFncmlkX3Rlc3RcIixcbiAgICAgICAgICB1c2VyOiBcInBvc3RncmVzXCIsXG4gICAgICAgICAgcGFzc3dvcmQ6IFwicG9zdGdyZXNcIixcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAgYXBpOiB7XG4gICAgZGlyOiBcImFwaVwiLFxuICAgIHRpbWV6b25lOiBcIkFzaWEvU2VvdWxcIixcbiAgICByb3V0ZToge1xuICAgICAgcHJlZml4OiBcIi9hcGlcIixcbiAgICB9LFxuICB9LFxuICBpMThuOiB7XG4gICAgZGVmYXVsdExvY2FsZTogXCJrb1wiLFxuICAgIHN1cHBvcnRlZExvY2FsZXM6IFtcImtvXCIsIFwiZW5cIl0sXG4gIH0sXG4gIHN5bmM6IHtcbiAgICB0YXJnZXRzOiBbXCJ3ZWJcIl0sXG4gIH0sXG4gIHNsYWNrQ29uZmlybTpcbiAgICBwcm9jZXNzLmVudi5TTEFDS19CT1RfVE9LRU4gJiYgcHJvY2Vzcy5lbnYuU0xBQ0tfQ0hBTk5FTF9JRFxuICAgICAgPyB7XG4gICAgICAgICAgdGFyZ2V0czogW1wiZGV2ZWxvcG1lbnRfbWFzdGVyXCIsIFwicHJvZHVjdGlvbl9tYXN0ZXJcIl0sXG4gICAgICAgICAgYm90VG9rZW46IHByb2Nlc3MuZW52LlNMQUNLX0JPVF9UT0tFTiA/PyBcIlwiLFxuICAgICAgICAgIGNoYW5uZWxJZDogcHJvY2Vzcy5lbnYuU0xBQ0tfQ0hBTk5FTF9JRCA/PyBcIlwiLFxuICAgICAgICB9XG4gICAgICA6IHVuZGVmaW5lZCxcbiAgdGVzdDoge1xuICAgIHBhcmFsbGVsOiB0cnVlLFxuICAgIG1heFdvcmtlcnM6IDQsXG4gICAgZGV2UnVubmVyOiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgfSxcbiAgbG9nZ2luZzoge1xuICAgIHNpbmtzOiB7XG4gICAgICBjb25zb2xlOiBnZXRDb25zb2xlU2luayh7XG4gICAgICAgIGZvcm1hdHRlcjogZ2V0UHJldHR5Rm9ybWF0dGVyKHtcbiAgICAgICAgICB0aW1lc3RhbXA6IFwidGltZVwiLFxuICAgICAgICAgIGNhdGVnb3J5V2lkdGg6IDIwLFxuICAgICAgICAgIGNhdGVnb3J5VHJ1bmNhdGU6IFwibWlkZGxlXCIsXG4gICAgICAgIH0pLFxuICAgICAgfSksXG4gICAgfSxcbiAgICBsb2dnZXJzOiBbXG4gICAgICB7XG4gICAgICAgIGNhdGVnb3J5OiBbXCJzb25hbXVcIl0sXG4gICAgICAgIHNpbmtzOiBbXCJjb25zb2xlXCJdLFxuICAgICAgICBsb3dlc3RMZXZlbDogcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiID8gXCJ3YXJuaW5nXCIgOiBcImRlYnVnXCIsXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG4gIHNlcnZlcjoge1xuICAgIGxpc3RlbjogeyBwb3J0LCBob3N0IH0sXG4gICAgcGx1Z2luczoge1xuICAgICAgZm9ybWJvZHk6IHRydWUsXG4gICAgICBxczogdHJ1ZSxcbiAgICAgIG11bHRpcGFydDogeyBsaW1pdHM6IHsgZmlsZVNpemU6IDEwMjQgKiAxMDI0ICogMzAgfSB9LFxuICAgICAgc3RhdGljOiB7XG4gICAgICAgIHJvb3Q6IHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi8uLi9cIiwgXCJwdWJsaWNcIiksXG4gICAgICAgIHByZWZpeDogXCIvYXBpL3B1YmxpY1wiLFxuICAgICAgfSxcbiAgICAgIGN1c3RvbTogKHNlcnZlcikgPT4ge1xuICAgICAgICAvLyBPQXV0aCDsvZzrsLEg4oCUIEFudGhyb3BpY+ydtCAvY2FsbGJhY2vsnLzroZwg66as64uk7J2066CJ7Yq4XG4gICAgICAgIHNlcnZlci5nZXQoXCIvY2FsbGJhY2tcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBjb2RlLCBzdGF0ZSB9ID0gcmVxdWVzdC5xdWVyeSBhcyB7IGNvZGU/OiBzdHJpbmc7IHN0YXRlPzogc3RyaW5nIH07XG4gICAgICAgICAgaWYgKCFjb2RlIHx8ICFzdGF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlcGx5LnJlZGlyZWN0KFwiLz9vYXV0aD1lcnJvciZyZWFzb249bWlzc2luZ19wYXJhbXNcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEZyYW1l7J2YIG9hdXRoQ2FsbGJhY2vsnLzroZwg7JyE7J6EXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgUWdyaWRGcmFtZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9hcHBsaWNhdGlvbi9xZ3JpZC9xZ3JpZC5mcmFtZVwiKTtcbiAgICAgICAgICAgIGF3YWl0IFFncmlkRnJhbWUuaGFuZGxlT0F1dGhDYWxsYmFjayhjb2RlLCBzdGF0ZSwgcmVwbHkpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcbiAgICAgICAgICAgICAgYC8/b2F1dGg9ZXJyb3ImcmVhc29uPSR7ZW5jb2RlVVJJQ29tcG9uZW50KChlIGFzIEVycm9yKS5tZXNzYWdlKX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9LFxuICAgIGFwaUNvbmZpZzoge1xuICAgICAgY29udGV4dFByb3ZpZGVyOiAoZGVmYXVsdENvbnRleHQsIHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5kZWZhdWx0Q29udGV4dCxcbiAgICAgICAgICBpcDogcmVxdWVzdC5pcCxcbiAgICAgICAgICBib2R5OiByZXF1ZXN0LmJvZHksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZ3VhcmRIYW5kbGVyOiAoX2d1YXJkLCBfcmVxdWVzdCwgX2FwaSkgPT4ge1xuICAgICAgICBpZiAoX2d1YXJkID09PSBcInVzZXJcIikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwidXNlciBndWFyZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhcIk5PVEhJTkcgWUVUXCIpO1xuICAgICAgfSxcbiAgICAgIGNhY2hlQ29udHJvbEhhbmRsZXI6IChyZXEpID0+IHtcbiAgICAgICAgc3dpdGNoIChyZXEudHlwZSkge1xuICAgICAgICAgIGNhc2UgXCJhc3NldHNcIjpcbiAgICAgICAgICAgIC8vIEhhc2gg7Y+s7ZWo65CcIO2MjOydvDog7JiB6rWsIOy6kOyLnFxuICAgICAgICAgICAgaWYgKHJlcS5wYXRoLm1hdGNoKC8tW2EtZjAtOV0rXFwuLykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5pbW11dGFibGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLmxvbmdMaXZlZDtcblxuICAgICAgICAgIGNhc2UgXCJhcGlcIjpcbiAgICAgICAgICAgIC8vIEdFVCDsmpTssq3rp4wg7LqQ7IuxIOqzoOugpFxuICAgICAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgICAgICAgLy8g7Yq57KCVIOqyveuhnOuKlCDsp6fsnYAg7LqQ7IucXG4gICAgICAgICAgICAgIGlmIChyZXEucGF0aC5zdGFydHNXaXRoKFwiL2FwaS9zdGF0aWMtZGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuc2hvcnRMaXZlZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVxLnBhdGguc3RhcnRzV2l0aChcIi9hcGkvdGVybXNcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLm1lZGl1bUxpdmVkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyDquLDrs7g6IOy6kOyLnCDsl4bsnYxcbiAgICAgICAgICAgIHJldHVybiBDYWNoZVByZXNldHMubm9DYWNoZTtcblxuICAgICAgICAgIGNhc2UgXCJzc3JcIjpcbiAgICAgICAgICAgIC8vIFNTUiDtjpjsnbTsp4A6IDEw7LSIIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zc3I7XG5cbiAgICAgICAgICBjYXNlIFwiY3NyXCI6XG4gICAgICAgICAgICAvLyBDU1IgZmFsbGJhY2sgKGluZGV4Lmh0bWwpOiAx67aEIOy6kOyLnFxuICAgICAgICAgICAgcmV0dXJuIENhY2hlUHJlc2V0cy5zaG9ydExpdmVkO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAgc3RvcmFnZToge1xuICAgICAgZHJpdmVyczoge1xuICAgICAgICBmczogZHJpdmVycy5mcyh7XG4gICAgICAgICAgbG9jYXRpb246IHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi8uLi9wdWJsaWMvdXBsb2FkZWRcIiksXG4gICAgICAgICAgdmlzaWJpbGl0eTogXCJwdWJsaWNcIixcbiAgICAgICAgICB1cmxCdWlsZGVyOiB7XG4gICAgICAgICAgICBhc3luYyBnZW5lcmF0ZVVSTChrZXkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGAvYXBpL3B1YmxpYy91cGxvYWRlZC8ke2tleX1gO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFzeW5jIGdlbmVyYXRlU2lnbmVkVVJMKGtleSkge1xuICAgICAgICAgICAgICByZXR1cm4gYC9hcGkvcHVibGljL3VwbG9hZGVkLyR7a2V5fWA7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBzMzogZHJpdmVycy5zMyh7XG4gICAgICAgICAgY3JlZGVudGlhbHM6IHtcbiAgICAgICAgICAgIGFjY2Vzc0tleUlkOiBwcm9jZXNzLmVudi5BV1NfQUNDRVNTX0tFWV9JRCA/PyBcIlwiLFxuICAgICAgICAgICAgc2VjcmV0QWNjZXNzS2V5OiBwcm9jZXNzLmVudi5BV1NfU0VDUkVUX0FDQ0VTU19LRVkgPz8gXCJcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlZ2lvbjogcHJvY2Vzcy5lbnYuUzNfUkVHSU9OID8/IFwiYXAtbm9ydGhlYXN0LTJcIixcbiAgICAgICAgICBidWNrZXQ6IHByb2Nlc3MuZW52LlMzX0JVQ0tFVCA/PyBcInNvbmFtdV9kZWZhdWx0X2J1Y2tldFwiLFxuICAgICAgICAgIHZpc2liaWxpdHk6IFwicHJpdmF0ZVwiLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBjYWNoZToge1xuICAgICAgZGVmYXVsdDogXCJtYWluXCIsXG4gICAgICBzdG9yZXM6IHtcbiAgICAgICAgbWFpbjogc3RvcmUoKS51c2VMMUxheWVyKGNhY2hlRHJpdmVycy5tZW1vcnkoeyBtYXhTaXplOiBcIjUwbWJcIiB9KSksXG4gICAgICB9LFxuICAgICAgdHRsOiBcIjVtXCIsXG4gICAgICBwcmVmaXg6IFwiXCIsXG4gICAgfSxcbiAgICBsaWZlY3ljbGU6IHtcbiAgICAgIG9uU3RhcnQ6IGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gREIg66eI7J206re466CI7J207IWYIOyekOuPmSDsi6TtlokgKO2FjOydtOu4lCDsl4bsnLzrqbQg7IOd7ISxKVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgVG9rZW5Nb2RlbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi9hcHBsaWNhdGlvbi90b2tlbi90b2tlbi5tb2RlbFwiKTtcbiAgICAgICAgICBjb25zdCBrbmV4ID0gVG9rZW5Nb2RlbC5nZXREQihcIndcIik7XG4gICAgICAgICAgY29uc3QgbWlncmF0aW9uc0RpciA9IHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi4uL3NyYy9taWdyYXRpb25zXCIpO1xuICAgICAgICAgIGNvbnN0IFtiYXRjaCwgbG9nXSA9IGF3YWl0IGtuZXgubWlncmF0ZS5sYXRlc3Qoe1xuICAgICAgICAgICAgZGlyZWN0b3J5OiBtaWdyYXRpb25zRGlyLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChsb2cubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYOKckyBNaWdyYXRpb246ICR7bG9nLmxlbmd0aH0gYXBwbGllZCAoYmF0Y2ggJHtiYXRjaH0pYCk7XG4gICAgICAgICAgICBsb2cuZm9yRWFjaCgobmFtZTogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhgICDinJMgJHtuYW1lfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYOKaoCBNaWdyYXRpb24gc2tpcHBlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgUWdyaWREaXNwYXRjaGVyIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLmRpc3BhdGNoZXJcIik7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBUb2tlbk1vZGVsIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCIpO1xuICAgICAgICAgIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRBY3RpdmUoXCJBXCIpO1xuICAgICAgICAgIGZvciAoY29uc3QgZSBvZiBlbnRyaWVzKSBRZ3JpZERpc3BhdGNoZXIuYWRkVG9rZW4oZS50b2tlbiwgZS5uYW1lKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGDwn4yyIFNlcnZlciBsaXN0ZW5pbmcgb24gaHR0cDovLyR7aG9zdH06JHtwb3J0fSAoJHtRZ3JpZERpc3BhdGNoZXIudG9rZW5zLnNpemV9IHRva2VucyBsb2FkZWQpYCxcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGDimqAgRGlzcGF0Y2hlciBpbml0IGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhg8J+MsiBTZXJ2ZXIgbGlzdGVuaW5nIG9uIGh0dHA6Ly8ke2hvc3R9OiR7cG9ydH0gKG5vIHRva2VucylgKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIG9uU2h1dGRvd246ICgpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coXCJncmFjZWZ1bCBzaHV0ZG93blwiKTtcbiAgICAgIH0sXG4gICAgICBvbkVycm9yOiAoZXJyb3IsIF9yZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgcmVwbHkuc3RhdHVzKDUwMCkuc2VuZCh7XG4gICAgICAgICAgbmFtZTogZXJyb3IubmFtZSxcbiAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFTQSxPQUFPLE9BQU8sRUFBRSxNQUFNLEtBQUssS0FBSyxPQUFPLEtBQUssU0FBUyxVQUFVLEVBQUUsQ0FBQztBQUVsRSxNQUFNLE9BQU8sUUFBUSxJQUFJLFFBQVE7QUFDakMsTUFBTSxPQUFPLE9BQU8sUUFBUSxJQUFJLFFBQVEsTUFBTTtBQUU5QyxJQUFBLHdCQUFlLGFBQWE7Q0FDMUIsYUFBYSxRQUFRLElBQUksZ0JBQWdCO0NBQ3pDLFVBQVU7RUFDUixNQUFNLFFBQVEsSUFBSSxpQkFBaUI7RUFDbkMsZ0JBQWdCLEVBQ2QsWUFBWTtHQUNWLE1BQU0sUUFBUSxJQUFJLGlCQUFpQjtHQUNuQyxNQUFNLE9BQU8sUUFBUSxJQUFJLGlCQUFpQixNQUFNO0dBQ2hELE1BQU0sUUFBUSxJQUFJLGlCQUFpQjtHQUNuQyxVQUFVLFFBQVEsSUFBSSxxQkFBcUI7R0FDM0MsV0FBVztHQUNYLDZCQUE2QjtHQUM5QixFQUNGO0VBQ0QsY0FBYztHQUNaLFNBQVMsRUFDUCxZQUFZO0lBQ1YsTUFBTSxRQUFRLElBQUk7SUFDbEIsTUFBTSxPQUFPLFFBQVEsSUFBSSxhQUFhO0lBQ3RDLFVBQVUsUUFBUSxJQUFJLGdCQUFnQjtJQUN0QyxNQUFNLFFBQVEsSUFBSTtJQUNsQixVQUFVLFFBQVEsSUFBSTtJQUN2QixFQUNGO0dBQ0QsTUFBTSxFQUNKLFlBQVk7SUFDVixNQUFNO0lBQ04sTUFBTTtJQUNOLFVBQVU7SUFDVixNQUFNO0lBQ04sVUFBVTtJQUNYLEVBQ0Y7R0FDRjtFQUNGO0NBQ0QsS0FBSztFQUNILEtBQUs7RUFDTCxVQUFVO0VBQ1YsT0FBTyxFQUNMLFFBQVEsUUFDVDtFQUNGO0NBQ0QsTUFBTTtFQUNKLGVBQWU7RUFDZixrQkFBa0IsQ0FBQyxN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
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { createHash, randomBytes } from "node:crypto";
|
|
5
5
|
|
|
6
|
-
import type
|
|
6
|
+
import { type UsageResponse } from "./qgrid.types";
|
|
7
7
|
|
|
8
8
|
const CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
9
9
|
const AUTHORIZE_URL = "https://claude.com/cai/oauth/authorize";
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QgridDispatcher — OAuth 토큰 선택 + claude CLI fresh spawn 디스패처 싱글턴.
|
|
3
|
+
*
|
|
4
|
+
* - 매 요청마다 새 claude CLI 프로세스 spawn → 응답 후 종료
|
|
5
|
+
* - system 은 --append-system-prompt 로 분리 전달 (user turn 오염 방지)
|
|
6
|
+
* - least-used round-robin 으로 토큰 선택
|
|
7
|
+
* - QuotaError 는 그대로 상위 전파 (자동 failover 없음, UI 에서 수동 토글)
|
|
8
|
+
*
|
|
9
|
+
* env allowlist: PATH, TMPDIR, CLAUDE_CODE_OAUTH_TOKEN + CLAUDE_CODE_DISABLE_*
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from "node:child_process";
|
|
12
|
+
import { mkdirSync } from "node:fs";
|
|
13
|
+
|
|
14
|
+
import { type CliResult, type QueryInput, type TokenStats } from "./qgrid.types";
|
|
15
|
+
import { maskToken, ProcessError, QuotaError, TimeoutError } from "./qgrid.types";
|
|
16
|
+
|
|
17
|
+
const DEFAULT_MODEL = "sonnet";
|
|
18
|
+
const DEFAULT_TIMEOUT_MS = 600_000;
|
|
19
|
+
|
|
20
|
+
class QgridDispatcherClass {
|
|
21
|
+
tokens = new Map<string, string>();
|
|
22
|
+
requestCounts = new Map<string, number>();
|
|
23
|
+
rrIndex = 0;
|
|
24
|
+
|
|
25
|
+
constructor() {
|
|
26
|
+
mkdirSync("/tmp/qgrid", { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getStats(): TokenStats[] {
|
|
30
|
+
return [...this.tokens.entries()].map(([token, name]) => ({
|
|
31
|
+
token,
|
|
32
|
+
name,
|
|
33
|
+
requests: this.requestCounts.get(token) ?? 0,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
selectToken(): { token: string; name: string } | null {
|
|
38
|
+
const entries = [...this.tokens.entries()];
|
|
39
|
+
if (entries.length === 0) return null;
|
|
40
|
+
|
|
41
|
+
const minCount = Math.min(...entries.map(([t]) => this.requestCounts.get(t) ?? 0));
|
|
42
|
+
const idle = entries.filter(([t]) => (this.requestCounts.get(t) ?? 0) === minCount);
|
|
43
|
+
const picked = idle[this.rrIndex % idle.length]!;
|
|
44
|
+
this.rrIndex++;
|
|
45
|
+
return { token: picked[0], name: picked[1] };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async query(input: QueryInput, timeoutMs?: number): Promise<CliResult> {
|
|
49
|
+
const sel = this.selectToken();
|
|
50
|
+
if (!sel) throw new QuotaError("No tokens available");
|
|
51
|
+
|
|
52
|
+
// await 전에 count 선반영. 병렬 요청이 동시에 도착해도 각자 다른 토큰을 고르도록.
|
|
53
|
+
this.requestCounts.set(sel.token, (this.requestCounts.get(sel.token) ?? 0) + 1);
|
|
54
|
+
|
|
55
|
+
console.log(`[qgrid] → ${sel.name} (model: ${input.model ?? DEFAULT_MODEL})`);
|
|
56
|
+
|
|
57
|
+
const result = await executeClaude(input, sel.token, timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
58
|
+
return { ...result, tokenName: sel.name };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
addToken(token: string, name: string): void {
|
|
62
|
+
if (this.tokens.has(token)) return;
|
|
63
|
+
this.tokens.set(token, name);
|
|
64
|
+
this.requestCounts.set(token, 0);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
removeToken(token: string): void {
|
|
68
|
+
this.tokens.delete(token);
|
|
69
|
+
this.requestCounts.delete(token);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
hasToken(token: string): boolean {
|
|
73
|
+
return this.tokens.has(token);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function executeClaude(
|
|
78
|
+
input: QueryInput,
|
|
79
|
+
token: string,
|
|
80
|
+
timeoutMs: number,
|
|
81
|
+
): Promise<CliResult> {
|
|
82
|
+
const model = input.model ?? DEFAULT_MODEL;
|
|
83
|
+
const timeout = input.timeout ?? timeoutMs;
|
|
84
|
+
|
|
85
|
+
const args: string[] = [
|
|
86
|
+
"-p",
|
|
87
|
+
"--output-format",
|
|
88
|
+
"stream-json",
|
|
89
|
+
"--verbose",
|
|
90
|
+
"--max-turns",
|
|
91
|
+
"1",
|
|
92
|
+
"--permission-mode",
|
|
93
|
+
"bypassPermissions",
|
|
94
|
+
"--setting-sources",
|
|
95
|
+
"project",
|
|
96
|
+
"--model",
|
|
97
|
+
model,
|
|
98
|
+
];
|
|
99
|
+
if (input.system) {
|
|
100
|
+
args.push("--append-system-prompt", input.system);
|
|
101
|
+
}
|
|
102
|
+
args.push(input.prompt);
|
|
103
|
+
|
|
104
|
+
const env: NodeJS.ProcessEnv = {
|
|
105
|
+
PATH: process.env.PATH,
|
|
106
|
+
TMPDIR: process.env.TMPDIR,
|
|
107
|
+
CLAUDE_CODE_OAUTH_TOKEN: token,
|
|
108
|
+
CLAUDE_CODE_DISABLE_AUTO_MEMORY: "1",
|
|
109
|
+
CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING: "1",
|
|
110
|
+
CLAUDE_CODE_DISABLE_1M_CONTEXT: "1",
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return new Promise<CliResult>((resolve, reject) => {
|
|
114
|
+
const child = spawn("claude", args, {
|
|
115
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
116
|
+
env,
|
|
117
|
+
cwd: "/tmp/qgrid",
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
let buffer = "";
|
|
121
|
+
let settled = false;
|
|
122
|
+
const timer = setTimeout(() => {
|
|
123
|
+
if (settled) return;
|
|
124
|
+
settled = true;
|
|
125
|
+
child.kill();
|
|
126
|
+
reject(new TimeoutError(`Timeout after ${timeout / 1000}s (token: ${maskToken(token)})`));
|
|
127
|
+
}, timeout);
|
|
128
|
+
|
|
129
|
+
child.stdout?.on("data", (d: Buffer) => {
|
|
130
|
+
if (settled) return;
|
|
131
|
+
buffer += d.toString();
|
|
132
|
+
const lines = buffer.split("\n");
|
|
133
|
+
buffer = lines.pop() ?? "";
|
|
134
|
+
for (const line of lines) {
|
|
135
|
+
if (!line.trim()) continue;
|
|
136
|
+
try {
|
|
137
|
+
const j = JSON.parse(line);
|
|
138
|
+
if (j.type === "result" && !settled) {
|
|
139
|
+
let text: string = j.result ?? "";
|
|
140
|
+
text = text.replace(/^```(?:json)?\s*\n?/i, "").replace(/\n?```\s*$/i, "");
|
|
141
|
+
|
|
142
|
+
if (text.startsWith("You've hit")) {
|
|
143
|
+
settled = true;
|
|
144
|
+
clearTimeout(timer);
|
|
145
|
+
reject(new QuotaError(`Quota exhausted (token: ${maskToken(token)})`));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const u = j.usage ?? {};
|
|
150
|
+
settled = true;
|
|
151
|
+
clearTimeout(timer);
|
|
152
|
+
resolve({
|
|
153
|
+
text,
|
|
154
|
+
usage: {
|
|
155
|
+
input_tokens: u.input_tokens ?? 0,
|
|
156
|
+
output_tokens: u.output_tokens ?? 0,
|
|
157
|
+
cache_creation_input_tokens: u.cache_creation_input_tokens ?? 0,
|
|
158
|
+
cache_read_input_tokens: u.cache_read_input_tokens ?? 0,
|
|
159
|
+
},
|
|
160
|
+
durationMs: j.duration_ms ?? 0,
|
|
161
|
+
costUsd: j.total_cost_usd ?? 0,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
} catch {}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
child.on("close", () => {
|
|
169
|
+
if (settled) return;
|
|
170
|
+
settled = true;
|
|
171
|
+
clearTimeout(timer);
|
|
172
|
+
reject(new ProcessError(`CLI process closed without result (token: ${maskToken(token)})`));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
child.on("error", (err) => {
|
|
176
|
+
if (settled) return;
|
|
177
|
+
settled = true;
|
|
178
|
+
clearTimeout(timer);
|
|
179
|
+
reject(new ProcessError(`CLI process error: ${err.message} (token: ${maskToken(token)})`));
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const QgridDispatcher = new QgridDispatcherClass();
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
generatePKCE,
|
|
12
12
|
refreshAccessToken,
|
|
13
13
|
} from "./oauth";
|
|
14
|
-
import {
|
|
14
|
+
import { QgridDispatcher } from "./qgrid.dispatcher";
|
|
15
15
|
import {
|
|
16
16
|
type CliResult,
|
|
17
17
|
type HealthResponse,
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
type UsageResponse,
|
|
21
21
|
} from "./qgrid.types";
|
|
22
22
|
|
|
23
|
-
// PKCE 세션 메모리 저장 (state → { codeVerifier, name, redirectUri })
|
|
24
23
|
const pendingOAuth = new Map<string, { codeVerifier: string; name: string; redirectUri: string }>();
|
|
25
24
|
|
|
26
25
|
class QgridFrameClass extends BaseFrameClass {
|
|
@@ -29,14 +28,17 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
@api({ httpMethod: "POST", clients: ["axios", "tanstack-mutation"] })
|
|
32
|
-
async query(
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
async query(
|
|
32
|
+
prompt: string,
|
|
33
|
+
system?: string,
|
|
34
|
+
timeout?: number,
|
|
35
|
+
model?: string,
|
|
36
|
+
): Promise<CliResult> {
|
|
37
|
+
const result = await QgridDispatcher.query({ system, prompt, model }, timeout);
|
|
35
38
|
|
|
36
|
-
// 로그 기록 실패해도 쿼리 결과는 반환
|
|
37
39
|
RequestLogModel.save([
|
|
38
40
|
{
|
|
39
|
-
token_name:
|
|
41
|
+
token_name: result.tokenName,
|
|
40
42
|
query: system ? `[System]\n${system}\n\n[User]\n${prompt}` : prompt,
|
|
41
43
|
response: result.text,
|
|
42
44
|
input_tokens: result.usage.input_tokens,
|
|
@@ -53,7 +55,7 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
53
55
|
|
|
54
56
|
@api({ httpMethod: "GET", clients: ["axios", "tanstack-query"] })
|
|
55
57
|
async stats(): Promise<TokenStats[]> {
|
|
56
|
-
return
|
|
58
|
+
return QgridDispatcher.getStats();
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
@api({ httpMethod: "GET", clients: ["axios", "tanstack-query"] })
|
|
@@ -70,7 +72,7 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
70
72
|
...(refreshToken && refreshToken.length > 0 ? { refresh_token: refreshToken } : {}),
|
|
71
73
|
},
|
|
72
74
|
]);
|
|
73
|
-
|
|
75
|
+
QgridDispatcher.addToken(token, name);
|
|
74
76
|
return { added: true };
|
|
75
77
|
}
|
|
76
78
|
|
|
@@ -81,7 +83,6 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
81
83
|
newToken?: string,
|
|
82
84
|
refreshToken?: string,
|
|
83
85
|
): Promise<{ updated: boolean }> {
|
|
84
|
-
const pool = getPool();
|
|
85
86
|
const entry = await TokenModel.findByToken("A", token);
|
|
86
87
|
if (!entry) return { updated: false };
|
|
87
88
|
|
|
@@ -97,52 +98,44 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
97
98
|
]);
|
|
98
99
|
|
|
99
100
|
if (hasNewToken) {
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
QgridDispatcher.removeToken(token);
|
|
102
|
+
QgridDispatcher.addToken(newToken, name ?? entry.name);
|
|
102
103
|
}
|
|
103
104
|
return { updated: true };
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
@api({ httpMethod: "POST", clients: ["axios", "tanstack-mutation"] })
|
|
107
108
|
async removeToken(token: string): Promise<{ removed: boolean }> {
|
|
108
|
-
|
|
109
|
-
if (!pool.workers.has(token)) return { removed: false };
|
|
109
|
+
if (!QgridDispatcher.hasToken(token)) return { removed: false };
|
|
110
110
|
|
|
111
111
|
const entry = await TokenModel.findByToken("A", token);
|
|
112
112
|
if (entry) await TokenModel.del([entry.id]);
|
|
113
|
-
|
|
113
|
+
QgridDispatcher.removeToken(token);
|
|
114
114
|
return { removed: true };
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/**
|
|
118
|
-
*
|
|
119
118
|
* @param id token_id
|
|
120
|
-
* 토큰 활성화/비활성화 토글 (
|
|
121
|
-
*
|
|
119
|
+
* 토큰 활성화/비활성화 토글 (dispatcher 등록/제거 & DB의 active 필드 업데이트)
|
|
122
120
|
* @returns 토큰 활성화 여부
|
|
123
121
|
*/
|
|
124
122
|
@api({ httpMethod: "POST", clients: ["axios", "tanstack-mutation"] })
|
|
125
123
|
async toggleToken(id: number): Promise<{ active: boolean }> {
|
|
126
|
-
const pool = getPool();
|
|
127
124
|
const entry = await TokenModel.findOne("A", { id });
|
|
128
125
|
if (!entry) return { active: false };
|
|
129
126
|
|
|
130
127
|
const newActive = !entry.active;
|
|
131
128
|
await TokenModel.save([{ id, token: entry.token, active: newActive, name: entry.name }]);
|
|
132
129
|
|
|
133
|
-
// 토큰의 새로운 상태가 활성화면/비활성화면
|
|
134
130
|
if (newActive) {
|
|
135
|
-
|
|
136
|
-
pool.createWorkers(entry.token, entry.name);
|
|
131
|
+
QgridDispatcher.addToken(entry.token, entry.name);
|
|
137
132
|
} else {
|
|
138
|
-
|
|
139
|
-
pool.destroyWorkers(entry.token);
|
|
133
|
+
QgridDispatcher.removeToken(entry.token);
|
|
140
134
|
}
|
|
141
135
|
|
|
142
136
|
return { active: newActive };
|
|
143
137
|
}
|
|
144
138
|
|
|
145
|
-
// OAuth 로그인: authUrl 생성 (프론트에서 이 API 호출 후 authUrl로 리다이렉트)
|
|
146
139
|
@api({ httpMethod: "POST", clients: ["axios", "tanstack-mutation"] })
|
|
147
140
|
async oauthStart(name: string): Promise<OAuthStartResult> {
|
|
148
141
|
const { codeVerifier, codeChallenge, state } = generatePKCE();
|
|
@@ -151,16 +144,13 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
151
144
|
const redirectUri = `http://localhost:${serverPort}/callback`;
|
|
152
145
|
const authUrl = buildAuthUrl(codeChallenge, state, redirectUri);
|
|
153
146
|
|
|
154
|
-
// PKCE를 메모리에 저장 (5분 TTL)
|
|
155
147
|
pendingOAuth.set(state, { codeVerifier, name, redirectUri });
|
|
156
148
|
setTimeout(() => pendingOAuth.delete(state), 300_000);
|
|
157
149
|
|
|
158
150
|
return { authUrl };
|
|
159
151
|
}
|
|
160
152
|
|
|
161
|
-
// OAuth 콜백 처리 — sonamu.config.ts의 custom 라우트에서 호출됨
|
|
162
153
|
async handleOAuthCallback(code: string, state: string, reply: FastifyReply): Promise<void> {
|
|
163
|
-
const pool = getPool();
|
|
164
154
|
const pending = pendingOAuth.get(state);
|
|
165
155
|
if (!pending) {
|
|
166
156
|
return reply.redirect("/?oauth=error&reason=invalid_state");
|
|
@@ -175,16 +165,14 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
175
165
|
pending.redirectUri,
|
|
176
166
|
);
|
|
177
167
|
|
|
178
|
-
// 같은 계정의 이전 토큰이 있으면 교체
|
|
179
168
|
if (tokens.accountUuid) {
|
|
180
169
|
const oldEntries = await TokenModel.findByAccountUuid("A", tokens.accountUuid);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
await TokenModel.del(
|
|
170
|
+
if (oldEntries.length > 0) {
|
|
171
|
+
for (const old of oldEntries) QgridDispatcher.removeToken(old.token);
|
|
172
|
+
await TokenModel.del(oldEntries.map((o) => o.id));
|
|
184
173
|
}
|
|
185
174
|
}
|
|
186
175
|
|
|
187
|
-
// 새 토큰 저장 + pool에 등록
|
|
188
176
|
await TokenModel.save([
|
|
189
177
|
{
|
|
190
178
|
token: tokens.accessToken,
|
|
@@ -194,7 +182,7 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
194
182
|
account_uuid: tokens.accountUuid,
|
|
195
183
|
},
|
|
196
184
|
]);
|
|
197
|
-
|
|
185
|
+
QgridDispatcher.addToken(tokens.accessToken, pending.name);
|
|
198
186
|
|
|
199
187
|
return reply.redirect(`/?oauth=success&name=${encodeURIComponent(pending.name)}`);
|
|
200
188
|
} catch (e) {
|
|
@@ -202,10 +190,8 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
202
190
|
}
|
|
203
191
|
}
|
|
204
192
|
|
|
205
|
-
// 토큰 사용량 조회 (OAuth usage API)
|
|
206
193
|
@api({ httpMethod: "GET", clients: ["axios", "tanstack-query"] })
|
|
207
194
|
async usage(tokenName?: string): Promise<UsageResponse> {
|
|
208
|
-
const pool = getPool();
|
|
209
195
|
const { rows: allTokens } = await TokenModel.findMany("A");
|
|
210
196
|
const entry = tokenName
|
|
211
197
|
? allTokens.find((e) => e.name === tokenName)
|
|
@@ -213,26 +199,23 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
213
199
|
|
|
214
200
|
if (!entry) return { error: "NOT_FOUND" };
|
|
215
201
|
|
|
216
|
-
// 만료 확인 + refresh 시도
|
|
217
202
|
let accessToken = entry.token;
|
|
218
203
|
const isExpired = entry.expires_at && Number(entry.expires_at) < Date.now();
|
|
219
204
|
|
|
220
205
|
if (isExpired && entry.refresh_token) {
|
|
221
206
|
try {
|
|
222
|
-
accessToken = await this.refreshToken(
|
|
207
|
+
accessToken = await this.refreshToken(entry);
|
|
223
208
|
} catch (e) {
|
|
224
209
|
console.warn(`[usage] refresh failed for ${entry.name}: ${(e as Error).message}`);
|
|
225
210
|
return { error: "re-login required" };
|
|
226
211
|
}
|
|
227
212
|
}
|
|
228
213
|
|
|
229
|
-
// usage 호출
|
|
230
214
|
const result = await fetchUsage(accessToken);
|
|
231
215
|
|
|
232
|
-
// 인증 에러면 refresh_token으로 재시도
|
|
233
216
|
if (result.error && entry.refresh_token) {
|
|
234
217
|
try {
|
|
235
|
-
accessToken = await this.refreshToken(
|
|
218
|
+
accessToken = await this.refreshToken(entry);
|
|
236
219
|
return await fetchUsage(accessToken);
|
|
237
220
|
} catch (e) {
|
|
238
221
|
console.warn(`[usage] refresh failed for ${entry.name}: ${(e as Error).message}`);
|
|
@@ -243,7 +226,7 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
243
226
|
return result;
|
|
244
227
|
}
|
|
245
228
|
|
|
246
|
-
async refreshToken(
|
|
229
|
+
async refreshToken(token: RefreshTokenParams): Promise<string> {
|
|
247
230
|
if (!token.refresh_token) throw new Error("No refresh token");
|
|
248
231
|
const refreshed = await refreshAccessToken(token.refresh_token);
|
|
249
232
|
await TokenModel.save([
|
|
@@ -255,19 +238,14 @@ class QgridFrameClass extends BaseFrameClass {
|
|
|
255
238
|
name: token.name ?? "",
|
|
256
239
|
},
|
|
257
240
|
]);
|
|
258
|
-
|
|
259
|
-
|
|
241
|
+
QgridDispatcher.removeToken(token.token);
|
|
242
|
+
QgridDispatcher.addToken(refreshed.accessToken, token.name);
|
|
260
243
|
return refreshed.accessToken;
|
|
261
244
|
}
|
|
262
245
|
|
|
263
246
|
@api({ httpMethod: "GET", clients: ["axios", "tanstack-query"] })
|
|
264
247
|
async health(): Promise<HealthResponse> {
|
|
265
|
-
|
|
266
|
-
return {
|
|
267
|
-
status: "ok",
|
|
268
|
-
workers: [...pool.workers.values()].flat().length,
|
|
269
|
-
activeTokens: pool.workers.size - pool.quotaExhausted.size,
|
|
270
|
-
};
|
|
248
|
+
return { status: "ok", activeTokens: QgridDispatcher.tokens.size };
|
|
271
249
|
}
|
|
272
250
|
}
|
|
273
251
|
|
|
@@ -5,12 +5,14 @@ import { z } from "zod";
|
|
|
5
5
|
export const QueryInput = z.object({
|
|
6
6
|
system: z.string().optional(),
|
|
7
7
|
prompt: z.string(),
|
|
8
|
+
model: z.string().optional(),
|
|
8
9
|
timeout: z.number().optional(),
|
|
9
10
|
});
|
|
10
11
|
export type QueryInput = z.infer<typeof QueryInput>;
|
|
11
12
|
|
|
12
13
|
export const CliResult = z.object({
|
|
13
14
|
text: z.string(),
|
|
15
|
+
tokenName: z.string().optional(),
|
|
14
16
|
usage: z.object({
|
|
15
17
|
input_tokens: z.number(),
|
|
16
18
|
output_tokens: z.number(),
|
|
@@ -22,18 +24,6 @@ export const CliResult = z.object({
|
|
|
22
24
|
});
|
|
23
25
|
export type CliResult = z.infer<typeof CliResult>;
|
|
24
26
|
|
|
25
|
-
// ─── Pool Config ───
|
|
26
|
-
|
|
27
|
-
export const PoolConfig = z.object({
|
|
28
|
-
tokens: z.array(z.object({ token: z.string(), name: z.string() })),
|
|
29
|
-
size: z.number().optional(),
|
|
30
|
-
model: z.string().optional(),
|
|
31
|
-
timeout: z.number().optional(),
|
|
32
|
-
cwd: z.string().optional(),
|
|
33
|
-
maxCalls: z.number().optional(),
|
|
34
|
-
});
|
|
35
|
-
export type PoolConfig = z.infer<typeof PoolConfig>;
|
|
36
|
-
|
|
37
27
|
// ─── Token Management ───
|
|
38
28
|
|
|
39
29
|
export const AddTokenInput = z.object({
|
|
@@ -51,7 +41,6 @@ export const TokenStats = z.object({
|
|
|
51
41
|
token: z.string(),
|
|
52
42
|
name: z.string(),
|
|
53
43
|
requests: z.number(),
|
|
54
|
-
active: z.boolean(),
|
|
55
44
|
});
|
|
56
45
|
export type TokenStats = z.infer<typeof TokenStats>;
|
|
57
46
|
|
|
@@ -93,7 +82,6 @@ export type UsageResponse = z.infer<typeof UsageResponse>;
|
|
|
93
82
|
|
|
94
83
|
export const HealthResponse = z.object({
|
|
95
84
|
status: z.string(),
|
|
96
|
-
workers: z.number(),
|
|
97
85
|
activeTokens: z.number(),
|
|
98
86
|
});
|
|
99
87
|
export type HealthResponse = z.infer<typeof HealthResponse>;
|