@gitsense/gsc-utils 0.2.24 → 0.2.27
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 +380 -62
- package/dist/gsc-utils.cjs.js +14270 -523
- package/dist/gsc-utils.esm.js +14270 -523
- package/package.json +1 -1
- package/src/AnalyzerUtils/cloner.js +149 -0
- package/src/AnalyzerUtils/constants.js +1 -1
- package/src/AnalyzerUtils/defaultPromptLoader.js +10 -10
- package/src/AnalyzerUtils/discovery.js +48 -39
- package/src/AnalyzerUtils/index.js +13 -7
- package/src/AnalyzerUtils/instructionLoader.js +6 -6
- package/src/AnalyzerUtils/jsonParser.js +35 -0
- package/src/AnalyzerUtils/management.js +6 -6
- package/src/AnalyzerUtils/saver.js +5 -5
- package/src/AnalyzerUtils/schemaLoader.js +194 -26
- package/src/AnalyzerUtils/updater.js +187 -0
- package/src/CodeBlockUtils/blockProcessor.js +14 -32
- package/src/CodeBlockUtils/constants.js +8 -4
- package/src/CodeBlockUtils/headerUtils.js +19 -3
- package/src/CodeBlockUtils/index.js +7 -6
- package/src/CodeBlockUtils/lineageTracer.js +95 -0
- package/src/CompactChatUtils/CompactedMessageUtils.js +224 -0
- package/src/CompactChatUtils/README.md +321 -0
- package/src/CompactChatUtils/ReferenceMessageUtils.js +143 -0
- package/src/CompactChatUtils/index.js +40 -0
- package/src/ContextUtils.js +41 -5
- package/src/DomUtils.js +559 -0
- package/src/GSToolBlockUtils.js +66 -1
- package/src/GitSenseChatUtils.js +108 -16
- package/src/LanguageNameUtils.js +171 -0
- package/src/MarkdownUtils.js +127 -0
- package/src/MessageUtils.js +1 -1
- package/src/MetaRawResultUtils.js +244 -0
- package/src/ObjectUtils.js +54 -0
- package/src/PatchUtils/constants.js +9 -3
- package/src/PatchUtils/patchParser.js +60 -37
- package/src/PatchUtils/patchProcessor.js +8 -5
- package/src/PatchUtils/patchVerifier/detectAndFixOverlappingHunks.js +1 -1
- package/src/SVGUtils.js +1467 -0
- package/src/SharedUtils/stringUtils.js +303 -0
- package/src/CodeBlockUtils/blockProcessor.js.rej +0 -8
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Component: CodeBlockUtils Header Utilities
|
|
3
3
|
* Block-UUID: 2565f708-feec-4b59-88fd-984084410fd4
|
|
4
4
|
* Parent-UUID: 01147ddf-320f-498a-a744-198d42a9d2ee
|
|
5
|
-
* Version: 1.2.
|
|
5
|
+
* Version: 1.2.1
|
|
6
6
|
* Description: Provides utility functions for parsing metadata headers from code blocks, validating timestamps, and calculating header line counts.
|
|
7
7
|
* Language: JavaScript
|
|
8
8
|
* Created-at: 2025-07-21T00:23:28.169Z
|
|
9
|
-
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Flash Thinking (v1.1.0), Gemini 2.5 Flash Thinking (v1.2.0)
|
|
9
|
+
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Flash Thinking (v1.1.0), Gemini 2.5 Flash Thinking (v1.2.0), Qwen 3 Coder 480B - Cerebras (v1.2.1)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -113,6 +113,22 @@ function parseHeader(header, language) {
|
|
|
113
113
|
.map(line => line.replace(/^\s*'\s?/, ''))
|
|
114
114
|
.join('\n');
|
|
115
115
|
break;
|
|
116
|
+
|
|
117
|
+
// --- New Case for HTML/XML/Markdown Comments ---
|
|
118
|
+
case 'html':
|
|
119
|
+
// Remove opening <!-- and closing --> tags.
|
|
120
|
+
// The regex handles cases where the tags might be on the same line as content
|
|
121
|
+
// or on their own lines.
|
|
122
|
+
cleanHeader = header.replace(/^<!--\s*/, '')
|
|
123
|
+
.replace(/\s*-->$/, '')
|
|
124
|
+
.split('\n')
|
|
125
|
+
// Remove leading whitespace and potential dashes (common in HTML comments)
|
|
126
|
+
// This is a heuristic, as HTML comments don't typically have line prefixes.
|
|
127
|
+
// It's included to be robust against minor formatting variations.
|
|
128
|
+
.map(line => line.replace(/^\s*(-|\*)\s?/, ''))
|
|
129
|
+
.join('\n');
|
|
130
|
+
break;
|
|
131
|
+
// --- End of New Case ---
|
|
116
132
|
|
|
117
133
|
case 'unknown':
|
|
118
134
|
// Attempt basic detection if language wasn't found in COMMENT_STYLES
|
|
@@ -170,7 +186,7 @@ function parseHeader(header, language) {
|
|
|
170
186
|
const requiredFields = [
|
|
171
187
|
'Component',
|
|
172
188
|
'Block-UUID',
|
|
173
|
-
'Version',
|
|
189
|
+
'Version',
|
|
174
190
|
'Language',
|
|
175
191
|
'Created-at',
|
|
176
192
|
'Authors'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Component: CodeBlockUtils Index
|
|
3
|
-
* Block-UUID:
|
|
4
|
-
* Parent-UUID:
|
|
5
|
-
* Version: 1.
|
|
3
|
+
* Block-UUID: 98684aa5-d597-41b6-a7fd-cc16482aafdc
|
|
4
|
+
* Parent-UUID: 7e9d3f8a-1b2c-4d5e-8f9a-0123456789ab
|
|
5
|
+
* Version: 1.5.0
|
|
6
6
|
* Description: Aggregates and exports all utilities related to code block processing from the CodeBlockUtils module. Serves as the main entry point for this module.
|
|
7
7
|
* Language: JavaScript
|
|
8
8
|
* Created-at: 2025-04-15T16:02:20.217Z
|
|
9
|
-
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Claude 3.7 Sonnet (v1.2.0), Gemini 2.5 Pro (v1.3.0), Gemini 2.5 Flash Thinking (v1.4.0)
|
|
9
|
+
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Claude 3.7 Sonnet (v1.2.0), Gemini 2.5 Pro (v1.3.0), Gemini 2.5 Flash Thinking (v1.4.0), Qwen 3 Coder 480B - Cerebras (v1.5.0)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
|
|
@@ -23,6 +23,7 @@ const { parseCodeBlocks: parseCommentDelimitedBlocks } = require('./headerParser
|
|
|
23
23
|
const { removeCodeBlockMarkers } = require('./markerRemover');
|
|
24
24
|
const { updateCodeBlockByIndex, updateCodeBlockByUUID, updateCodeBlock, updateCodeBlockInMessage, deleteCodeBlockByIndex } = require('./updateCodeBlock');
|
|
25
25
|
const { formatWithLineNumbers, formatBlockWithLineNumbers, formatBlocksWithLineNumbers, removeLineNumbers } = require('./lineNumberFormatter');
|
|
26
|
+
const { getLineage } = require('./lineageTracer');
|
|
26
27
|
|
|
27
28
|
// Export all imported items
|
|
28
29
|
module.exports = {
|
|
@@ -77,7 +78,7 @@ module.exports = {
|
|
|
77
78
|
// Line Number Formatting Utilities
|
|
78
79
|
formatWithLineNumbers,
|
|
79
80
|
formatBlockWithLineNumbers,
|
|
80
|
-
formatBlocksWithLineNumbers,
|
|
81
|
+
formatBlocksWithLineNumbers,
|
|
82
|
+
getLineage,
|
|
81
83
|
removeLineNumbers,
|
|
82
84
|
};
|
|
83
|
-
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: CodeBlockUtils Lineage Tracer
|
|
3
|
+
* Block-UUID: 13b08cce-6fd1-4ec9-a915-240714ee89b9
|
|
4
|
+
* Parent-UUID: df1a629b-2cc0-4677-b410-3172ee0e0f9f
|
|
5
|
+
* Version: 1.1.0
|
|
6
|
+
* Description: Provides a utility function to trace the full lineage (patch-based and parent-based) of code blocks within a chat, including loop detection.
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-10-23T01:28:10.456Z
|
|
9
|
+
* Authors: Qwen 3 Coder 480B - Cerebras (v1.0.0), Qwen 3 Coder 480B - Cerebras (v1.1.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Traces the full lineage of a code block or patch identified by a UUID.
|
|
15
|
+
* The lineage includes the block itself and all its ancestors, tracing backwards
|
|
16
|
+
* first through patch relationships (Source-Block-UUID -> Target-Block-UUID)
|
|
17
|
+
* and then through Parent-UUID relationships.
|
|
18
|
+
* Loop detection is included to prevent infinite tracing.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} uuid - The UUID of the target code block or patch.
|
|
21
|
+
* @param {Map<string, object>} blockMap - A map where keys are UUIDs (for code blocks)
|
|
22
|
+
* or patch UUIDs (source:target) and values
|
|
23
|
+
* are the corresponding block objects.
|
|
24
|
+
* Block objects are expected to have
|
|
25
|
+
* properties like `isPatch`, `metadata`, and `header`.
|
|
26
|
+
* @returns {Array<object>} An array of block objects representing the lineage.
|
|
27
|
+
* The first element is the block for the provided `uuid`.
|
|
28
|
+
* Subsequent elements are its ancestors.
|
|
29
|
+
* Returns an empty array if the initial uuid is not found.
|
|
30
|
+
* If a loop is detected, the last element will have a property `loopDetected: true`.
|
|
31
|
+
*/
|
|
32
|
+
function getLineage(uuid, blockMap) {
|
|
33
|
+
if (!uuid || !blockMap) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const lineage = [];
|
|
38
|
+
const visitedUuids = new Set();
|
|
39
|
+
let currentUuid = uuid;
|
|
40
|
+
|
|
41
|
+
while (currentUuid) {
|
|
42
|
+
// --- Loop Detection ---
|
|
43
|
+
if (visitedUuids.has(currentUuid)) {
|
|
44
|
+
// Add a marker or the block itself to indicate the loop
|
|
45
|
+
const loopBlock = blockMap.get(currentUuid) || { uuid: currentUuid, loopDetected: true, type: 'loop-marker' };
|
|
46
|
+
loopBlock.loopDetected = true; // Ensure the property is set
|
|
47
|
+
lineage.push(loopBlock);
|
|
48
|
+
break; // Stop the trace
|
|
49
|
+
}
|
|
50
|
+
visitedUuids.add(currentUuid);
|
|
51
|
+
|
|
52
|
+
// --- 1. Try to find the block directly by its UUID ---
|
|
53
|
+
let block = blockMap.get(currentUuid);
|
|
54
|
+
|
|
55
|
+
// --- 2. If not found directly, search patch keys ---
|
|
56
|
+
if (!block) {
|
|
57
|
+
for (const [key, value] of blockMap) {
|
|
58
|
+
// Check if the map key is a patch key (contains ':') and ends with our target UUID
|
|
59
|
+
if (key.includes(':') && key.endsWith(`:${currentUuid}`)) {
|
|
60
|
+
block = value;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// --- 3. If a block was found, add it to the lineage ---
|
|
67
|
+
if (block) {
|
|
68
|
+
lineage.push(block);
|
|
69
|
+
|
|
70
|
+
let nextUuid = null;
|
|
71
|
+
|
|
72
|
+
// --- 3a. If it's a patch, move to its source UUID ---
|
|
73
|
+
if (block.isPatch && block.metadata && block.metadata['Source-Block-UUID']) {
|
|
74
|
+
nextUuid = block.metadata['Source-Block-UUID'];
|
|
75
|
+
}
|
|
76
|
+
// --- 3b. If it's a code block, move to its Parent-UUID (if valid) ---
|
|
77
|
+
else if (!block.isPatch && block.header && block.header['Parent-UUID'] && block.header['Parent-UUID'] !== 'N/A') {
|
|
78
|
+
nextUuid = block.header['Parent-UUID'];
|
|
79
|
+
}
|
|
80
|
+
// If it's a code block with Parent-UUID: 0c104865-260a-4942-8cb6-93bebf40c450
|
|
81
|
+
|
|
82
|
+
currentUuid = nextUuid;
|
|
83
|
+
} else {
|
|
84
|
+
// If no block is found for currentUuid, the lineage is incomplete.
|
|
85
|
+
// We could add a placeholder here if needed, but for now, we just stop.
|
|
86
|
+
currentUuid = null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return lineage;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = {
|
|
94
|
+
getLineage
|
|
95
|
+
};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component: CompactedMessageUtils
|
|
3
|
+
* Block-UUID: b4111118-ec11-49d6-9a6e-402ca0b6df5b
|
|
4
|
+
* Parent-UUID: N/A
|
|
5
|
+
* Version: 1.0.1
|
|
6
|
+
* Description: Utility for formatting, parsing, and validating compacted messages with standardized metadata headers.
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-12-07T00:09:15.842Z
|
|
9
|
+
* Authors: GLM-4.6 (v1.0.0), GLM-4.6 (v1.0.1)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CompactedMessageUtils {
|
|
14
|
+
/**
|
|
15
|
+
* Formats a compacted message with standardized metadata headers
|
|
16
|
+
* @param {string} content - The compacted message content
|
|
17
|
+
* @param {string} originalChatUuid - UUID of the original chat
|
|
18
|
+
* @param {string} messageRange - Message range that was compacted (e.g., "3-6")
|
|
19
|
+
* @param {Object} options - Additional options
|
|
20
|
+
* @param {Date} options.compactedAt - Custom timestamp for when the message was compacted
|
|
21
|
+
* @returns {string} Formatted compacted message with metadata
|
|
22
|
+
*/
|
|
23
|
+
static formatCompactedMessage(content, originalChatUuid, messageRange, options = {}) {
|
|
24
|
+
if (!content) {
|
|
25
|
+
throw new Error('Content is required for formatting a compacted message');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!originalChatUuid) {
|
|
29
|
+
throw new Error('Original chat UUID is required for formatting a compacted message');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!messageRange) {
|
|
33
|
+
throw new Error('Message range is required for formatting a compacted message');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Use provided timestamp or generate current one
|
|
37
|
+
const compactedAt = options.compactedAt || new Date().toISOString();
|
|
38
|
+
|
|
39
|
+
return `## Compacted Message
|
|
40
|
+
|
|
41
|
+
- **Original Chat:** [${originalChatUuid}](/?chat=${originalChatUuid})
|
|
42
|
+
- **Message Range:** ${messageRange}
|
|
43
|
+
- **Compacted At:** ${compactedAt}
|
|
44
|
+
|
|
45
|
+
${content}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Extracts metadata from a compacted message
|
|
50
|
+
* @param {string} compactedMessage - The compacted message to parse
|
|
51
|
+
* @returns {Object|null} Metadata object or null if format is invalid
|
|
52
|
+
*/
|
|
53
|
+
static extractCompactedMessageMetadata(compactedMessage) {
|
|
54
|
+
if (!this.isCompactedMessage(compactedMessage)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Extract Original Chat UUID
|
|
59
|
+
const originalChatMatch = compactedMessage.match(/\*\*Original Chat:\*\*\s*([a-f0-9-]+)/i);
|
|
60
|
+
const originalChatUuid = originalChatMatch ? originalChatMatch[1] : null;
|
|
61
|
+
|
|
62
|
+
// Extract Message Range
|
|
63
|
+
const rangeMatch = compactedMessage.match(/\*\*Message Range:\*\*\s*(\d+-\d+)/i);
|
|
64
|
+
const messageRange = rangeMatch ? rangeMatch[1] : null;
|
|
65
|
+
|
|
66
|
+
// Extract Compacted At timestamp
|
|
67
|
+
const compactedAtMatch = compactedMessage.match(/\*\*Compacted At:\*\*\s*([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z)/i);
|
|
68
|
+
const compactedAt = compactedAtMatch ? compactedAtMatch[1] : null;
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
originalChatUuid,
|
|
72
|
+
messageRange,
|
|
73
|
+
compactedAt
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Extracts just the content portion from a compacted message (without metadata)
|
|
79
|
+
* @param {string} compactedMessage - The compacted message to parse
|
|
80
|
+
* @returns {string|null} Content portion or null if format is invalid
|
|
81
|
+
*/
|
|
82
|
+
static extractCompactedMessageContent(compactedMessage) {
|
|
83
|
+
if (!this.isCompactedMessage(compactedMessage)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Find the start and end boundaries
|
|
88
|
+
const startMarker = "## Compacted Message";
|
|
89
|
+
const endMarker = "## End Compacted Message";
|
|
90
|
+
|
|
91
|
+
const startIndex = compactedMessage.indexOf(startMarker);
|
|
92
|
+
const endIndex = compactedMessage.indexOf(endMarker);
|
|
93
|
+
|
|
94
|
+
// If start marker is not found, return null
|
|
95
|
+
if (startIndex === -1) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// If end marker is not found, extract everything after start marker
|
|
100
|
+
if (endIndex === -1) {
|
|
101
|
+
return compactedMessage.substring(startIndex + startMarker.length).trim();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Extract content between the markers
|
|
105
|
+
const contentStart = startIndex + startMarker.length;
|
|
106
|
+
return compactedMessage.substring(contentStart, endIndex).trim();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Validates that a compacted message follows the expected format
|
|
111
|
+
* @param {string} compactedMessage - The compacted message to validate
|
|
112
|
+
* @returns {Object} Validation result with isValid flag and any errors/warnings
|
|
113
|
+
*/
|
|
114
|
+
static validateCompactedMessageFormat(compactedMessage) {
|
|
115
|
+
const result = {
|
|
116
|
+
isValid: true,
|
|
117
|
+
errors: [],
|
|
118
|
+
warnings: []
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (!compactedMessage) {
|
|
122
|
+
result.isValid = false;
|
|
123
|
+
result.errors.push('Compacted message is empty or null');
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Check for required header
|
|
128
|
+
if (!compactedMessage.includes('## Compacted Message')) {
|
|
129
|
+
result.isValid = false;
|
|
130
|
+
result.errors.push('Missing required "## Compacted Message" header');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Check for required metadata fields
|
|
134
|
+
const metadata = this.extractCompactedMessageMetadata(compactedMessage);
|
|
135
|
+
|
|
136
|
+
if (!metadata) {
|
|
137
|
+
result.isValid = false;
|
|
138
|
+
result.errors.push('Could not extract metadata from compacted message');
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!metadata.originalChatUuid) {
|
|
143
|
+
result.isValid = false;
|
|
144
|
+
result.errors.push('Missing or invalid Original Chat UUID');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (!metadata.messageRange) {
|
|
148
|
+
result.isValid = false;
|
|
149
|
+
result.errors.push('Missing or invalid Message Range');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!metadata.compactedAt) {
|
|
153
|
+
result.warnings.push('Missing or invalid Compacted At timestamp');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Validate UUID format
|
|
157
|
+
if (metadata.originalChatUuid && !this.isValidUUID(metadata.originalChatUuid)) {
|
|
158
|
+
result.isValid = false;
|
|
159
|
+
result.errors.push('Original Chat UUID is not in valid UUID format');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Validate message range format
|
|
163
|
+
if (metadata.messageRange && !this.isValidMessageRange(metadata.messageRange)) {
|
|
164
|
+
result.isValid = false;
|
|
165
|
+
result.errors.push('Message Range is not in valid format (expected "X-Y")');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Validate timestamp format
|
|
169
|
+
if (metadata.compactedAt && !this.isValidISOTimestamp(metadata.compactedAt)) {
|
|
170
|
+
result.warnings.push('Compacted At timestamp is not in valid ISO 8601 format');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Checks if a message is a compacted message
|
|
178
|
+
* @param {string} message - The message content to check
|
|
179
|
+
* @returns {boolean} True if the message is a compacted message
|
|
180
|
+
*/
|
|
181
|
+
static isCompactedMessage(message) {
|
|
182
|
+
if (!message) return false;
|
|
183
|
+
|
|
184
|
+
// Check for the compacted message header
|
|
185
|
+
return message.includes('## Compacted Message');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Validates if a string is a valid UUID v4
|
|
190
|
+
* @param {string} uuid - The UUID string to validate
|
|
191
|
+
* @returns {boolean} True if valid UUID v4
|
|
192
|
+
*/
|
|
193
|
+
static isValidUUID(uuid) {
|
|
194
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
195
|
+
return uuidRegex.test(uuid);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Validates if a string is a valid message range (e.g., "3-6")
|
|
200
|
+
* @param {string} range - The range string to validate
|
|
201
|
+
* @returns {boolean} True if valid range format
|
|
202
|
+
*/
|
|
203
|
+
static isValidMessageRange(range) {
|
|
204
|
+
const rangeRegex = /^\d+-\d+$/;
|
|
205
|
+
if (!rangeRegex.test(range)) return false;
|
|
206
|
+
|
|
207
|
+
const [from, to] = range.split('-').map(Number);
|
|
208
|
+
return !isNaN(from) && !isNaN(to) && from <= to;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Validates if a string is a valid ISO 8601 timestamp
|
|
213
|
+
* @param {string} timestamp - The timestamp string to validate
|
|
214
|
+
* @returns {boolean} True if valid ISO 8601 timestamp
|
|
215
|
+
*/
|
|
216
|
+
static isValidISOTimestamp(timestamp) {
|
|
217
|
+
if (!timestamp) return false;
|
|
218
|
+
|
|
219
|
+
const date = new Date(timestamp);
|
|
220
|
+
return !isNaN(date.getTime()) && timestamp === date.toISOString();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
module.exports = { CompactedMessageUtils };
|