@frontmcp/utils 0.12.2 → 1.0.0-beta.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.
Files changed (48) hide show
  1. package/async-context/browser-async-context.d.ts +12 -0
  2. package/async-context/browser-async-context.js +49 -0
  3. package/async-context/index.d.ts +1 -0
  4. package/async-context/node-async-context.d.ts +1 -0
  5. package/async-context/node-async-context.js +30 -0
  6. package/crypto/browser.d.ts +16 -0
  7. package/crypto/browser.js +160 -0
  8. package/crypto/index.d.ts +15 -6
  9. package/crypto/jwt-alg.d.ts +5 -0
  10. package/crypto/key-persistence/factory.d.ts +8 -1
  11. package/crypto/key-persistence/types.d.ts +10 -2
  12. package/crypto/node.d.ts +2 -0
  13. package/crypto/node.js +185 -0
  14. package/env/browser-env.d.ts +17 -0
  15. package/env/browser-env.js +78 -0
  16. package/env/index.d.ts +1 -0
  17. package/env/node-env.d.ts +14 -0
  18. package/env/node-env.js +85 -0
  19. package/esm/async-context/browser-async-context.mjs +24 -0
  20. package/esm/async-context/node-async-context.mjs +5 -0
  21. package/esm/crypto/browser.mjs +131 -0
  22. package/esm/crypto/node.mjs +143 -0
  23. package/esm/env/browser-env.mjs +44 -0
  24. package/esm/env/node-env.mjs +51 -0
  25. package/esm/event-emitter/browser-event-emitter.mjs +49 -0
  26. package/esm/event-emitter/node-event-emitter.mjs +5 -0
  27. package/esm/index.mjs +3887 -3064
  28. package/event-emitter/browser-event-emitter.d.ts +19 -0
  29. package/event-emitter/browser-event-emitter.js +74 -0
  30. package/event-emitter/index.d.ts +1 -0
  31. package/event-emitter/node-event-emitter.d.ts +1 -0
  32. package/event-emitter/node-event-emitter.js +30 -0
  33. package/index.d.ts +14 -5
  34. package/index.js +4144 -3314
  35. package/llm/index.d.ts +2 -0
  36. package/llm/llm-tool-handler.types.d.ts +48 -0
  37. package/llm/llm-tool-handlers.d.ts +10 -0
  38. package/naming/index.d.ts +2 -1
  39. package/package.json +23 -1
  40. package/path/browser-path.d.ts +5 -0
  41. package/path/index.d.ts +1 -0
  42. package/path/node-path.d.ts +1 -0
  43. package/storage/adapters/index.d.ts +4 -0
  44. package/storage/adapters/indexeddb.d.ts +77 -0
  45. package/storage/adapters/localstorage.d.ts +84 -0
  46. package/storage/index.d.ts +2 -2
  47. package/uri/index.d.ts +2 -1
  48. package/esm/package.json +0 -69
