@frontmcp/utils 1.1.0 → 1.1.1

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.
@@ -27,6 +27,19 @@
27
27
  * // { key: 'value' }
28
28
  */
29
29
  export declare function sanitizeToJson(value: unknown): unknown;
30
+ /**
31
+ * Walk a JSON-like value and return the first non-finite number encountered
32
+ * (`Infinity`, `-Infinity`, or `NaN`), or `undefined` if all numbers are
33
+ * finite. Used by the SDK to reject tool/resource output that would silently
34
+ * be serialized as `null` by `JSON.stringify`.
35
+ *
36
+ * Cycles in the input tree are not expected (callers run sanitizeToJson
37
+ * first, which drops them) but we guard with a WeakSet anyway.
38
+ */
39
+ export declare function findNonFiniteNumber(value: unknown): {
40
+ path: string;
41
+ value: number;
42
+ } | undefined;
30
43
  /**
31
44
  * Infer MIME type from file extension or content.
32
45
  *
@@ -1 +1 @@
1
- export { sanitizeToJson, inferMimeType } from './content';
1
+ export { sanitizeToJson, inferMimeType, findNonFiniteNumber } from './content';
package/esm/index.mjs CHANGED
@@ -4147,6 +4147,31 @@ function sanitizeToJson(value) {
4147
4147
  }
4148
4148
  return sanitize(value);
4149
4149
  }
4150
+ function findNonFiniteNumber(value) {
4151
+ const seen = /* @__PURE__ */ new WeakSet();
4152
+ function walk(val, path) {
4153
+ if (typeof val === "number" && !Number.isFinite(val)) {
4154
+ return { path, value: val };
4155
+ }
4156
+ if (val && typeof val === "object") {
4157
+ if (seen.has(val)) return void 0;
4158
+ seen.add(val);
4159
+ if (Array.isArray(val)) {
4160
+ for (let i = 0; i < val.length; i++) {
4161
+ const found = walk(val[i], `${path}[${i}]`);
4162
+ if (found) return found;
4163
+ }
4164
+ return void 0;
4165
+ }
4166
+ for (const [k, v] of Object.entries(val)) {
4167
+ const found = walk(v, path ? `${path}.${k}` : k);
4168
+ if (found) return found;
4169
+ }
4170
+ }
4171
+ return void 0;
4172
+ }
4173
+ return walk(value, "");
4174
+ }
4150
4175
  var MIME_TYPES = {
4151
4176
  json: "application/json",
4152
4177
  xml: "application/xml",
@@ -5392,6 +5417,7 @@ export {
5392
5417
  extractTemplateParams,
5393
5418
  extractUriScheme,
5394
5419
  fileExists,
5420
+ findNonFiniteNumber,
5395
5421
  generateCodeChallenge,
5396
5422
  generateCodeVerifier,
5397
5423
  generatePkcePair,
package/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export type { NameCase } from './naming';
10
10
  export { isValidMcpUri, extractUriScheme, isValidMcpUriTemplate, parseUriTemplate, matchUriTemplate, expandUriTemplate, extractTemplateParams, isUriTemplate, } from './uri';
11
11
  export type { ParsedUriTemplate } from './uri';
12
12
  export { trimSlashes, joinPath, pathResolve, pathJoin, basename, dirname, extname } from './path';
13
- export { sanitizeToJson, inferMimeType } from './content';
13
+ export { sanitizeToJson, inferMimeType, findNonFiniteNumber } from './content';
14
14
  export { validateBaseUrl, buildSetCookie, parseCookies, getCookie, isLocalhost, isSecureRequest } from './http';
15
15
  export type { CookieOptions, SecureDetectionRequest } from './http';
16
16
  export { readFile, readFileSync, readFileBuffer, writeFile, mkdir, rename, unlink, stat, copyFile, cp, readdir, rm, mkdtemp, access, fileExists, readJSON, writeJSON, ensureDir, isDirEmpty, runCmd, } from './fs';
package/index.js CHANGED
@@ -3805,6 +3805,7 @@ __export(index_exports, {
3805
3805
  extractTemplateParams: () => extractTemplateParams,
3806
3806
  extractUriScheme: () => extractUriScheme,
3807
3807
  fileExists: () => fileExists,
3808
+ findNonFiniteNumber: () => findNonFiniteNumber,
3808
3809
  generateCodeChallenge: () => generateCodeChallenge,
3809
3810
  generateCodeVerifier: () => generateCodeVerifier,
3810
3811
  generatePkcePair: () => generatePkcePair,
@@ -4359,6 +4360,31 @@ function sanitizeToJson(value) {
4359
4360
  }
4360
4361
  return sanitize(value);
4361
4362
  }
4363
+ function findNonFiniteNumber(value) {
4364
+ const seen = /* @__PURE__ */ new WeakSet();
4365
+ function walk(val, path) {
4366
+ if (typeof val === "number" && !Number.isFinite(val)) {
4367
+ return { path, value: val };
4368
+ }
4369
+ if (val && typeof val === "object") {
4370
+ if (seen.has(val)) return void 0;
4371
+ seen.add(val);
4372
+ if (Array.isArray(val)) {
4373
+ for (let i = 0; i < val.length; i++) {
4374
+ const found = walk(val[i], `${path}[${i}]`);
4375
+ if (found) return found;
4376
+ }
4377
+ return void 0;
4378
+ }
4379
+ for (const [k, v] of Object.entries(val)) {
4380
+ const found = walk(v, path ? `${path}.${k}` : k);
4381
+ if (found) return found;
4382
+ }
4383
+ }
4384
+ return void 0;
4385
+ }
4386
+ return walk(value, "");
4387
+ }
4362
4388
  var MIME_TYPES = {
4363
4389
  json: "application/json",
4364
4390
  xml: "application/xml",
@@ -5594,6 +5620,7 @@ function setMachineIdOverride(id) {
5594
5620
  extractTemplateParams,
5595
5621
  extractUriScheme,
5596
5622
  fileExists,
5623
+ findNonFiniteNumber,
5597
5624
  generateCodeChallenge,
5598
5625
  generateCodeVerifier,
5599
5626
  generatePkcePair,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/utils",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Shared utility functions for FrontMCP - string manipulation, URI handling, path utilities, and more",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -34,7 +34,7 @@
34
34
  "peerDependencies": {
35
35
  "@vercel/kv": "^2.0.0 || ^3.0.0",
36
36
  "ioredis": "^5.0.0",
37
- "@frontmcp/lazy-zod": "1.1.0"
37
+ "@frontmcp/lazy-zod": "1.1.1"
38
38
  },
39
39
  "peerDependenciesMeta": {
40
40
  "@vercel/kv": {