@elizaos/core 1.5.4 → 1.5.5

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 (90) hide show
  1. package/README.md +0 -15
  2. package/dist/index.d.ts +4886 -3
  3. package/dist/index.js +5287 -4
  4. package/package.json +21 -39
  5. package/dist/browser/index.browser.js +0 -1109
  6. package/dist/browser/index.browser.js.map +0 -707
  7. package/dist/browser/index.d.ts +0 -3
  8. package/dist/node/index.d.ts +0 -3
  9. package/dist/node/index.node.js +0 -74530
  10. package/dist/node/index.node.js.map +0 -1027
  11. package/src/__tests__/action-chaining-simple.test.ts +0 -203
  12. package/src/__tests__/actions.test.ts +0 -218
  13. package/src/__tests__/buffer.test.ts +0 -337
  14. package/src/__tests__/character-validation.test.ts +0 -309
  15. package/src/__tests__/database.test.ts +0 -750
  16. package/src/__tests__/entities.test.ts +0 -727
  17. package/src/__tests__/env.test.ts +0 -23
  18. package/src/__tests__/environment.test.ts +0 -285
  19. package/src/__tests__/logger-browser-node.test.ts +0 -716
  20. package/src/__tests__/logger.test.ts +0 -403
  21. package/src/__tests__/messages.test.ts +0 -196
  22. package/src/__tests__/mockCharacter.ts +0 -544
  23. package/src/__tests__/parsing.test.ts +0 -58
  24. package/src/__tests__/prompts.test.ts +0 -159
  25. package/src/__tests__/roles.test.ts +0 -331
  26. package/src/__tests__/runtime-embedding.test.ts +0 -343
  27. package/src/__tests__/runtime.test.ts +0 -978
  28. package/src/__tests__/search.test.ts +0 -15
  29. package/src/__tests__/services-by-type.test.ts +0 -204
  30. package/src/__tests__/services.test.ts +0 -136
  31. package/src/__tests__/settings.test.ts +0 -810
  32. package/src/__tests__/utils.test.ts +0 -1105
  33. package/src/__tests__/uuid.test.ts +0 -94
  34. package/src/actions.ts +0 -122
  35. package/src/database.ts +0 -579
  36. package/src/entities.ts +0 -406
  37. package/src/index.browser.ts +0 -48
  38. package/src/index.node.ts +0 -39
  39. package/src/index.ts +0 -50
  40. package/src/logger.ts +0 -527
  41. package/src/prompts.ts +0 -243
  42. package/src/roles.ts +0 -85
  43. package/src/runtime.ts +0 -2514
  44. package/src/schemas/character.ts +0 -149
  45. package/src/search.ts +0 -1543
  46. package/src/sentry/instrument.browser.ts +0 -65
  47. package/src/sentry/instrument.node.ts +0 -57
  48. package/src/sentry/instrument.ts +0 -82
  49. package/src/services.ts +0 -105
  50. package/src/settings.ts +0 -409
  51. package/src/test_resources/constants.ts +0 -12
  52. package/src/test_resources/testSetup.ts +0 -21
  53. package/src/test_resources/types.ts +0 -22
  54. package/src/types/agent.ts +0 -112
  55. package/src/types/browser.ts +0 -145
  56. package/src/types/components.ts +0 -184
  57. package/src/types/database.ts +0 -348
  58. package/src/types/email.ts +0 -162
  59. package/src/types/environment.ts +0 -129
  60. package/src/types/events.ts +0 -249
  61. package/src/types/index.ts +0 -29
  62. package/src/types/knowledge.ts +0 -65
  63. package/src/types/lp.ts +0 -124
  64. package/src/types/memory.ts +0 -228
  65. package/src/types/message.ts +0 -233
  66. package/src/types/messaging.ts +0 -57
  67. package/src/types/model.ts +0 -359
  68. package/src/types/pdf.ts +0 -77
  69. package/src/types/plugin.ts +0 -78
  70. package/src/types/post.ts +0 -271
  71. package/src/types/primitives.ts +0 -97
  72. package/src/types/runtime.ts +0 -190
  73. package/src/types/service.ts +0 -198
  74. package/src/types/settings.ts +0 -30
  75. package/src/types/state.ts +0 -60
  76. package/src/types/task.ts +0 -72
  77. package/src/types/tee.ts +0 -107
  78. package/src/types/testing.ts +0 -30
  79. package/src/types/token.ts +0 -96
  80. package/src/types/transcription.ts +0 -133
  81. package/src/types/video.ts +0 -108
  82. package/src/types/wallet.ts +0 -56
  83. package/src/types/web-search.ts +0 -146
  84. package/src/utils/__tests__/buffer.test.ts +0 -80
  85. package/src/utils/__tests__/environment.test.ts +0 -58
  86. package/src/utils/__tests__/stringToUuid.test.ts +0 -88
  87. package/src/utils/buffer.ts +0 -312
  88. package/src/utils/environment.ts +0 -316
  89. package/src/utils/server-health.ts +0 -117
  90. package/src/utils.ts +0 -1076