package/llm/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { processPlatformToolCalls } from './llm-tool-handlers';
2
+ export type { CallToolFn, OpenAIToolCallItem, OpenAIToolResponse, ClaudeToolUseBlock, ClaudeToolResultBlock, VercelToolCallInfo, PlatformToolCallsInput, PlatformToolCallsOutput, SupportedPlatform, } from './llm-tool-handler.types';
@@ -0,0 +1,48 @@
1
+ /**
2
+ * LLM platform tool call types.
3
+ *
4
+ * Defines the input/output shapes for processing tool calls across
5
+ * different AI SDK platforms (OpenAI, Claude, Vercel AI).
6
+ */
7
+ /** Generic function signature for executing an MCP tool. */
8
+ export type CallToolFn = (name: string, args?: Record<string, unknown>) => Promise<unknown>;
9
+ export interface OpenAIToolCallItem {
10
+ id: string;
11
+ type: 'function';
12
+ function: {
13
+ name: string;
14
+ arguments: string;
15
+ };
16
+ }
17
+ export interface ClaudeToolUseBlock {
18
+ type: 'tool_use';
19
+ id: string;
20
+ name: string;
21
+ input: Record<string, unknown>;
22
+ }
23
+ export interface VercelToolCallInfo {
24
+ toolCallId: string;
25
+ toolName: string;
26
+ args: unknown;
27
+ }
28
+ export interface OpenAIToolResponse {
29
+ role: 'tool';
30
+ tool_call_id: string;
31
+ content: string;
32
+ }
33
+ export interface ClaudeToolResultBlock {
34
+ type: 'tool_result';
35
+ tool_use_id: string;
36
+ content: string;
37
+ }
38
+ export type PlatformToolCallsInput = {
39
+ openai: OpenAIToolCallItem[];
40
+ claude: ClaudeToolUseBlock[];
41
+ 'vercel-ai': VercelToolCallInfo;
42
+ };
43
+ export type PlatformToolCallsOutput = {
44
+ openai: OpenAIToolResponse[];
45
+ claude: ClaudeToolResultBlock[];
46
+ 'vercel-ai': unknown;
47
+ };
48
+ export type SupportedPlatform = keyof PlatformToolCallsInput;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * processPlatformToolCalls — generic handler that processes LLM tool calls
3
+ * for any supported platform and returns platform-appropriate responses.
4
+ *
5
+ * Usable from both React hooks and Node.js backends.
6
+ */
7
+ import type { CallToolFn, OpenAIToolCallItem, OpenAIToolResponse, ClaudeToolUseBlock, ClaudeToolResultBlock, VercelToolCallInfo } from './llm-tool-handler.types';
8
+ export declare function processPlatformToolCalls(platform: 'openai', calls: OpenAIToolCallItem[], callTool: CallToolFn): Promise<OpenAIToolResponse[]>;
9
+ export declare function processPlatformToolCalls(platform: 'claude', calls: ClaudeToolUseBlock[], callTool: CallToolFn): Promise<ClaudeToolResultBlock[]>;
10
+ export declare function processPlatformToolCalls(platform: 'vercel-ai', calls: VercelToolCallInfo, callTool: CallToolFn): Promise<unknown>;
package/naming/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { NameCase, splitWords, toCase, sepFor, shortHash, ensureMaxLen, idFromString } from './naming';
1
+ export { splitWords, toCase, sepFor, shortHash, ensureMaxLen, idFromString } from './naming';
2
+ export type { NameCase } from './naming';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/utils",
3
- "version": "0.12.2",
3
+ "version": "1.0.0-beta.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",
@@ -44,6 +44,28 @@
44
44
  "optional": true
45
45
  }
46
46
  },
47
+ "imports": {
48
+ "#crypto-provider": {
49
+ "browser": "./crypto/browser.js",
50
+ "default": "./crypto/node.js"
51
+ },
52
+ "#async-context": {
53
+ "browser": "./async-context/browser-async-context.js",
54
+ "default": "./async-context/node-async-context.js"
55
+ },
56
+ "#event-emitter": {
57
+ "browser": "./event-emitter/browser-event-emitter.js",
58
+ "default": "./event-emitter/node-event-emitter.js"
59
+ },
60
+ "#env": {
61
+ "browser": "./env/browser-env.js",
62
+ "default": "./env/node-env.js"
63
+ },
64
+ "#path": {
65
+ "browser": "./path/browser-path.js",
66
+ "default": "./path/node-path.js"
67
+ }
68
+ },
47
69
  "type": "commonjs",
48
70
  "main": "./index.js",
49
71
  "module": "./esm/index.mjs",
