@agent-team-foundation/first-tree-hub 0.11.2 → 0.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{bootstrap-B-FRMuvL.mjs → bootstrap-D4rdqM2F.mjs} +2 -1
- package/dist/cli/index.mjs +44 -41
- package/dist/cli-fetch--tiwKm5S.mjs +167 -0
- package/dist/client-By1K4VVT-C5K7WZo6.mjs +4 -0
- package/dist/{client-CLdRbuml-B416INrm.mjs → client-CLdRbuml-BRtalKpQ.mjs} +2 -2
- package/dist/{dist-BLY7Bu-l.mjs → dist-BQtAQNRD.mjs} +1 -1
- package/dist/{feishu-GvFABWW5.mjs → feishu-Th_-ivJ7.mjs} +4 -3
- package/dist/{getMachineId-bsd-DjLgZlll.mjs → getMachineId-bsd-DyySs8xz.mjs} +2 -2
- package/dist/{getMachineId-bsd-DR4-Dysy.mjs → getMachineId-bsd-c2VImogj.mjs} +2 -2
- package/dist/{getMachineId-darwin-CaD2juTg.mjs → getMachineId-darwin-Cl7TSzgO.mjs} +2 -2
- package/dist/{getMachineId-darwin-B6WCAhc4.mjs → getMachineId-darwin-DKgI8b1d.mjs} +2 -2
- package/dist/{getMachineId-linux-Dk3gWdQK.mjs → getMachineId-linux-1OIMWfdh.mjs} +1 -1
- package/dist/{getMachineId-linux-BeWHG1gK.mjs → getMachineId-linux-cT7EbP10.mjs} +1 -1
- package/dist/{getMachineId-unsupported-BMJQItvF.mjs → getMachineId-unsupported-CkX-YOG1.mjs} +1 -1
- package/dist/{getMachineId-unsupported-Bgz_Je1J.mjs → getMachineId-unsupported-CmVlhzIo.mjs} +1 -1
- package/dist/{getMachineId-win-vJ6VfDRI.mjs → getMachineId-win-C2cM60YT.mjs} +2 -2
- package/dist/{getMachineId-win-CdgcrzCW.mjs → getMachineId-win-Chl03TYe.mjs} +2 -2
- package/dist/index.mjs +10 -9
- package/dist/invitation-DWlyNb8x-D3zjZSwI.mjs +4 -0
- package/dist/{invitation-Dnn5gGGX-Ce7zbZpn.mjs → invitation-Dnn5gGGX-DXryyvRG.mjs} +1 -1
- package/dist/{multipart-parser-BIksYTkk.mjs → multipart-parser-QRu3OKK4.mjs} +1 -1
- package/dist/{observability-C3nY6Jcz-Bk7FX689.mjs → observability-BAScT_5S-gw1ODB_o.mjs} +140 -17
- package/dist/observability-CYsdAcoF.mjs +5 -0
- package/dist/{saas-connect-Df2CVAGp.mjs → saas-connect-gcT6Q10z.mjs} +78 -158
- package/dist/{src-CzQ5KF6D.mjs → src-DFlbpJfU.mjs} +2 -2
- package/package.json +1 -1
- package/dist/client-By1K4VVT-nVOhsXBy.mjs +0 -4
- package/dist/invitation-DWlyNb8x-BEgoZ9k1.mjs +0 -4
- package/dist/observability-DttujCqj.mjs +0 -5
- /package/dist/{dist-FuUBFTEB.mjs → dist-BAqGZkco.mjs} +0 -0
- /package/dist/{errors-BmyRwN0Y-CIZZ_sDc.mjs → errors-BmyRwN0Y-Dad3eV8F.mjs} +0 -0
- /package/dist/{esm-iadMkGbV.mjs → esm-Ci8E1Gtj.mjs} +0 -0
- /package/dist/{execAsync-pImxPKN5.mjs → execAsync-DUfRkc4a.mjs} +0 -0
- /package/dist/{execAsync-CCyouKZM.mjs → execAsync-YbEZSOYd.mjs} +0 -0
- /package/dist/{from-CaD373S1.mjs → from-DQ7eNRwu.mjs} +0 -0
- /package/dist/{src-DNBS5Yjj.mjs → src-aJMV60mR.mjs} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import "./observability-
|
|
2
|
-
import { A as
|
|
1
|
+
import "./observability-BAScT_5S-gw1ODB_o.mjs";
|
|
2
|
+
import { A as checkDocker, B as isServiceSupported, E as checkAgentConfigs, F as checkWebSocket, G as uninstallClientService, H as restartClientService, I as printResults, J as stopPostgres, K as ensurePostgres, M as checkServerConfig, N as checkServerHealth, O as checkClientConfig, P as checkServerReachable, R as getClientServiceStatus, S as runHomeMigration, T as runMigrations, U as startClientService, V as resolveCliInvocation, W as stopClientService, X as handleClientOrgMismatch, Y as ClientRuntime, Z as rotateClientIdWithBackup, _ as formatCheckReport, b as onboardCreate, ct as FirstTreeHubSDK, d as startServer, g as promptMissingFields, h as promptAddAgent, j as checkNodeVersion, k as checkDatabase, lt as SdkError, m as isInteractive, n as deriveHubUrlFromToken, nt as hasUser, q as isDockerAvailable, t as HubUrlDerivationError, tt as createOwner, y as onboardCheck, z as installClientService } from "./saas-connect-gcT6Q10z.mjs";
|
|
3
3
|
import "./logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
4
|
-
import { a as ensureFreshAdminToken, c as resolveServerUrl, i as ensureFreshAccessToken, n as AuthRefreshRateLimitedError, s as resolveAccessToken, t as AuthRefreshFailedError } from "./bootstrap-
|
|
5
|
-
import "./
|
|
6
|
-
import
|
|
7
|
-
import "./
|
|
8
|
-
import "./
|
|
9
|
-
import "./
|
|
10
|
-
import "./
|
|
4
|
+
import { a as ensureFreshAdminToken, c as resolveServerUrl, i as ensureFreshAccessToken, n as AuthRefreshRateLimitedError, s as resolveAccessToken, t as AuthRefreshFailedError } from "./bootstrap-D4rdqM2F.mjs";
|
|
5
|
+
import { i as blank, s as status } from "./cli-fetch--tiwKm5S.mjs";
|
|
6
|
+
import "./dist-BAqGZkco.mjs";
|
|
7
|
+
import { n as bindFeishuUser, t as bindFeishuBot } from "./feishu-Th_-ivJ7.mjs";
|
|
8
|
+
import "./errors-BmyRwN0Y-Dad3eV8F.mjs";
|
|
9
|
+
import "./client-CLdRbuml-BRtalKpQ.mjs";
|
|
10
|
+
import "./src-aJMV60mR.mjs";
|
|
11
|
+
import "./invitation-Dnn5gGGX-DXryyvRG.mjs";
|
|
11
12
|
export { AuthRefreshFailedError, AuthRefreshRateLimitedError, ClientRuntime, FirstTreeHubSDK, HubUrlDerivationError, SdkError, bindFeishuBot, bindFeishuUser, blank, checkAgentConfigs, checkClientConfig, checkDatabase, checkDocker, checkNodeVersion, checkServerConfig, checkServerHealth, checkServerReachable, checkWebSocket, createOwner, deriveHubUrlFromToken, ensureFreshAccessToken, ensureFreshAdminToken, ensurePostgres, formatCheckReport, getClientServiceStatus, handleClientOrgMismatch, hasUser, installClientService, isDockerAvailable, isInteractive, isServiceSupported, onboardCheck, onboardCreate, printResults, promptAddAgent, promptMissingFields, resolveAccessToken, resolveCliInvocation, resolveServerUrl, restartClientService, rotateClientIdWithBackup, runHomeMigration, runMigrations, startClientService, startServer, status, stopClientService, stopPostgres, uninstallClientService };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as organizations, s as NotFoundError, u as users } from "./errors-BmyRwN0Y-
|
|
1
|
+
import { l as organizations, s as NotFoundError, u as users } from "./errors-BmyRwN0Y-Dad3eV8F.mjs";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
import { and, desc, eq, gt, isNull, or } from "drizzle-orm";
|
|
4
4
|
import { index, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __esmMin } from "./chunk-BSw8zbkd.mjs";
|
|
2
|
-
import { a as File, i as init_esm_min, n as FormData, t as init_from } from "./from-
|
|
2
|
+
import { a as File, i as init_esm_min, n as FormData, t as init_from } from "./from-DQ7eNRwu.mjs";
|
|
3
3
|
//#region ../../node_modules/.pnpm/node-fetch@3.3.2/node_modules/node-fetch/src/utils/multipart-parser.js
|
|
4
4
|
function _fileName(headerValue) {
|
|
5
5
|
const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "./chunk-BSw8zbkd.mjs";
|
|
2
2
|
import { a as formatLocalTime, c as parseLogLevel, i as createLoggerOutputStream, n as LOG_REDACT_PATHS, r as SKIP_KEYS, t as LOG_REDACT_CENSOR } from "./logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
3
|
-
import { a as metrics, c as SpanStatusCode, d as createContextKey, f as DiagLogLevel, n as init_esm$2, o as diag, r as trace, s as context, t as esm_exports$2, u as DiagConsoleLogger } from "./esm-
|
|
4
|
-
import { t as require_src$85 } from "./src-
|
|
3
|
+
import { a as metrics, c as SpanStatusCode, d as createContextKey, f as DiagLogLevel, n as init_esm$2, o as diag, r as trace, s as context, t as esm_exports$2, u as DiagConsoleLogger } from "./esm-Ci8E1Gtj.mjs";
|
|
4
|
+
import { t as require_src$85 } from "./src-aJMV60mR.mjs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { Writable } from "node:stream";
|
|
7
7
|
import * as fs$5 from "fs";
|
|
8
8
|
import * as path$2 from "path";
|
|
9
|
+
import { decodeJwt } from "jose";
|
|
9
10
|
import { Readable } from "stream";
|
|
10
11
|
import * as zlib$2 from "zlib";
|
|
11
12
|
//#region ../../node_modules/.pnpm/pino-std-serializers@7.1.0/node_modules/pino-std-serializers/lib/err-helpers.js
|
|
@@ -8162,19 +8163,19 @@ var require_getMachineId$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
8162
8163
|
async function getMachineId() {
|
|
8163
8164
|
if (!getMachineIdImpl) switch (process$3.platform) {
|
|
8164
8165
|
case "darwin":
|
|
8165
|
-
getMachineIdImpl = (await import("./getMachineId-darwin-
|
|
8166
|
+
getMachineIdImpl = (await import("./getMachineId-darwin-DKgI8b1d.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
8166
8167
|
break;
|
|
8167
8168
|
case "linux":
|
|
8168
|
-
getMachineIdImpl = (await import("./getMachineId-linux-
|
|
8169
|
+
getMachineIdImpl = (await import("./getMachineId-linux-cT7EbP10.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
8169
8170
|
break;
|
|
8170
8171
|
case "freebsd":
|
|
8171
|
-
getMachineIdImpl = (await import("./getMachineId-bsd-
|
|
8172
|
+
getMachineIdImpl = (await import("./getMachineId-bsd-DyySs8xz.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
8172
8173
|
break;
|
|
8173
8174
|
case "win32":
|
|
8174
|
-
getMachineIdImpl = (await import("./getMachineId-win-
|
|
8175
|
+
getMachineIdImpl = (await import("./getMachineId-win-Chl03TYe.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
8175
8176
|
break;
|
|
8176
8177
|
default:
|
|
8177
|
-
getMachineIdImpl = (await import("./getMachineId-unsupported-
|
|
8178
|
+
getMachineIdImpl = (await import("./getMachineId-unsupported-CkX-YOG1.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
8178
8179
|
break;
|
|
8179
8180
|
}
|
|
8180
8181
|
return getMachineIdImpl();
|
|
@@ -33763,12 +33764,12 @@ var require_gaxios = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
33763
33764
|
* @returns A proxy agent
|
|
33764
33765
|
*/
|
|
33765
33766
|
static async #getProxyAgent() {
|
|
33766
|
-
this.#proxyAgent ||= (await import("./dist-
|
|
33767
|
+
this.#proxyAgent ||= (await import("./dist-BQtAQNRD.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).HttpsProxyAgent;
|
|
33767
33768
|
return this.#proxyAgent;
|
|
33768
33769
|
}
|
|
33769
33770
|
static async #getFetch() {
|
|
33770
33771
|
const hasWindow = typeof window !== "undefined" && !!window;
|
|
33771
|
-
this.#fetch ||= hasWindow ? window.fetch : (await import("./src-
|
|
33772
|
+
this.#fetch ||= hasWindow ? window.fetch : (await import("./src-DFlbpJfU.mjs")).default;
|
|
33772
33773
|
return this.#fetch;
|
|
33773
33774
|
}
|
|
33774
33775
|
/**
|
|
@@ -41932,19 +41933,19 @@ var require_getMachineId = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
41932
41933
|
async function getMachineId() {
|
|
41933
41934
|
if (!getMachineIdImpl) switch (process$1.platform) {
|
|
41934
41935
|
case "darwin":
|
|
41935
|
-
getMachineIdImpl = (await import("./getMachineId-darwin-
|
|
41936
|
+
getMachineIdImpl = (await import("./getMachineId-darwin-Cl7TSzgO.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
41936
41937
|
break;
|
|
41937
41938
|
case "linux":
|
|
41938
|
-
getMachineIdImpl = (await import("./getMachineId-linux-
|
|
41939
|
+
getMachineIdImpl = (await import("./getMachineId-linux-1OIMWfdh.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
41939
41940
|
break;
|
|
41940
41941
|
case "freebsd":
|
|
41941
|
-
getMachineIdImpl = (await import("./getMachineId-bsd-
|
|
41942
|
+
getMachineIdImpl = (await import("./getMachineId-bsd-c2VImogj.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
41942
41943
|
break;
|
|
41943
41944
|
case "win32":
|
|
41944
|
-
getMachineIdImpl = (await import("./getMachineId-win-
|
|
41945
|
+
getMachineIdImpl = (await import("./getMachineId-win-C2cM60YT.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
41945
41946
|
break;
|
|
41946
41947
|
default:
|
|
41947
|
-
getMachineIdImpl = (await import("./getMachineId-unsupported-
|
|
41948
|
+
getMachineIdImpl = (await import("./getMachineId-unsupported-CmVlhzIo.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).getMachineId;
|
|
41948
41949
|
break;
|
|
41949
41950
|
}
|
|
41950
41951
|
return getMachineIdImpl();
|
|
@@ -95375,7 +95376,7 @@ const vr = {
|
|
|
95375
95376
|
warning: Ne$2
|
|
95376
95377
|
};
|
|
95377
95378
|
//#endregion
|
|
95378
|
-
//#region ../server/dist/observability-
|
|
95379
|
+
//#region ../server/dist/observability-BAScT_5S.mjs
|
|
95379
95380
|
init_esm$2();
|
|
95380
95381
|
var import_pino = /* @__PURE__ */ __toESM(require_pino(), 1);
|
|
95381
95382
|
const initialLevel = parseLogLevel(process.env.FIRST_TREE_HUB_LOG_LEVEL);
|
|
@@ -95764,6 +95765,70 @@ const observabilityPlugin = async (app) => {
|
|
|
95764
95765
|
});
|
|
95765
95766
|
};
|
|
95766
95767
|
/**
|
|
95768
|
+
* Map a thrown jose error to a stable failure-reason bucket. Unknown shapes
|
|
95769
|
+
* fall through to `jwt_verify_failed` so the span attribute always has a
|
|
95770
|
+
* value (callers can then refine the mapping without coordinating a deploy
|
|
95771
|
+
* with the trace backend).
|
|
95772
|
+
*/
|
|
95773
|
+
function classifyJoseError(err) {
|
|
95774
|
+
if (typeof err !== "object" || err === null) return "jwt_verify_failed";
|
|
95775
|
+
const code = err.code;
|
|
95776
|
+
if (typeof code !== "string") return "jwt_verify_failed";
|
|
95777
|
+
switch (code) {
|
|
95778
|
+
case "ERR_JWT_EXPIRED": return "jwt_expired";
|
|
95779
|
+
case "ERR_JWS_SIGNATURE_VERIFICATION_FAILED": return "jwt_signature_invalid";
|
|
95780
|
+
case "ERR_JWT_INVALID":
|
|
95781
|
+
case "ERR_JWS_INVALID":
|
|
95782
|
+
case "ERR_JWT_CLAIM_VALIDATION_FAILED": return "jwt_malformed";
|
|
95783
|
+
default: return "jwt_verify_failed";
|
|
95784
|
+
}
|
|
95785
|
+
}
|
|
95786
|
+
/**
|
|
95787
|
+
* Best-effort decode of a JWT *without* signature verification, for the sole
|
|
95788
|
+
* purpose of stamping its `sub` / `jti` / `exp` onto a failure trace.
|
|
95789
|
+
*
|
|
95790
|
+
* Returns `null` when the token is malformed enough that even base64 decode
|
|
95791
|
+
* fails — callers should treat absence as "no untrusted claims to record"
|
|
95792
|
+
* and continue without trace decoration.
|
|
95793
|
+
*
|
|
95794
|
+
* **Do not call from any code path that grants access.**
|
|
95795
|
+
*/
|
|
95796
|
+
function decodeJwtForTrace(token) {
|
|
95797
|
+
try {
|
|
95798
|
+
const claims = decodeJwt(token);
|
|
95799
|
+
const out = {};
|
|
95800
|
+
if (typeof claims.sub === "string") out.sub = claims.sub;
|
|
95801
|
+
if (typeof claims.exp === "number") out.exp = claims.exp;
|
|
95802
|
+
if (typeof claims.iat === "number") out.iat = claims.iat;
|
|
95803
|
+
if (typeof claims.jti === "string") out.jti = claims.jti;
|
|
95804
|
+
if (typeof claims.type === "string") out.type = claims.type;
|
|
95805
|
+
return out;
|
|
95806
|
+
} catch {
|
|
95807
|
+
return null;
|
|
95808
|
+
}
|
|
95809
|
+
}
|
|
95810
|
+
/**
|
|
95811
|
+
* Spread-helper that turns untrusted claims into the `<prefix>.untrusted.*`
|
|
95812
|
+
* attribute keys used on auth failure spans. Keeps the call sites short:
|
|
95813
|
+
*
|
|
95814
|
+
* throw new UnauthorizedError("...", {
|
|
95815
|
+
* "auth.refresh.reason": reason,
|
|
95816
|
+
* ...untrustedAttrs("auth.refresh", untrusted),
|
|
95817
|
+
* });
|
|
95818
|
+
*
|
|
95819
|
+
* Returns `{}` when `claims` is null so callers don't have to branch.
|
|
95820
|
+
*/
|
|
95821
|
+
function untrustedAttrs(prefix, claims) {
|
|
95822
|
+
if (!claims) return {};
|
|
95823
|
+
const out = {};
|
|
95824
|
+
if (claims.sub !== void 0) out[`${prefix}.untrusted.sub`] = claims.sub;
|
|
95825
|
+
if (claims.exp !== void 0) out[`${prefix}.untrusted.exp`] = claims.exp;
|
|
95826
|
+
if (claims.iat !== void 0) out[`${prefix}.untrusted.iat`] = claims.iat;
|
|
95827
|
+
if (claims.jti !== void 0) out[`${prefix}.untrusted.jti`] = claims.jti;
|
|
95828
|
+
if (claims.type !== void 0) out[`${prefix}.untrusted.type`] = claims.type;
|
|
95829
|
+
return out;
|
|
95830
|
+
}
|
|
95831
|
+
/**
|
|
95767
95832
|
* Logfire / OpenTelemetry bootstrap.
|
|
95768
95833
|
*
|
|
95769
95834
|
* This module replaces a previous hand-rolled `NodeTracerProvider` +
|
|
@@ -95891,6 +95956,63 @@ async function shutdownTelemetry() {
|
|
|
95891
95956
|
_enabled = false;
|
|
95892
95957
|
}
|
|
95893
95958
|
/**
|
|
95959
|
+
* Routes whose request body contains a JWT in `refreshToken` / `token`.
|
|
95960
|
+
* Used to gate the body-sniff in {@link buildRateLimitError} so unrelated
|
|
95961
|
+
* routes that happen to add a `token` field in the future won't get their
|
|
95962
|
+
* 429 trace polluted with bogus untrusted-decode attempts.
|
|
95963
|
+
*/
|
|
95964
|
+
const TOKEN_BODY_ROUTES = new Set(["/api/v1/auth/refresh", "/api/v1/auth/connect-token"]);
|
|
95965
|
+
/**
|
|
95966
|
+
* Constructs the `Error` instance that `@fastify/rate-limit` will throw on
|
|
95967
|
+
* a 429. Two side effects happen here that aren't trivial to express via
|
|
95968
|
+
* the limiter's default builder:
|
|
95969
|
+
*
|
|
95970
|
+
* 1. Stamp `rate_limit.{max,ttl_ms}` onto the active root span. The
|
|
95971
|
+
* limiter short-circuits before our handler runs, so without this
|
|
95972
|
+
* the 429 trace has no rate-limit metadata at all (issue #246).
|
|
95973
|
+
* 2. For `/auth/refresh` and `/auth/connect-token` only, opportunistically
|
|
95974
|
+
* decode the JWT in the request body (without verifying signature)
|
|
95975
|
+
* and stamp `auth.untrusted.sub` onto the same span — gives operators
|
|
95976
|
+
* the same `sub` pivot they get on a matching 401, so 429 storms can
|
|
95977
|
+
* be answered "1 looping client or N independent clients?".
|
|
95978
|
+
*
|
|
95979
|
+
* The returned value MUST be an `Error` instance — `@fastify/rate-limit`
|
|
95980
|
+
* throws it, and our `setErrorHandler` only honours the `statusCode`
|
|
95981
|
+
* branch when `error instanceof Error`. A plain object falls through to
|
|
95982
|
+
* the 500 generic branch.
|
|
95983
|
+
*
|
|
95984
|
+
* `exception.type` / `exception.message` are NOT stamped here: when our
|
|
95985
|
+
* `setErrorHandler` catches this, `reportErrorToRoot` calls
|
|
95986
|
+
* `span.recordException(err)` which sets those (OTel SDK convention)
|
|
95987
|
+
* using `error.name` / `error.message`. Stamping them here too would be
|
|
95988
|
+
* either redundant (same value) or overwritten (different value).
|
|
95989
|
+
*/
|
|
95990
|
+
function buildRateLimitError(request, context) {
|
|
95991
|
+
const span = request.openTelemetry().activeSpan;
|
|
95992
|
+
if (span) stampRateLimitAttrs(span, request, context);
|
|
95993
|
+
const message = `Rate limit exceeded, retry in ${Math.ceil(context.ttl / 1e3)} seconds`;
|
|
95994
|
+
const err = new Error(message);
|
|
95995
|
+
err.name = "RateLimitError";
|
|
95996
|
+
Object.assign(err, { statusCode: 429 });
|
|
95997
|
+
return err;
|
|
95998
|
+
}
|
|
95999
|
+
/**
|
|
96000
|
+
* Exported for unit testing. Pure side-effect function on `span` —
|
|
96001
|
+
* everything observable is the set of `setAttribute` calls.
|
|
96002
|
+
*/
|
|
96003
|
+
function stampRateLimitAttrs(span, request, context) {
|
|
96004
|
+
span.setAttribute("rate_limit.max", context.max);
|
|
96005
|
+
span.setAttribute("rate_limit.ttl_ms", context.ttl);
|
|
96006
|
+
const route = request.routeOptions?.url;
|
|
96007
|
+
if (!route || !TOKEN_BODY_ROUTES.has(route)) return;
|
|
96008
|
+
const body = request.body;
|
|
96009
|
+
if (!body || typeof body !== "object") return;
|
|
96010
|
+
const candidate = "refreshToken" in body && typeof body.refreshToken === "string" ? body.refreshToken : "token" in body && typeof body.token === "string" ? body.token : null;
|
|
96011
|
+
if (!candidate) return;
|
|
96012
|
+
const untrusted = decodeJwtForTrace(candidate);
|
|
96013
|
+
for (const [k, v] of Object.entries(untrustedAttrs("auth", untrusted))) span.setAttribute(k, v);
|
|
96014
|
+
}
|
|
96015
|
+
/**
|
|
95894
96016
|
* Helpers that turn domain objects (messages, inbox entries, chats, agents,
|
|
95895
96017
|
* adapters) into a consistent set of span attribute records.
|
|
95896
96018
|
*
|
|
@@ -95943,7 +96065,8 @@ function startWsConnectionSpan(socket, attrs = {}) {
|
|
|
95943
96065
|
const span = startTrackedSpan("ws.connection", {
|
|
95944
96066
|
[FIRST_TREE_HUB_ATTR.CLIENT_ID]: attrs.clientId,
|
|
95945
96067
|
[FIRST_TREE_HUB_ATTR.ORGANIZATION_ID]: attrs.organizationId,
|
|
95946
|
-
[FIRST_TREE_HUB_ATTR.WS_REMOTE_IP]: attrs.remoteIp
|
|
96068
|
+
[FIRST_TREE_HUB_ATTR.WS_REMOTE_IP]: attrs.remoteIp,
|
|
96069
|
+
[FIRST_TREE_HUB_ATTR.HTTP_USER_AGENT]: attrs.userAgent
|
|
95947
96070
|
});
|
|
95948
96071
|
if (!span) return;
|
|
95949
96072
|
const ctx = trace.setSpan(context.active(), span);
|
|
@@ -96003,4 +96126,4 @@ async function withWsMessageSpan(socket, type, attrs, fn) {
|
|
|
96003
96126
|
}));
|
|
96004
96127
|
}
|
|
96005
96128
|
//#endregion
|
|
96006
|
-
export {
|
|
96129
|
+
export { FIRST_TREE_HUB_ATTR as A, stampOrgScope as C, untrustedAttrs as D, startWsConnectionSpan as E, require_pino as M, withSpan as O, stampChatResource as S, startTrackedSpan as T, rootLogger as _, buildRateLimitError as a, shutdownTelemetry as b, currentTraceId as c, initTelemetry as d, messageAttrs as f, reportErrorToRoot as g, parseHeaderString as h, bodyCaptureOnSendHook as i, redactUrl as j, withWsMessageSpan as k, decodeJwtForTrace as l, observabilityPlugin as m, applyLoggerConfig as n, classifyJoseError as o, normalizeAttrs as p, attachRequestContext as r, createLogger as s, adapterAttrs as t, endWsConnectionSpan as u, setErrorSink as v, stampRateLimitAttrs as w, stampAgentResource as x, setWsConnectionAttrs as y };
|