@thenewlabs/entangle-utils 2.11.2 → 2.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/index.d.ts CHANGED
@@ -4,5 +4,6 @@ export * from './validation.js';
4
4
  export * from './counters.js';
5
5
  export * from './stream-counters.js';
6
6
  export * from './version.js';
7
+ export * from './user-agent.js';
7
8
  export * from './output.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -4,5 +4,6 @@ export * from './validation.js';
4
4
  export * from './counters.js';
5
5
  export * from './stream-counters.js';
6
6
  export * from './version.js';
7
+ export * from './user-agent.js';
7
8
  export * from './output.js';
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ /** Project URL appended so an operator seeing the UA in a log can identify it. */
2
+ export declare const USER_AGENT_URL = "https://github.com/thenewlabs/entangle";
3
+ /** Product token for the component making the request. Add a member per new outbound caller. */
4
+ export type UserAgentProduct = 'entangle-serve' | 'entangle-connect' | 'entangle-relay' | 'entangle';
5
+ /**
6
+ * Build the UA for `product` at the CALLING package's version. Pass the calling module's
7
+ * `import.meta.url`; as with `packageVersion()`, the manifest is expected one level up, which
8
+ * holds for any module directly under `src/` (tsx dev) or `dist/` (tsc output).
9
+ *
10
+ * In a standalone bundle the runtime manifest lookup CANNOT be trusted: `import.meta.url` is
11
+ * empty under the CJS output format, and even once a bundler rewrites it, it points at the
12
+ * bundle — so `../package.json` resolves to whichever package happens to sit above the output
13
+ * directory rather than to the calling package. That is how a bundled `locus` came to announce
14
+ * `entangle-serve/0.1.0` (the Locus root manifest) instead of serve's own 2.15.1. The injected
15
+ * map therefore WINS over the runtime read, which stays as the tsx/tsc-build path.
16
+ *
17
+ * e.g. `entangle-serve/2.15.1 (+https://github.com/thenewlabs/entangle)`
18
+ */
19
+ export declare function buildUserAgent(product: UserAgentProduct, callerModuleUrl: string): string;
20
+ /**
21
+ * Headers object for a Node `ws` client or `fetch`. Lowercase key: HTTP/1.1 header names are
22
+ * case-insensitive, and `ws` merges its own defaults case-sensitively.
23
+ */
24
+ export declare function userAgentHeaders(product: UserAgentProduct, callerModuleUrl: string): {
25
+ 'user-agent': string;
26
+ };
27
+ //# sourceMappingURL=user-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-agent.d.ts","sourceRoot":"","sources":["../src/user-agent.ts"],"names":[],"mappings":"AAgBA,kFAAkF;AAClF,eAAO,MAAM,cAAc,2CAA2C,CAAC;AAEvE,gGAAgG;AAChG,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,UAAU,CAAC;AAsCrG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,eAAe,EAAE,MAAM,GACtB;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAE1B"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The `User-Agent` every entangle component puts on its OWN outbound requests.
3
+ *
4
+ * Node sets no `User-Agent` by default — neither global `fetch` (undici) nor the `ws` client
5
+ * send one, unlike a browser. Relays and reverse proxies in front of them log the header as
6
+ * "-", and intrusion-prevention layers (CrowdSec et al.) treat a stream of UA-less requests as
7
+ * bot traffic and ban the source IP. `serve`'s registration WebSocket reconnects on a backoff
8
+ * loop, so a single unhappy relay produced exactly that pattern against `/agent/register`.
9
+ *
10
+ * The string is product + version only. It MUST NOT carry capIds, tokens, secrets, machine ids
11
+ * or paths: the relay is blind by design, and the header is the one part of a connection it
12
+ * always sees in cleartext. Distinguishing the products (`entangle-serve` vs `entangle-connect`)
13
+ * tells a relay operator which component is calling without telling them anything about who.
14
+ */
15
+ import { packageVersion } from './version.js';
16
+ /** Project URL appended so an operator seeing the UA in a log can identify it. */
17
+ export const USER_AGENT_URL = 'https://github.com/thenewlabs/entangle';
18
+ function buildTimeVersion(product) {
19
+ // `typeof` first and short-circuit: the identifier is undeclared outside a bundle, where any
20
+ // other reference to it would throw a ReferenceError at module load.
21
+ if (typeof ENTANGLE_BUILD_UA_VERSIONS !== 'object' || ENTANGLE_BUILD_UA_VERSIONS === null) {
22
+ return undefined;
23
+ }
24
+ const version = ENTANGLE_BUILD_UA_VERSIONS[product];
25
+ return typeof version === 'string' ? version : undefined;
26
+ }
27
+ /**
28
+ * Coerce a version to a single safe HTTP token, falling back to 'unknown'. Guards the two ways
29
+ * a bundle can degrade — a missing manifest yields `undefined`, and a lookup against an empty
30
+ * `import.meta` yields `''` — so the header is never `product/` or `product/undefined`. Also
31
+ * rejects whitespace and control characters, which would split or inject a header.
32
+ */
33
+ function safeVersion(raw) {
34
+ if (typeof raw !== 'string')
35
+ return 'unknown';
36
+ const version = raw.trim();
37
+ return version !== '' && /^[\x21-\x7e]+$/.test(version) ? version : 'unknown';
38
+ }
39
+ /**
40
+ * Build the UA for `product` at the CALLING package's version. Pass the calling module's
41
+ * `import.meta.url`; as with `packageVersion()`, the manifest is expected one level up, which
42
+ * holds for any module directly under `src/` (tsx dev) or `dist/` (tsc output).
43
+ *
44
+ * In a standalone bundle the runtime manifest lookup CANNOT be trusted: `import.meta.url` is
45
+ * empty under the CJS output format, and even once a bundler rewrites it, it points at the
46
+ * bundle — so `../package.json` resolves to whichever package happens to sit above the output
47
+ * directory rather than to the calling package. That is how a bundled `locus` came to announce
48
+ * `entangle-serve/0.1.0` (the Locus root manifest) instead of serve's own 2.15.1. The injected
49
+ * map therefore WINS over the runtime read, which stays as the tsx/tsc-build path.
50
+ *
51
+ * e.g. `entangle-serve/2.15.1 (+https://github.com/thenewlabs/entangle)`
52
+ */
53
+ export function buildUserAgent(product, callerModuleUrl) {
54
+ const version = safeVersion(buildTimeVersion(product) ?? packageVersion(callerModuleUrl));
55
+ return `${product}/${version} (+${USER_AGENT_URL})`;
56
+ }
57
+ /**
58
+ * Headers object for a Node `ws` client or `fetch`. Lowercase key: HTTP/1.1 header names are
59
+ * case-insensitive, and `ws` merges its own defaults case-sensitively.
60
+ */
61
+ export function userAgentHeaders(product, callerModuleUrl) {
62
+ return { 'user-agent': buildUserAgent(product, callerModuleUrl) };
63
+ }
64
+ //# sourceMappingURL=user-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-agent.js","sourceRoot":"","sources":["../src/user-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG,wCAAwC,CAAC;AAmBvE,SAAS,gBAAgB,CAAC,OAAyB;IACjD,6FAA6F;IAC7F,qEAAqE;IACrE,IAAI,OAAO,0BAA0B,KAAK,QAAQ,IAAI,0BAA0B,KAAK,IAAI,EAAE,CAAC;QAC1F,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAI,0BAAsD,CAAC,OAAO,CAAC,CAAC;IACjF,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,GAAuB;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,OAAO,OAAO,KAAK,EAAE,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,OAAyB,EAAE,eAAuB;IAC/E,MAAM,OAAO,GAAG,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC;IAC1F,OAAO,GAAG,OAAO,IAAI,OAAO,MAAM,cAAc,GAAG,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAyB,EACzB,eAAuB;IAEvB,OAAO,EAAE,YAAY,EAAE,cAAc,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC;AACpE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thenewlabs/entangle-utils",
3
- "version": "2.11.2",
3
+ "version": "2.11.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -20,7 +20,7 @@
20
20
  "prepublishOnly": "npm run build"
21
21
  },
22
22
  "dependencies": {
23
- "@thenewlabs/entangle-protocol": "^2.11.0",
23
+ "@thenewlabs/entangle-protocol": "^2.12.0",
24
24
  "dotenv": "^17.4.2",
25
25
  "pino": "^10.3.1"
26
26
  },