@@ -0,0 +1,5 @@
1
+ export declare function resolve(..._segments: string[]): string;
2
+ export declare function join(..._segments: string[]): string;
3
+ export declare function basename(p: string, ext?: string): string;
4
+ export declare function dirname(_p: string): string;
5
+ export declare function extname(p: string): string;
package/path/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { trimSlashes, joinPath } from './path';
2
+ export { resolve as pathResolve, join as pathJoin, basename, dirname, extname } from '#path';
@@ -0,0 +1 @@
1
+ export { resolve, join, basename, dirname, extname } from 'path';
@@ -10,3 +10,7 @@ export { VercelKvStorageAdapter } from './vercel-kv';
10
10
  export { UpstashStorageAdapter } from './upstash';
11
11
  export { FileSystemStorageAdapter } from './filesystem';
12
12
  export type { FileSystemAdapterOptions } from './filesystem';
13
+ export { LocalStorageAdapter } from './localstorage';
14
+ export type { LocalStorageAdapterOptions } from './localstorage';
15
+ export { IndexedDBStorageAdapter } from './indexeddb';
16
+ export type { IndexedDBAdapterOptions } from './indexeddb';
@@ -0,0 +1,77 @@
1
+ /**
2
+ * IndexedDB Storage Adapter
3
+ *
4
+ * Browser-compatible storage using the IndexedDB API.
5
+ * Persistent, supports larger data than localStorage (~50MB+ per origin).
6
+ *
7
+ * Suitable for key persistence in browser environments where
8
+ * larger storage capacity is needed.
9
+ */
10
+ import { BaseStorageAdapter } from './base';
11
+ import type { SetOptions } from '../types';
12
+ /**
13
+ * Options for the IndexedDB adapter.
14
+ */
15
+ export interface IndexedDBAdapterOptions {
16
+ /**
17
+ * Database name.
18
+ * @default 'frontmcp'
19
+ */
20
+ dbName?: string;
21
+ /**
22
+ * Object store name.
23
+ * @default 'kv'
24
+ */
25
+ storeName?: string;
26
+ /**
27
+ * Key prefix for namespacing.
28
+ * @default 'frontmcp:'
29
+ */
30
+ prefix?: string;
31
+ }
32
+ /**
33
+ * Browser IndexedDB-based storage adapter.
34
+ *
35
+ * Features:
36
+ * - Persistent across page reloads and browser restarts
37
+ * - Asynchronous API matching StorageAdapter contract
38
+ * - TTL support via stored expiration timestamps
39
+ * - Larger storage limit than localStorage (~50MB+)
40
+ *
41
+ * Limitations:
42
+ * - No pub/sub support
43
+ * - Browser-only (requires globalThis.indexedDB)
44
+ * - Pattern matching uses simple iteration over all keys
45
+ */
46
+ export declare class IndexedDBStorageAdapter extends BaseStorageAdapter {
47
+ protected readonly backendName = "indexeddb";
48
+ private readonly dbName;
49
+ private readonly storeName;
50
+ private readonly prefix;
51
+ private db;
52
+ constructor(options?: IndexedDBAdapterOptions);
53
+ private assertAvailable;
54
+ private key;
55
+ private stripPrefix;
56
+ connect(): Promise<void>;
57
+ disconnect(): Promise<void>;
58
+ ping(): Promise<boolean>;
59
+ private getStore;
60
+ private idbRequest;
61
+ private idbTransaction;
62
+ get(key: string): Promise<string | null>;
63
+ protected doSet(key: string, value: string, options?: SetOptions): Promise<void>;
64
+ delete(key: string): Promise<boolean>;
65
+ exists(key: string): Promise<boolean>;
66
+ expire(key: string, ttlSeconds: number): Promise<boolean>;
67
+ ttl(key: string): Promise<number | null>;
68
+ keys(pattern?: string): Promise<string[]>;
69
+ incr(key: string): Promise<number>;
70
+ decr(key: string): Promise<number>;
71
+ /**
72
+ * Increment by amount. NOT atomic — uses read-then-write which can race
73
+ * under concurrent access (e.g., multiple browser tabs).
74
+ */
75
+ incrBy(key: string, amount: number): Promise<number>;
76
+ private matchPattern;
77
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * LocalStorage Storage Adapter
3
+ *
4
+ * Browser-compatible storage using the Web Storage API (localStorage).
5
+ * Persistent across page reloads but limited to ~5MB per origin.
6
+ *
7
+ * Supports optional AES-256-GCM at-rest encryption when an encryption key
8
+ * is provided, preventing clear-text storage of sensitive values.
9
+ */
10
+ import { BaseStorageAdapter } from './base';
11
+ import type { SetOptions, MessageHandler, Unsubscribe } from '../types';
12
+ /**
13
+ * Options for the LocalStorage adapter.
14
+ */
15
+ export interface LocalStorageAdapterOptions {
16
+ /**
17
+ * Key prefix for namespacing.
18
+ * @default 'frontmcp:'
19
+ */
20
+ prefix?: string;
21
+ /**
22
+ * Optional 32-byte AES-256-GCM encryption key.
23
+ * When provided, all values are encrypted at rest in localStorage.
24
+ */
25
+ encryptionKey?: Uint8Array;
26
+ /**
27
+ * Whether to allow plaintext storage when no encryption key is provided.
28
+ * @default true
29
+ */
30
+ allowPlaintext?: boolean;
31
+ }
32
+ /**
33
+ * Browser localStorage-based storage adapter.
34
+ *
35
+ * Features:
36
+ * - Persistent across page reloads
37
+ * - Synchronous underlying API (async interface for consistency)
38
+ * - TTL support via stored expiration timestamps
39
+ * - Size-limited (~5MB per origin)
40
+ *
41
+ * Limitations:
42
+ * - No pub/sub support
43
+ * - incr/decr/incrBy are non-atomic (read-then-write); do not assume atomicity under concurrent access
44
+ * - String-only values (matches StorageAdapter contract)
45
+ * - Pattern matching uses simple iteration
46
+ */
47
+ export declare class LocalStorageAdapter extends BaseStorageAdapter {
48
+ protected readonly backendName = "localstorage";
49
+ private readonly prefix;
50
+ private readonly encryptionKey;
51
+ private readonly allowPlaintext;
52
+ private readonly encoder;
53
+ private readonly decoder;
54
+ constructor(options?: LocalStorageAdapterOptions);
55
+ private assertAvailable;
56
+ private key;
57
+ private stripPrefix;
58
+ connect(): Promise<void>;
59
+ disconnect(): Promise<void>;
60
+ ping(): Promise<boolean>;
61
+ get(key: string): Promise<string | null>;
62
+ set(key: string, value: string, options?: SetOptions): Promise<void>;
63
+ protected doSet(key: string, value: string, options?: SetOptions): Promise<void>;
64
+ delete(key: string): Promise<boolean>;
65
+ exists(key: string): Promise<boolean>;
66
+ mget(keys: string[]): Promise<(string | null)[]>;
67
+ mset(entries: {
68
+ key: string;
69
+ value: string;
70
+ options?: SetOptions;
71
+ }[]): Promise<void>;
72
+ mdelete(keys: string[]): Promise<number>;
73
+ expire(key: string, ttlSeconds: number): Promise<boolean>;
74
+ ttl(key: string): Promise<number | null>;
75
+ keys(pattern?: string): Promise<string[]>;
76
+ count(pattern?: string): Promise<number>;
77
+ incr(key: string): Promise<number>;
78
+ decr(key: string): Promise<number>;
79
+ incrBy(key: string, amount: number): Promise<number>;
80
+ publish(): Promise<number>;
81
+ subscribe(_channel: string, _handler: MessageHandler): Promise<Unsubscribe>;
82
+ supportsPubSub(): boolean;
83
+ private matchPattern;
84
+ }
@@ -12,7 +12,7 @@ export { TypedStorage } from './typed-storage';
12
12
  export type { TypedStorageOptions, TypedSetOptions, TypedSetEntry } from './typed-storage.types';
13
13
  export { EncryptedTypedStorage } from './encrypted-typed-storage';
14
14
  export type { EncryptedTypedStorageOptions, EncryptedSetOptions, EncryptedSetEntry, EncryptionKey, StoredEncryptedBlob, ClientKeyBinding, } from './encrypted-typed-storage.types';
15
- export { BaseStorageAdapter, MemoryStorageAdapter, RedisStorageAdapter, VercelKvStorageAdapter, UpstashStorageAdapter, FileSystemStorageAdapter, } from './adapters';
16
- export type { FileSystemAdapterOptions } from './adapters';
15
+ export { BaseStorageAdapter, MemoryStorageAdapter, RedisStorageAdapter, VercelKvStorageAdapter, UpstashStorageAdapter, FileSystemStorageAdapter, LocalStorageAdapter, IndexedDBStorageAdapter, } from './adapters';
16
+ export type { FileSystemAdapterOptions, LocalStorageAdapterOptions, IndexedDBAdapterOptions } from './adapters';
17
17
  export { globToRegex, matchesPattern, validatePattern, escapeGlob } from './utils/pattern';
18
18
  export { MAX_TTL_SECONDS, validateTTL, validateOptionalTTL, ttlToExpiresAt, expiresAtToTTL, isExpired, normalizeTTL, } from './utils/ttl';
package/uri/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { isValidMcpUri, extractUriScheme, isValidMcpUriTemplate } from './uri-validation';
2
- export { ParsedUriTemplate, parseUriTemplate, matchUriTemplate, expandUriTemplate, extractTemplateParams, isUriTemplate, } from './uri-template';
2
+ export { parseUriTemplate, matchUriTemplate, expandUriTemplate, extractTemplateParams, isUriTemplate, } from './uri-template';
3
+ export type { ParsedUriTemplate } from './uri-template';
package/esm/package.json DELETED
@@ -1,69 +0,0 @@
1
- {
2
- "name": "@frontmcp/utils",
3
- "version": "0.12.2",
4
- "description": "Shared utility functions for FrontMCP - string manipulation, URI handling, path utilities, and more",
5
- "author": "AgentFront <info@agentfront.dev>",
6
- "license": "Apache-2.0",
7
- "keywords": [
8
- "utils",
9
- "utilities",
10
- "uri",
11
- "url",
12
- "string",
13
- "path",
14
- "typescript",
15
- "mcp"
16
- ],
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/agentfront/frontmcp.git",
20
- "directory": "libs/utils"
21
- },
22
- "bugs": {
23
- "url": "https://github.com/agentfront/frontmcp/issues"
24
- },
25
- "homepage": "https://github.com/agentfront/frontmcp/blob/main/libs/utils/README.md",
26
- "engines": {
27
- "node": ">=22.0.0"
28
- },
29
- "dependencies": {
30
- "@noble/hashes": "^2.0.1",
31
- "@noble/ciphers": "^2.1.1",
32
- "@enclave-vm/ast": "^2.11.1",
33
- "zod": "^4.0.0"
34
- },
35
- "peerDependencies": {
36
- "@vercel/kv": "^2.0.0 || ^3.0.0",
37
- "ioredis": "^5.0.0"
38
- },
39
- "peerDependenciesMeta": {
40
- "@vercel/kv": {
41
- "optional": true
42
- },
43
- "ioredis": {
44
- "optional": true
45
- }
46
- },
47
- "type": "module",
48
- "main": "../index.js",
49
- "module": "./index.mjs",
50
- "types": "../index.d.ts",
51
- "sideEffects": false,
52
- "exports": {
53
- "./package.json": "../package.json",
54
- ".": {
55
- "require": {
56
- "types": "../index.d.ts",
57
- "default": "../index.js"
58
- },
59
- "import": {
60
- "types": "../index.d.ts",
61
- "default": "./index.mjs"
62
- }
63
- }
64
- },
65
- "devDependencies": {
66
- "@types/node": "^24.0.0",
67
- "typescript": "^5.0.0"
68
- }
69
- }