@@ -1,133 +0,0 @@
1
- import { Service, ServiceType } from './service';
2
-
3
- export interface TranscriptionOptions {
4
- language?: string;
5
- model?: string;
6
- temperature?: number;
7
- prompt?: string;
8
- response_format?: 'json' | 'text' | 'srt' | 'vtt' | 'verbose_json';
9
- timestamp_granularities?: ('word' | 'segment')[];
10
- word_timestamps?: boolean;
11
- segment_timestamps?: boolean;
12
- }
13
-
14
- export interface TranscriptionResult {
15
- text: string;
16
- language?: string;
17
- duration?: number;
18
- segments?: TranscriptionSegment[];
19
- words?: TranscriptionWord[];
20
- confidence?: number;
21
- }
22
-
23
- export interface TranscriptionSegment {
24
- id: number;
25
- text: string;
26
- start: number;
27
- end: number;
28
- confidence?: number;
29
- tokens?: number[];
30
- temperature?: number;
31
- avg_logprob?: number;
32
- compression_ratio?: number;
33
- no_speech_prob?: number;
34
- }
35
-
36
- export interface TranscriptionWord {
37
- word: string;
38
- start: number;
39
- end: number;
40
- confidence?: number;
41
- }
42
-
43
- export interface SpeechToTextOptions {
44
- language?: string;
45
- model?: string;
46
- continuous?: boolean;
47
- interimResults?: boolean;
48
- maxAlternatives?: number;
49
- }
50
-
51
- export interface TextToSpeechOptions {
52
- voice?: string;
53
- model?: string;
54
- speed?: number;
55
- format?: 'mp3' | 'wav' | 'flac' | 'aac';
56
- response_format?: 'mp3' | 'opus' | 'aac' | 'flac';
57
- }
58
-
59
- /**
60
- * Interface for audio transcription and speech services
61
- */
62
- export abstract class ITranscriptionService extends Service {
63
- static override readonly serviceType = ServiceType.TRANSCRIPTION;
64
-
65
- public readonly capabilityDescription = 'Audio transcription and speech processing capabilities';
66
-
67
- /**
68
- * Transcribe audio file to text
69
- * @param audioPath - Path to audio file or audio buffer
70
- * @param options - Transcription options
71
- * @returns Promise resolving to transcription result
72
- */
73
- abstract transcribeAudio(
74
- audioPath: string | Buffer,
75
- options?: TranscriptionOptions
76
- ): Promise<TranscriptionResult>;
77
-
78
- /**
79
- * Transcribe video file to text (extracts audio first)
80
- * @param videoPath - Path to video file or video buffer
81
- * @param options - Transcription options
82
- * @returns Promise resolving to transcription result
83
- */
84
- abstract transcribeVideo(
85
- videoPath: string | Buffer,
86
- options?: TranscriptionOptions
87
- ): Promise<TranscriptionResult>;
88
-
89
- /**
90
- * Real-time speech to text from audio stream
91
- * @param audioStream - Audio stream or buffer
92
- * @param options - Speech to text options
93
- * @returns Promise resolving to transcription result
94
- */
95
- abstract speechToText(
96
- audioStream: NodeJS.ReadableStream | Buffer,
97
- options?: SpeechToTextOptions
98
- ): Promise<TranscriptionResult>;
99
-
100
- /**
101
- * Convert text to speech
102
- * @param text - Text to convert to speech
103
- * @param options - Text to speech options
104
- * @returns Promise resolving to audio buffer
105
- */
106
- abstract textToSpeech(text: string, options?: TextToSpeechOptions): Promise<Buffer>;
107
-
108
- /**
109
- * Get supported languages for transcription
110
- * @returns Promise resolving to array of supported language codes
111
- */
112
- abstract getSupportedLanguages(): Promise<string[]>;
113
-
114
- /**
115
- * Get available voices for text to speech
116
- * @returns Promise resolving to array of available voices
117
- */
118
- abstract getAvailableVoices(): Promise<
119
- Array<{
120
- id: string;
121
- name: string;
122
- language: string;
123
- gender?: 'male' | 'female' | 'neutral';
124
- }>
125
- >;
126
-
127
- /**
128
- * Detect language of audio file
129
- * @param audioPath - Path to audio file or audio buffer
130
- * @returns Promise resolving to detected language code
131
- */
132
- abstract detectLanguage(audioPath: string | Buffer): Promise<string>;
133
- }
@@ -1,108 +0,0 @@
1
- import { Service, ServiceType } from './service';
2
-
3
- export interface VideoInfo {
4
- title?: string;
5
- duration?: number;
6
- url: string;
7
- thumbnail?: string;
8
- description?: string;
9
- uploader?: string;
10
- viewCount?: number;
11
- uploadDate?: Date;
12
- formats?: VideoFormat[];
13
- }
14
-
15
- export interface VideoFormat {
16
- formatId: string;
17
- url: string;
18
- extension: string;
19
- quality: string;
20
- fileSize?: number;
21
- videoCodec?: string;
22
- audioCodec?: string;
23
- resolution?: string;
24
- fps?: number;
25
- bitrate?: number;
26
- }
27
-
28
- export interface VideoDownloadOptions {
29
- format?: string;
30
- quality?: 'best' | 'worst' | 'bestvideo' | 'bestaudio' | string;
31
- outputPath?: string;
32
- audioOnly?: boolean;
33
- videoOnly?: boolean;
34
- subtitles?: boolean;
35
- embedSubs?: boolean;
36
- writeInfoJson?: boolean;
37
- }
38
-
39
- export interface VideoProcessingOptions {
40
- startTime?: number;
41
- endTime?: number;
42
- outputFormat?: string;
43
- resolution?: string;
44
- bitrate?: string;
45
- framerate?: number;
46
- audioCodec?: string;
47
- videoCodec?: string;
48
- }
49
-
50
- /**
51
- * Interface for video processing and download services
52
- */
53
- export abstract class IVideoService extends Service {
54
- static override readonly serviceType = ServiceType.VIDEO;
55
-
56
- public readonly capabilityDescription = 'Video download, processing, and conversion capabilities';
57
-
58
- /**
59
- * Get video information without downloading
60
- * @param url - Video URL
61
- * @returns Promise resolving to video information
62
- */
63
- abstract getVideoInfo(url: string): Promise<VideoInfo>;
64
-
65
- /**
66
- * Download a video from URL
67
- * @param url - Video URL
68
- * @param options - Download options
69
- * @returns Promise resolving to downloaded file path
70
- */
71
- abstract downloadVideo(url: string, options?: VideoDownloadOptions): Promise<string>;
72
-
73
- /**
74
- * Extract audio from video
75
- * @param videoPath - Path to video file or video URL
76
- * @param outputPath - Optional output path for audio file
77
- * @returns Promise resolving to audio file path
78
- */
79
- abstract extractAudio(videoPath: string, outputPath?: string): Promise<string>;
80
-
81
- /**
82
- * Generate thumbnail from video
83
- * @param videoPath - Path to video file or video URL
84
- * @param timestamp - Timestamp in seconds to capture thumbnail
85
- * @returns Promise resolving to thumbnail image path
86
- */
87
- abstract getThumbnail(videoPath: string, timestamp?: number): Promise<string>;
88
-
89
- /**
90
- * Convert video to different format
91
- * @param videoPath - Path to input video file
92
- * @param outputPath - Path for output video file
93
- * @param options - Processing options
94
- * @returns Promise resolving to converted video path
95
- */
96
- abstract convertVideo(
97
- videoPath: string,
98
- outputPath: string,
99
- options?: VideoProcessingOptions
100
- ): Promise<string>;
101
-
102
- /**
103
- * Get available formats for a video URL
104
- * @param url - Video URL
105
- * @returns Promise resolving to available formats
106
- */
107
- abstract getAvailableFormats(url: string): Promise<VideoFormat[]>;
108
- }
@@ -1,56 +0,0 @@
1
- import { Service, ServiceType } from './service';
2
- import type { TokenBalance } from './token';
3
-
4
- /**
5
- * Represents a single asset holding within a wallet, including its value.
6
- * This extends a generic TokenBalance with wallet-specific valuation.
7
- */
8
- export interface WalletAsset extends TokenBalance {
9
- priceUsd?: number;
10
- valueUsd?: number;
11
- }
12
-
13
- /**
14
- * Represents the entire portfolio of assets in a wallet.
15
- */
16
- export interface WalletPortfolio {
17
- totalValueUsd: number;
18
- assets: WalletAsset[];
19
- }
20
-
21
- /**
22
- * Abstract interface for a Wallet Service.
23
- * Plugins that provide wallet functionality (e.g., for Solana, EVM) should implement this service.
24
- * It provides a standardized way for other plugins to query the state of a wallet.
25
- */
26
- export abstract class IWalletService extends Service {
27
- static override readonly serviceType = ServiceType.WALLET;
28
-
29
- public readonly capabilityDescription =
30
- 'Provides standardized access to wallet balances and portfolios.';
31
-
32
- /**
33
- * Retrieves the entire portfolio of assets held by the wallet.
34
- * @param owner - Optional: The specific wallet address/owner to query if the service manages multiple.
35
- * @returns A promise that resolves to the wallet's portfolio.
36
- */
37
- abstract getPortfolio(owner?: string): Promise<WalletPortfolio>;
38
-
39
- /**
40
- * Retrieves the balance of a specific asset in the wallet.
41
- * @param assetAddress - The mint address or native identifier of the asset.
42
- * @param owner - Optional: The specific wallet address/owner to query.
43
- * @returns A promise that resolves to the user-friendly (decimal-adjusted) balance of the asset held.
44
- */
45
- abstract getBalance(assetAddress: string, owner?: string): Promise<number>;
46
-
47
- /**
48
- * Transfers SOL from a specified keypair to a given public key.
49
- * This is a low-level function primarily for Solana-based wallet services.
50
- * @param from - The Keypair of the sender.
51
- * @param to - The PublicKey of the recipient.
52
- * @param lamports - The amount in lamports to transfer.
53
- * @returns A promise that resolves with the transaction signature.
54
- */
55
- abstract transferSol(from: any, to: any, lamports: number): Promise<string>;
56
- }
@@ -1,146 +0,0 @@
1
- import { Service, ServiceType } from './service';
2
-
3
- export interface SearchOptions {
4
- limit?: number;
5
- offset?: number;
6
- language?: string;
7
- region?: string;
8
- dateRange?: {
9
- start?: Date;
10
- end?: Date;
11
- };
12
- fileType?: string;
13
- site?: string;
14
- sortBy?: 'relevance' | 'date' | 'popularity';
15
- safeSearch?: 'strict' | 'moderate' | 'off';
16
- }
17
-
18
- export interface SearchResult {
19
- title: string;
20
- url: string;
21
- description: string;
22
- displayUrl?: string;
23
- thumbnail?: string;
24
- publishedDate?: Date;
25
- source?: string;
26
- relevanceScore?: number;
27
- snippet?: string;
28
- }
29
-
30
- export interface SearchResponse {
31
- query: string;
32
- results: SearchResult[];
33
- totalResults?: number;
34
- searchTime?: number;
35
- suggestions?: string[];
36
- nextPageToken?: string;
37
- relatedSearches?: string[];
38
- }
39
-
40
- export interface NewsSearchOptions extends SearchOptions {
41
- category?:
42
- | 'general'
43
- | 'business'
44
- | 'entertainment'
45
- | 'health'
46
- | 'science'
47
- | 'sports'
48
- | 'technology';
49
- freshness?: 'day' | 'week' | 'month';
50
- }
51
-
52
- export interface ImageSearchOptions extends SearchOptions {
53
- size?: 'small' | 'medium' | 'large' | 'wallpaper' | 'any';
54
- color?:
55
- | 'color'
56
- | 'monochrome'
57
- | 'red'
58
- | 'orange'
59
- | 'yellow'
60
- | 'green'
61
- | 'blue'
62
- | 'purple'
63
- | 'pink'
64
- | 'brown'
65
- | 'black'
66
- | 'gray'
67
- | 'white';
68
- type?: 'photo' | 'clipart' | 'line' | 'animated';
69
- layout?: 'square' | 'wide' | 'tall' | 'any';
70
- license?: 'any' | 'public' | 'share' | 'sharecommercially' | 'modify';
71
- }
72
-
73
- export interface VideoSearchOptions extends SearchOptions {
74
- duration?: 'short' | 'medium' | 'long' | 'any';
75
- resolution?: 'high' | 'standard' | 'any';
76
- quality?: 'high' | 'standard' | 'any';
77
- }
78
-
79
- /**
80
- * Interface for web search services
81
- */
82
- export abstract class IWebSearchService extends Service {
83
- static override readonly serviceType = ServiceType.WEB_SEARCH;
84
-
85
- public readonly capabilityDescription = 'Web search and content discovery capabilities';
86
-
87
- /**
88
- * Perform a general web search
89
- * @param query - Search query
90
- * @param options - Search options
91
- * @returns Promise resolving to search results
92
- */
93
- abstract search(query: string, options?: SearchOptions): Promise<SearchResponse>;
94
-
95
- /**
96
- * Search for news articles
97
- * @param query - Search query
98
- * @param options - News search options
99
- * @returns Promise resolving to news search results
100
- */
101
- abstract searchNews(query: string, options?: NewsSearchOptions): Promise<SearchResponse>;
102
-
103
- /**
104
- * Search for images
105
- * @param query - Search query
106
- * @param options - Image search options
107
- * @returns Promise resolving to image search results
108
- */
109
- abstract searchImages(query: string, options?: ImageSearchOptions): Promise<SearchResponse>;
110
-
111
- /**
112
- * Search for videos
113
- * @param query - Search query
114
- * @param options - Video search options
115
- * @returns Promise resolving to video search results
116
- */
117
- abstract searchVideos(query: string, options?: VideoSearchOptions): Promise<SearchResponse>;
118
-
119
- /**
120
- * Get search suggestions for a query
121
- * @param query - Partial search query
122
- * @returns Promise resolving to array of suggestions
123
- */
124
- abstract getSuggestions(query: string): Promise<string[]>;
125
-
126
- /**
127
- * Get trending searches
128
- * @param region - Optional region code
129
- * @returns Promise resolving to trending search queries
130
- */
131
- abstract getTrendingSearches(region?: string): Promise<string[]>;
132
-
133
- /**
134
- * Get detailed information about a specific URL
135
- * @param url - URL to analyze
136
- * @returns Promise resolving to page information
137
- */
138
- abstract getPageInfo(url: string): Promise<{
139
- title: string;
140
- description: string;
141
- content: string;
142
- metadata: Record<string, string>;
143
- images: string[];
144
- links: string[];
145
- }>;
146
- }
@@ -1,80 +0,0 @@
1
- import { describe, it, expect } from 'bun:test';
2
- import {
3
- fromHex,
4
- toHex,
5
- fromString,
6
- toString,
7
- fromBytes,
8
- alloc,
9
- concat,
10
- slice,
11
- equals,
12
- isBuffer,
13
- byteLength,
14
- randomBytes,
15
- } from '../buffer';
16
-
17
- describe('buffer utils', () => {
18
- it('converts hex <-> buffer', () => {
19
- const hex = 'deadbeef01ff';
20
- const buf = fromHex(hex);
21
- expect(byteLength(buf)).toBe(6);
22
- expect(toHex(buf)).toBe(hex);
23
- });
24
-
25
- it('converts string utf8 <-> buffer', () => {
26
- const str = 'Hello, 世界';
27
- const buf = fromString(str, 'utf8');
28
- const out = toString(buf, 'utf8');
29
- expect(out).toBe(str);
30
- });
31
-
32
- it('converts string base64 <-> buffer', () => {
33
- const str = 'hello-base64';
34
- const b64 = 'aGVsbG8tYmFzZTY0';
35
- const bufFromB64 = fromString(b64, 'base64');
36
- expect(toString(bufFromB64, 'utf8')).toBe(str);
37
-
38
- const bufFromStr = fromString(str, 'utf8');
39
- expect(toString(bufFromStr, 'base64')).toBe(b64);
40
- });
41
-
42
- it('creates from bytes and allocates', () => {
43
- const bytes = [1, 2, 3, 4];
44
- const buf = fromBytes(bytes);
45
- expect(byteLength(buf)).toBe(4);
46
- expect(toHex(buf)).toBe('01020304');
47
-
48
- const zero = alloc(3);
49
- expect(byteLength(zero)).toBe(3);
50
- // All zeros
51
- expect(toHex(zero)).toBe('000000');
52
- });
53
-
54
- it('concatenates and slices buffers', () => {
55
- const a = fromHex('aa');
56
- const b = fromHex('bbcc');
57
- const c = concat([a, b]);
58
- expect(toHex(c)).toBe('aabbcc');
59
-
60
- const s = slice(c, 1, 3);
61
- expect(toHex(s)).toBe('bbcc');
62
- });
63
-
64
- it('checks equality and buffer detection', () => {
65
- const a = fromHex('0a0b0c');
66
- const b = fromHex('0a0b0c');
67
- const c = fromHex('0a0b0d');
68
- expect(equals(a, b)).toBe(true);
69
- expect(equals(a, c)).toBe(false);
70
-
71
- expect(isBuffer(a)).toBe(true);
72
- expect(isBuffer(new Uint8Array([1, 2, 3]))).toBe(true);
73
- expect(isBuffer({})).toBe(false);
74
- });
75
-
76
- it('generates random bytes with correct length', () => {
77
- const r = randomBytes(16);
78
- expect(byteLength(r)).toBe(16);
79
- });
80
- });
@@ -1,58 +0,0 @@
1
- import { describe, it, expect } from 'bun:test';
2
- import {
3
- detectEnvironment,
4
- getEnvironment,
5
- getEnv,
6
- setEnv,
7
- hasEnv,
8
- getBooleanEnv,
9
- getNumberEnv,
10
- initBrowserEnvironment,
11
- } from '../environment';
12
-
13
- describe('environment utils', () => {
14
- it('detects runtime (node in tests)', () => {
15
- const runtime = detectEnvironment();
16
- expect(['node', 'browser', 'unknown']).toContain(runtime);
17
- });
18
-
19
- it('gets and sets env vars via API', () => {
20
- const key = 'TEST_ENV_UTILS_KEY';
21
- setEnv(key, 'value1');
22
- expect(getEnv(key)).toBe('value1');
23
- expect(hasEnv(key)).toBe(true);
24
- });
25
-
26
- it('boolean env parsing works', () => {
27
- const key = 'TEST_BOOL_ENV';
28
- setEnv(key, 'true');
29
- expect(getBooleanEnv(key, false)).toBe(true);
30
- setEnv(key, '0');
31
- expect(getBooleanEnv(key, true)).toBe(false);
32
- });
33
-
34
- it('number env parsing works', () => {
35
- const key = 'TEST_NUM_ENV';
36
- setEnv(key, '42');
37
- expect(getNumberEnv(key)).toBe(42);
38
- setEnv(key, 'NaN');
39
- expect(getNumberEnv(key, 7)).toBe(7);
40
- });
41
-
42
- it('browser init helper is safe in node', () => {
43
- // Should not throw even though we are not in browser
44
- initBrowserEnvironment({ SOME_KEY: 'x' });
45
- expect(true).toBe(true);
46
- });
47
-
48
- it('environment cache can be cleared indirectly by creating a new instance', () => {
49
- const env = getEnvironment();
50
- // Access a key, then change it, ensure fresh read gets latest
51
- const key = 'TEST_CACHE_KEY';
52
- setEnv(key, 'a');
53
- expect(getEnv(key)).toBe('a');
54
- setEnv(key, 'b');
55
- // getEnv reads through the singleton which clears cache on set
56
- expect(getEnv(key)).toBe('b');
57
- });
58
- });
@@ -1,88 +0,0 @@
1
- import { describe, it, expect } from 'bun:test';
2
- import { stringToUuid } from '../../utils';
3
- import type { UUID } from '../../types';
4
-
5
- describe('stringToUuid SHA-1 implementation', () => {
6
- // Test vectors to ensure deterministic output
7
- // These are the actual SHA-1 based outputs for consistency
8
- const testVectors = [
9
- { input: 'test', expected: 'a94a8fe5-ccb1-0ba6-9c4c-0873d391e987' },
10
- { input: 'hello world', expected: 'f0355dd5-2823-054c-ae66-a0b12842c215' },
11
- { input: '', expected: 'da39a3ee-5e6b-0b0d-b255-bfef95601890' },
12
- { input: '123', expected: '40bd0015-6308-0fc3-9165-329ea1ff5c5e' },
13
- { input: 'user:agent', expected: 'a49810ce-da30-0d3b-97ee-d4d47774d8af' },
14
- ];
15
-
16
- it('should produce deterministic UUIDs for known inputs', () => {
17
- testVectors.forEach(({ input, expected }) => {
18
- const result = stringToUuid(input);
19
- expect(result).toBe(expected);
20
- });
21
- });
22
-
23
- it('should handle UTF-8 strings correctly', () => {
24
- // Generate actual values for unicode tests
25
- const unicodeTests = [
26
- { input: 'Hello 世界', expected: stringToUuid('Hello 世界') },
27
- { input: '🌍🌎🌏', expected: stringToUuid('🌍🌎🌏') },
28
- { input: 'Café', expected: stringToUuid('Café') },
29
- ];
30
-
31
- unicodeTests.forEach(({ input, expected }) => {
32
- const result = stringToUuid(input);
33
- expect(result).toBe(expected);
34
- });
35
- });
36
-
37
- it('should return existing UUIDs unchanged', () => {
38
- const existingUuid = '550e8400-e29b-41d4-a716-446655440000' as UUID;
39
- const result = stringToUuid(existingUuid);
40
- expect(result).toBe(existingUuid);
41
- });
42
-
43
- it('should handle URL-unsafe characters consistently', () => {
44
- const urlTests = [
45
- { input: 'test?query=value&param=123', expected: stringToUuid('test?query=value&param=123') },
46
- { input: 'path/to/resource#anchor', expected: stringToUuid('path/to/resource#anchor') },
47
- ];
48
-
49
- urlTests.forEach(({ input, expected }) => {
50
- const result = stringToUuid(input);
51
- expect(result).toBe(expected);
52
- });
53
- });
54
-
55
- it('should handle numbers correctly', () => {
56
- expect(stringToUuid(42)).toBe(stringToUuid('42'));
57
- expect(stringToUuid(0)).toBe(stringToUuid('0'));
58
- expect(stringToUuid(-1)).toBe(stringToUuid('-1'));
59
- });
60
-
61
- it('should throw for invalid inputs', () => {
62
- expect(() => stringToUuid(null as any)).toThrow(TypeError);
63
- expect(() => stringToUuid(undefined as any)).toThrow(TypeError);
64
- expect(() => stringToUuid({} as any)).toThrow(TypeError);
65
- expect(() => stringToUuid([] as any)).toThrow(TypeError);
66
- });
67
-
68
- it('should set correct UUID format bits', () => {
69
- const uuid = stringToUuid('test');
70
- // Check format
71
- expect(uuid).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
72
-
73
- // Check variant bits (should be 10xxxxxx in the 9th byte)
74
- const parts = uuid.split('-');
75
- const variantByte = parseInt(parts[3].substring(0, 2), 16);
76
- expect(variantByte & 0xc0).toBe(0x80); // 10xxxxxx pattern
77
-
78
- // Check version nibble (should be 0 for custom)
79
- const versionNibble = parseInt(parts[2][0], 16);
80
- expect(versionNibble).toBe(0);
81
- });
82
-
83
- it('should handle long inputs without errors', () => {
84
- const longInput = 'a'.repeat(10000);
85
- const result = stringToUuid(longInput);
86
- expect(result).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
87
- });
88
- });