@frontmcp/utils 0.8.0 → 0.9.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/README.md +24 -83
- package/esm/index.mjs +7 -2
- package/esm/package.json +2 -2
- package/index.js +9 -4
- package/package.json +2 -2
- package/regex/safe-regex.d.ts +1 -1
package/README.md
CHANGED
|
@@ -1,110 +1,51 @@
|
|
|
1
1
|
# @frontmcp/utils
|
|
2
2
|
|
|
3
|
-
Shared utility functions for the FrontMCP ecosystem.
|
|
3
|
+
Shared utility functions for the FrontMCP ecosystem.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@frontmcp/utils)
|
|
6
|
+
|
|
7
|
+
> **Internal package.** Used by `@frontmcp/sdk` and other `@frontmcp/*` libraries — most users do not need to install this directly.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
6
10
|
|
|
7
11
|
```bash
|
|
8
12
|
npm install @frontmcp/utils
|
|
9
|
-
# or
|
|
10
|
-
yarn add @frontmcp/utils
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
## Features
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import { splitWords, toCase, shortHash, ensureMaxLen, idFromString } from '@frontmcp/utils';
|
|
19
|
-
|
|
20
|
-
// Split strings into words (handles camelCase, PascalCase, delimiters)
|
|
21
|
-
splitWords('myFunctionName'); // ['my', 'Function', 'Name']
|
|
22
|
-
|
|
23
|
-
// Convert to different cases
|
|
24
|
-
toCase(['my', 'function'], 'snake'); // 'my_function'
|
|
25
|
-
toCase(['my', 'function'], 'kebab'); // 'my-function'
|
|
26
|
-
toCase(['my', 'function'], 'camel'); // 'myFunction'
|
|
17
|
+
**Naming** — `splitWords`, `toCase`, `shortHash`, `ensureMaxLen`, `idFromString` for string manipulation and case conversion
|
|
27
18
|
|
|
28
|
-
|
|
29
|
-
shortHash('some-string'); // '6-char hex hash'
|
|
19
|
+
**URI** — `isValidMcpUri`, `extractUriScheme`, `parseUriTemplate`, `matchUriTemplate`, `expandUriTemplate` (RFC 3986 / RFC 6570)
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
ensureMaxLen('very-long-name-that-exceeds-limit', 20);
|
|
21
|
+
**Path** — `trimSlashes`, `joinPath` for URL path operations
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
idFromString('My Function Name!'); // 'My-Function-Name'
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### URI Utilities
|
|
23
|
+
**Content** — `sanitizeToJson`, `inferMimeType` for safe serialization and MIME detection
|
|
39
24
|
|
|
40
|
-
|
|
41
|
-
import {
|
|
42
|
-
isValidMcpUri,
|
|
43
|
-
extractUriScheme,
|
|
44
|
-
parseUriTemplate,
|
|
45
|
-
matchUriTemplate,
|
|
46
|
-
expandUriTemplate,
|
|
47
|
-
} from '@frontmcp/utils';
|
|
25
|
+
**HTTP** — `validateBaseUrl` for URL validation and normalization
|
|
48
26
|
|
|
49
|
-
|
|
50
|
-
isValidMcpUri('https://example.com/resource'); // true
|
|
51
|
-
isValidMcpUri('/path/without/scheme'); // false
|
|
27
|
+
**Crypto** — `sha256`, `sha256Hex`, `sha256Base64url`, `hkdfSha256`, `encryptAesGcm`, `decryptAesGcm`, `randomBytes`, `randomUUID`, `generateCodeVerifier`, `generateCodeChallenge`, `generatePkcePair`, `base64urlEncode`, `base64urlDecode` for cross-platform cryptography
|
|
52
28
|
|
|
53
|
-
|
|
54
|
-
extractUriScheme('https://example.com'); // 'https'
|
|
29
|
+
**File system** — `readFile`, `writeFile`, `mkdir`, `stat`, `fileExists`, `readJSON`, `writeJSON`, `ensureDir`, `isDirEmpty`, `runCmd` and more — lazy-loaded for Node.js environments
|
|
55
30
|
|
|
56
|
-
|
|
57
|
-
const params = matchUriTemplate('users/{userId}/posts/{postId}', 'users/123/posts/456');
|
|
58
|
-
// { userId: '123', postId: '456' }
|
|
31
|
+
## Quick Example
|
|
59
32
|
|
|
60
|
-
|
|
61
|
-
|
|
33
|
+
```ts
|
|
34
|
+
import { matchUriTemplate, sha256Hex, fileExists } from '@frontmcp/utils';
|
|
62
35
|
|
|
63
|
-
|
|
36
|
+
const params = matchUriTemplate('users/{id}/posts/{postId}', 'users/123/posts/456');
|
|
37
|
+
// { id: '123', postId: '456' }
|
|
64
38
|
|
|
65
|
-
|
|
66
|
-
import { trimSlashes, joinPath } from '@frontmcp/utils';
|
|
39
|
+
const hash = sha256Hex('hello world');
|
|
67
40
|
|
|
68
|
-
|
|
69
|
-
joinPath('api', 'v1', 'users'); // '/api/v1/users'
|
|
41
|
+
const exists = await fileExists('/path/to/file');
|
|
70
42
|
```
|
|
71
43
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
import { sanitizeToJson, inferMimeType } from '@frontmcp/utils';
|
|
76
|
-
|
|
77
|
-
// Sanitize values to JSON-safe objects
|
|
78
|
-
sanitizeToJson({ date: new Date(), fn: () => {} }); // { date: '2024-01-01T00:00:00.000Z' }
|
|
44
|
+
## Related Packages
|
|
79
45
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
inferMimeType('image.png'); // 'image/png'
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### HTTP Utilities
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { validateBaseUrl } from '@frontmcp/utils';
|
|
89
|
-
|
|
90
|
-
// Validate and normalize URLs
|
|
91
|
-
const url = validateBaseUrl('https://api.example.com');
|
|
92
|
-
// Throws for invalid URLs or unsupported protocols (file://, javascript:)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### File System Utilities
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
import { fileExists, readJSON, writeJSON, ensureDir, isDirEmpty } from '@frontmcp/utils';
|
|
99
|
-
|
|
100
|
-
// Async file operations
|
|
101
|
-
await fileExists('/path/to/file');
|
|
102
|
-
await readJSON<Config>('/path/to/config.json');
|
|
103
|
-
await writeJSON('/path/to/output.json', { key: 'value' });
|
|
104
|
-
await ensureDir('/path/to/directory');
|
|
105
|
-
await isDirEmpty('/path/to/directory');
|
|
106
|
-
```
|
|
46
|
+
- [`@frontmcp/sdk`](../sdk) — core framework
|
|
47
|
+
- [`@frontmcp/auth`](../auth) — uses crypto utilities for PKCE, encryption
|
|
107
48
|
|
|
108
49
|
## License
|
|
109
50
|
|
|
110
|
-
Apache-2.0
|
|
51
|
+
Apache-2.0 — see [LICENSE](../../LICENSE).
|
package/esm/index.mjs
CHANGED
|
@@ -1435,7 +1435,7 @@ var init_upstash = __esm({
|
|
|
1435
1435
|
});
|
|
1436
1436
|
|
|
1437
1437
|
// libs/utils/src/regex/safe-regex.ts
|
|
1438
|
-
import { analyzeForReDoS, REDOS_THRESHOLDS } from "ast
|
|
1438
|
+
import { analyzeForReDoS, REDOS_THRESHOLDS } from "@enclave-vm/ast";
|
|
1439
1439
|
var DEFAULT_MAX_INPUT_LENGTH = 5e4;
|
|
1440
1440
|
function analyzePattern(pattern, level = "polynomial") {
|
|
1441
1441
|
const patternStr = typeof pattern === "string" ? pattern : pattern.source;
|
|
@@ -3492,7 +3492,12 @@ function base64urlEncode(data) {
|
|
|
3492
3492
|
const binString = Array.from(data, (byte) => String.fromCodePoint(byte)).join("");
|
|
3493
3493
|
base64 = btoa(binString);
|
|
3494
3494
|
}
|
|
3495
|
-
|
|
3495
|
+
const result = base64.replace(/\+/g, "-").replace(/\//g, "_");
|
|
3496
|
+
let end = result.length;
|
|
3497
|
+
while (end > 0 && result[end - 1] === "=") {
|
|
3498
|
+
end--;
|
|
3499
|
+
}
|
|
3500
|
+
return result.slice(0, end);
|
|
3496
3501
|
}
|
|
3497
3502
|
function base64urlDecode(data) {
|
|
3498
3503
|
let base64 = data.replace(/-/g, "+").replace(/_/g, "/");
|
package/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
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",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@noble/hashes": "^2.0.1",
|
|
31
31
|
"@noble/ciphers": "^2.1.1",
|
|
32
|
-
"ast
|
|
32
|
+
"@enclave-vm/ast": "^2.10.1",
|
|
33
33
|
"zod": "^4.0.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
package/index.js
CHANGED
|
@@ -1457,7 +1457,7 @@ __export(index_exports, {
|
|
|
1457
1457
|
NAMESPACE_SEPARATOR: () => NAMESPACE_SEPARATOR,
|
|
1458
1458
|
NamespacedStorageImpl: () => NamespacedStorageImpl,
|
|
1459
1459
|
PkceError: () => PkceError,
|
|
1460
|
-
REDOS_THRESHOLDS: () =>
|
|
1460
|
+
REDOS_THRESHOLDS: () => import_ast.REDOS_THRESHOLDS,
|
|
1461
1461
|
RedisStorageAdapter: () => RedisStorageAdapter,
|
|
1462
1462
|
StorageConfigError: () => StorageConfigError,
|
|
1463
1463
|
StorageConnectionError: () => StorageConnectionError,
|
|
@@ -1617,7 +1617,7 @@ __export(index_exports, {
|
|
|
1617
1617
|
module.exports = __toCommonJS(index_exports);
|
|
1618
1618
|
|
|
1619
1619
|
// libs/utils/src/regex/safe-regex.ts
|
|
1620
|
-
var
|
|
1620
|
+
var import_ast = require("@enclave-vm/ast");
|
|
1621
1621
|
var DEFAULT_MAX_INPUT_LENGTH = 5e4;
|
|
1622
1622
|
function analyzePattern(pattern, level = "polynomial") {
|
|
1623
1623
|
const patternStr = typeof pattern === "string" ? pattern : pattern.source;
|
|
@@ -1632,7 +1632,7 @@ function analyzePattern(pattern, level = "polynomial") {
|
|
|
1632
1632
|
};
|
|
1633
1633
|
}
|
|
1634
1634
|
try {
|
|
1635
|
-
const result = (0,
|
|
1635
|
+
const result = (0, import_ast.analyzeForReDoS)(patternStr, level);
|
|
1636
1636
|
return {
|
|
1637
1637
|
safe: !result.vulnerable,
|
|
1638
1638
|
score: result.score,
|
|
@@ -3674,7 +3674,12 @@ function base64urlEncode(data) {
|
|
|
3674
3674
|
const binString = Array.from(data, (byte) => String.fromCodePoint(byte)).join("");
|
|
3675
3675
|
base64 = btoa(binString);
|
|
3676
3676
|
}
|
|
3677
|
-
|
|
3677
|
+
const result = base64.replace(/\+/g, "-").replace(/\//g, "_");
|
|
3678
|
+
let end = result.length;
|
|
3679
|
+
while (end > 0 && result[end - 1] === "=") {
|
|
3680
|
+
end--;
|
|
3681
|
+
}
|
|
3682
|
+
return result.slice(0, end);
|
|
3678
3683
|
}
|
|
3679
3684
|
function base64urlDecode(data) {
|
|
3680
3685
|
let base64 = data.replace(/-/g, "+").replace(/_/g, "/");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
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",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@noble/hashes": "^2.0.1",
|
|
31
31
|
"@noble/ciphers": "^2.1.1",
|
|
32
|
-
"ast
|
|
32
|
+
"@enclave-vm/ast": "^2.10.1",
|
|
33
33
|
"zod": "^4.0.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
package/regex/safe-regex.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* These utilities protect against ReDoS (Regular Expression Denial of Service)
|
|
5
5
|
* attacks by validating patterns and enforcing input length limits.
|
|
6
6
|
*/
|
|
7
|
-
import { REDOS_THRESHOLDS } from 'ast
|
|
7
|
+
import { REDOS_THRESHOLDS } from '@enclave-vm/ast';
|
|
8
8
|
/**
|
|
9
9
|
* Default maximum input length for safe regex operations.
|
|
10
10
|
* Inputs longer than this will be rejected to prevent ReDoS attacks.
|