@danielsimonjr/memory-mcp 0.48.0 → 9.8.2
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/LICENSE +22 -0
- package/README.md +2000 -194
- package/dist/__tests__/file-path.test.js +7 -11
- package/dist/__tests__/knowledge-graph.test.js +3 -8
- package/dist/core/EntityManager.d.ts +266 -0
- package/dist/core/EntityManager.d.ts.map +1 -0
- package/dist/core/EntityManager.js +89 -137
- package/dist/core/GraphEventEmitter.d.ts +202 -0
- package/dist/core/GraphEventEmitter.d.ts.map +1 -0
- package/dist/core/GraphEventEmitter.js +346 -0
- package/dist/core/GraphStorage.d.ts +395 -0
- package/dist/core/GraphStorage.d.ts.map +1 -0
- package/dist/core/GraphStorage.js +644 -31
- package/dist/core/GraphTraversal.d.ts +141 -0
- package/dist/core/GraphTraversal.d.ts.map +1 -0
- package/dist/core/GraphTraversal.js +573 -0
- package/dist/core/HierarchyManager.d.ts +111 -0
- package/dist/core/HierarchyManager.d.ts.map +1 -0
- package/dist/{features → core}/HierarchyManager.js +14 -9
- package/dist/core/ManagerContext.d.ts +72 -0
- package/dist/core/ManagerContext.d.ts.map +1 -0
- package/dist/core/ManagerContext.js +118 -0
- package/dist/core/ObservationManager.d.ts +85 -0
- package/dist/core/ObservationManager.d.ts.map +1 -0
- package/dist/core/ObservationManager.js +51 -57
- package/dist/core/RelationManager.d.ts +131 -0
- package/dist/core/RelationManager.d.ts.map +1 -0
- package/dist/core/RelationManager.js +31 -7
- package/dist/core/SQLiteStorage.d.ts +354 -0
- package/dist/core/SQLiteStorage.d.ts.map +1 -0
- package/dist/core/SQLiteStorage.js +918 -0
- package/dist/core/StorageFactory.d.ts +45 -0
- package/dist/core/StorageFactory.d.ts.map +1 -0
- package/dist/core/StorageFactory.js +64 -0
- package/dist/core/TransactionManager.d.ts +464 -0
- package/dist/core/TransactionManager.d.ts.map +1 -0
- package/dist/core/TransactionManager.js +493 -14
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +12 -2
- package/dist/features/AnalyticsManager.d.ts +44 -0
- package/dist/features/AnalyticsManager.d.ts.map +1 -0
- package/dist/features/AnalyticsManager.js +3 -2
- package/dist/features/ArchiveManager.d.ts +133 -0
- package/dist/features/ArchiveManager.d.ts.map +1 -0
- package/dist/features/ArchiveManager.js +221 -14
- package/dist/features/CompressionManager.d.ts +117 -0
- package/dist/features/CompressionManager.d.ts.map +1 -0
- package/dist/features/CompressionManager.js +189 -20
- package/dist/features/IOManager.d.ts +225 -0
- package/dist/features/IOManager.d.ts.map +1 -0
- package/dist/features/IOManager.js +1092 -0
- package/dist/features/StreamingExporter.d.ts +128 -0
- package/dist/features/StreamingExporter.d.ts.map +1 -0
- package/dist/features/StreamingExporter.js +211 -0
- package/dist/features/TagManager.d.ts +147 -0
- package/dist/features/TagManager.d.ts.map +1 -0
- package/dist/features/index.d.ts +12 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +5 -6
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -10
- package/dist/memory.jsonl +1 -26
- package/dist/search/BasicSearch.d.ts +51 -0
- package/dist/search/BasicSearch.d.ts.map +1 -0
- package/dist/search/BasicSearch.js +9 -3
- package/dist/search/BooleanSearch.d.ts +98 -0
- package/dist/search/BooleanSearch.d.ts.map +1 -0
- package/dist/search/BooleanSearch.js +156 -9
- package/dist/search/EmbeddingService.d.ts +178 -0
- package/dist/search/EmbeddingService.d.ts.map +1 -0
- package/dist/search/EmbeddingService.js +358 -0
- package/dist/search/FuzzySearch.d.ts +118 -0
- package/dist/search/FuzzySearch.d.ts.map +1 -0
- package/dist/search/FuzzySearch.js +241 -25
- package/dist/search/QueryCostEstimator.d.ts +111 -0
- package/dist/search/QueryCostEstimator.d.ts.map +1 -0
- package/dist/search/QueryCostEstimator.js +355 -0
- package/dist/search/RankedSearch.d.ts +71 -0
- package/dist/search/RankedSearch.d.ts.map +1 -0
- package/dist/search/RankedSearch.js +54 -6
- package/dist/search/SavedSearchManager.d.ts +79 -0
- package/dist/search/SavedSearchManager.d.ts.map +1 -0
- package/dist/search/SavedSearchManager.js +3 -2
- package/dist/search/SearchFilterChain.d.ts +120 -0
- package/dist/search/SearchFilterChain.d.ts.map +1 -0
- package/dist/search/SearchFilterChain.js +2 -4
- package/dist/search/SearchManager.d.ts +326 -0
- package/dist/search/SearchManager.d.ts.map +1 -0
- package/dist/search/SearchManager.js +148 -0
- package/dist/search/SearchSuggestions.d.ts +27 -0
- package/dist/search/SearchSuggestions.d.ts.map +1 -0
- package/dist/search/SearchSuggestions.js +1 -1
- package/dist/search/SemanticSearch.d.ts +149 -0
- package/dist/search/SemanticSearch.d.ts.map +1 -0
- package/dist/search/SemanticSearch.js +323 -0
- package/dist/search/TFIDFEventSync.d.ts +85 -0
- package/dist/search/TFIDFEventSync.d.ts.map +1 -0
- package/dist/search/TFIDFEventSync.js +133 -0
- package/dist/search/TFIDFIndexManager.d.ts +151 -0
- package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
- package/dist/search/TFIDFIndexManager.js +232 -17
- package/dist/search/VectorStore.d.ts +235 -0
- package/dist/search/VectorStore.d.ts.map +1 -0
- package/dist/search/VectorStore.js +311 -0
- package/dist/search/index.d.ts +21 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +12 -0
- package/dist/server/MCPServer.d.ts +21 -0
- package/dist/server/MCPServer.d.ts.map +1 -0
- package/dist/server/MCPServer.js +4 -4
- package/dist/server/responseCompressor.d.ts +94 -0
- package/dist/server/responseCompressor.d.ts.map +1 -0
- package/dist/server/responseCompressor.js +127 -0
- package/dist/server/toolDefinitions.d.ts +27 -0
- package/dist/server/toolDefinitions.d.ts.map +1 -0
- package/dist/server/toolDefinitions.js +188 -17
- package/dist/server/toolHandlers.d.ts +41 -0
- package/dist/server/toolHandlers.d.ts.map +1 -0
- package/dist/server/toolHandlers.js +469 -75
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -1
- package/dist/types/types.d.ts +1654 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +9 -0
- package/dist/utils/compressedCache.d.ts +192 -0
- package/dist/utils/compressedCache.d.ts.map +1 -0
- package/dist/utils/compressedCache.js +309 -0
- package/dist/utils/compressionUtil.d.ts +214 -0
- package/dist/utils/compressionUtil.d.ts.map +1 -0
- package/dist/utils/compressionUtil.js +247 -0
- package/dist/utils/constants.d.ts +245 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +124 -0
- package/dist/utils/entityUtils.d.ts +354 -0
- package/dist/utils/entityUtils.d.ts.map +1 -0
- package/dist/utils/entityUtils.js +511 -4
- package/dist/utils/errors.d.ts +95 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +24 -0
- package/dist/utils/formatters.d.ts +145 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/{paginationUtils.js → formatters.js} +54 -3
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +71 -31
- package/dist/utils/indexes.d.ts +270 -0
- package/dist/utils/indexes.d.ts.map +1 -0
- package/dist/utils/indexes.js +526 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/operationUtils.d.ts +124 -0
- package/dist/utils/operationUtils.d.ts.map +1 -0
- package/dist/utils/operationUtils.js +175 -0
- package/dist/utils/parallelUtils.d.ts +76 -0
- package/dist/utils/parallelUtils.d.ts.map +1 -0
- package/dist/utils/parallelUtils.js +191 -0
- package/dist/utils/schemas.d.ts +374 -0
- package/dist/utils/schemas.d.ts.map +1 -0
- package/dist/utils/schemas.js +307 -7
- package/dist/utils/searchAlgorithms.d.ts +99 -0
- package/dist/utils/searchAlgorithms.d.ts.map +1 -0
- package/dist/utils/searchAlgorithms.js +167 -0
- package/dist/utils/searchCache.d.ts +108 -0
- package/dist/utils/searchCache.d.ts.map +1 -0
- package/dist/utils/taskScheduler.d.ts +294 -0
- package/dist/utils/taskScheduler.d.ts.map +1 -0
- package/dist/utils/taskScheduler.js +486 -0
- package/dist/workers/index.d.ts +12 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +9 -0
- package/dist/workers/levenshteinWorker.d.ts +60 -0
- package/dist/workers/levenshteinWorker.d.ts.map +1 -0
- package/dist/workers/levenshteinWorker.js +98 -0
- package/package.json +17 -4
- package/dist/__tests__/edge-cases/edge-cases.test.js +0 -406
- package/dist/__tests__/integration/workflows.test.js +0 -449
- package/dist/__tests__/performance/benchmarks.test.js +0 -413
- package/dist/__tests__/unit/core/EntityManager.test.js +0 -334
- package/dist/__tests__/unit/core/GraphStorage.test.js +0 -205
- package/dist/__tests__/unit/core/RelationManager.test.js +0 -274
- package/dist/__tests__/unit/features/CompressionManager.test.js +0 -350
- package/dist/__tests__/unit/search/BasicSearch.test.js +0 -311
- package/dist/__tests__/unit/search/BooleanSearch.test.js +0 -432
- package/dist/__tests__/unit/search/FuzzySearch.test.js +0 -448
- package/dist/__tests__/unit/search/RankedSearch.test.js +0 -379
- package/dist/__tests__/unit/utils/levenshtein.test.js +0 -77
- package/dist/core/KnowledgeGraphManager.js +0 -423
- package/dist/features/BackupManager.js +0 -311
- package/dist/features/ExportManager.js +0 -305
- package/dist/features/ImportExportManager.js +0 -50
- package/dist/features/ImportManager.js +0 -328
- package/dist/memory-saved-searches.jsonl +0 -0
- package/dist/memory-tag-aliases.jsonl +0 -0
- package/dist/types/analytics.types.js +0 -6
- package/dist/types/entity.types.js +0 -7
- package/dist/types/import-export.types.js +0 -7
- package/dist/types/search.types.js +0 -7
- package/dist/types/tag.types.js +0 -6
- package/dist/utils/dateUtils.js +0 -89
- package/dist/utils/filterUtils.js +0 -155
- package/dist/utils/levenshtein.js +0 -62
- package/dist/utils/pathUtils.js +0 -115
- package/dist/utils/responseFormatter.js +0 -55
- package/dist/utils/tagUtils.js +0 -107
- package/dist/utils/tfidf.js +0 -90
- package/dist/utils/validationHelper.js +0 -99
- package/dist/utils/validationUtils.js +0 -109
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Entity
|
|
2
|
+
* Entity Utilities
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Consolidated module for entity-related utilities including:
|
|
5
|
+
* - Entity lookup and manipulation functions
|
|
6
|
+
* - Tag normalization and matching
|
|
7
|
+
* - Date parsing and validation
|
|
8
|
+
* - Entity filtering by various criteria
|
|
9
|
+
* - Path utilities and validation
|
|
10
|
+
*
|
|
11
|
+
* @module utils/entityUtils
|
|
6
12
|
*/
|
|
7
|
-
import {
|
|
13
|
+
import { promises as fs } from 'fs';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
import { EntityNotFoundError, FileOperationError } from './errors.js';
|
|
8
17
|
export function findEntityByName(graph, name, throwIfNotFound = true) {
|
|
9
18
|
const entity = graph.entities.find(e => e.name === name);
|
|
10
19
|
if (!entity && throwIfNotFound) {
|
|
@@ -106,3 +115,501 @@ export function touchEntity(entity) {
|
|
|
106
115
|
entity.lastModified = new Date().toISOString();
|
|
107
116
|
return entity;
|
|
108
117
|
}
|
|
118
|
+
// ==================== Tag Normalization and Matching ====================
|
|
119
|
+
/**
|
|
120
|
+
* Normalizes a single tag to lowercase and trimmed.
|
|
121
|
+
*
|
|
122
|
+
* @param tag - Tag to normalize
|
|
123
|
+
* @returns Normalized tag
|
|
124
|
+
*/
|
|
125
|
+
export function normalizeTag(tag) {
|
|
126
|
+
return tag.toLowerCase().trim();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Normalizes an array of tags to lowercase.
|
|
130
|
+
* Handles undefined/null input gracefully.
|
|
131
|
+
*
|
|
132
|
+
* @param tags - Array of tags to normalize, or undefined
|
|
133
|
+
* @returns Normalized tags array, or empty array if input is undefined/null
|
|
134
|
+
*/
|
|
135
|
+
export function normalizeTags(tags) {
|
|
136
|
+
if (!tags || tags.length === 0)
|
|
137
|
+
return [];
|
|
138
|
+
return tags.map(tag => tag.toLowerCase());
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Checks if an entity's tags include any of the specified search tags.
|
|
142
|
+
* Both inputs are normalized before comparison.
|
|
143
|
+
*
|
|
144
|
+
* @param entityTags - Tags on the entity (may be undefined)
|
|
145
|
+
* @param searchTags - Tags to search for (may be undefined)
|
|
146
|
+
* @returns true if any search tag matches any entity tag, false if no match or either is empty
|
|
147
|
+
*/
|
|
148
|
+
export function hasMatchingTag(entityTags, searchTags) {
|
|
149
|
+
if (!entityTags || entityTags.length === 0)
|
|
150
|
+
return false;
|
|
151
|
+
if (!searchTags || searchTags.length === 0)
|
|
152
|
+
return false;
|
|
153
|
+
const normalizedEntity = normalizeTags(entityTags);
|
|
154
|
+
const normalizedSearch = normalizeTags(searchTags);
|
|
155
|
+
return normalizedSearch.some(tag => normalizedEntity.includes(tag));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Checks if entity tags include ALL of the specified required tags.
|
|
159
|
+
*
|
|
160
|
+
* @param entityTags - Tags on the entity (may be undefined)
|
|
161
|
+
* @param requiredTags - All tags that must be present
|
|
162
|
+
* @returns true if all required tags are present
|
|
163
|
+
*/
|
|
164
|
+
export function hasAllTags(entityTags, requiredTags) {
|
|
165
|
+
if (!entityTags || entityTags.length === 0)
|
|
166
|
+
return false;
|
|
167
|
+
if (requiredTags.length === 0)
|
|
168
|
+
return true;
|
|
169
|
+
const normalizedEntity = normalizeTags(entityTags);
|
|
170
|
+
return normalizeTags(requiredTags).every(tag => normalizedEntity.includes(tag));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Filters entities by tag match.
|
|
174
|
+
* Returns all entities if searchTags is empty or undefined.
|
|
175
|
+
*
|
|
176
|
+
* @param entities - Array of entities with optional tags property
|
|
177
|
+
* @param searchTags - Tags to filter by
|
|
178
|
+
* @returns Filtered entities that have at least one matching tag
|
|
179
|
+
*/
|
|
180
|
+
export function filterByTags(entities, searchTags) {
|
|
181
|
+
if (!searchTags || searchTags.length === 0) {
|
|
182
|
+
return entities;
|
|
183
|
+
}
|
|
184
|
+
const normalizedSearch = normalizeTags(searchTags);
|
|
185
|
+
return entities.filter(entity => {
|
|
186
|
+
if (!entity.tags || entity.tags.length === 0)
|
|
187
|
+
return false;
|
|
188
|
+
const normalizedEntity = normalizeTags(entity.tags);
|
|
189
|
+
return normalizedSearch.some(tag => normalizedEntity.includes(tag));
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Adds new tags to an existing tag array, avoiding duplicates.
|
|
194
|
+
* All tags are normalized to lowercase.
|
|
195
|
+
*
|
|
196
|
+
* @param existingTags - Current tags (may be undefined)
|
|
197
|
+
* @param newTags - Tags to add
|
|
198
|
+
* @returns Combined tags array with no duplicates
|
|
199
|
+
*/
|
|
200
|
+
export function addUniqueTags(existingTags, newTags) {
|
|
201
|
+
const existing = normalizeTags(existingTags);
|
|
202
|
+
const toAdd = normalizeTags(newTags);
|
|
203
|
+
const uniqueNew = toAdd.filter(tag => !existing.includes(tag));
|
|
204
|
+
return [...existing, ...uniqueNew];
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Removes specified tags from an existing tag array.
|
|
208
|
+
* Comparison is case-insensitive.
|
|
209
|
+
*
|
|
210
|
+
* @param existingTags - Current tags (may be undefined)
|
|
211
|
+
* @param tagsToRemove - Tags to remove
|
|
212
|
+
* @returns Tags array with specified tags removed
|
|
213
|
+
*/
|
|
214
|
+
export function removeTags(existingTags, tagsToRemove) {
|
|
215
|
+
if (!existingTags || existingTags.length === 0)
|
|
216
|
+
return [];
|
|
217
|
+
const toRemoveNormalized = normalizeTags(tagsToRemove);
|
|
218
|
+
return existingTags.filter(tag => !toRemoveNormalized.includes(tag.toLowerCase()));
|
|
219
|
+
}
|
|
220
|
+
// ==================== Date Utilities ====================
|
|
221
|
+
/**
|
|
222
|
+
* Check if a date falls within a specified range.
|
|
223
|
+
*
|
|
224
|
+
* @param date - ISO 8601 date string to check (may be undefined)
|
|
225
|
+
* @param start - Optional start date (inclusive)
|
|
226
|
+
* @param end - Optional end date (inclusive)
|
|
227
|
+
* @returns True if date is within range or no filters are set
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* isWithinDateRange('2024-06-15T00:00:00Z', '2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'); // true
|
|
232
|
+
* isWithinDateRange('2024-06-15T00:00:00Z', '2024-07-01T00:00:00Z'); // false
|
|
233
|
+
* isWithinDateRange(undefined); // true (no filters)
|
|
234
|
+
* isWithinDateRange(undefined, '2024-01-01T00:00:00Z'); // false (has filter but no date)
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
export function isWithinDateRange(date, start, end) {
|
|
238
|
+
// If no filters set, always pass
|
|
239
|
+
if (!start && !end) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
// If date is undefined but we have filters, fail
|
|
243
|
+
if (!date) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
const dateObj = new Date(date);
|
|
247
|
+
if (isNaN(dateObj.getTime())) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
if (start) {
|
|
251
|
+
const startObj = new Date(start);
|
|
252
|
+
if (isNaN(startObj.getTime())) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
if (dateObj < startObj) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (end) {
|
|
260
|
+
const endObj = new Date(end);
|
|
261
|
+
if (isNaN(endObj.getTime())) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
if (dateObj > endObj) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Parse and validate date range strings.
|
|
272
|
+
*
|
|
273
|
+
* @param startDate - Optional ISO 8601 start date
|
|
274
|
+
* @param endDate - Optional ISO 8601 end date
|
|
275
|
+
* @returns Parsed Date objects or null
|
|
276
|
+
*/
|
|
277
|
+
export function parseDateRange(startDate, endDate) {
|
|
278
|
+
let start = null;
|
|
279
|
+
let end = null;
|
|
280
|
+
if (startDate) {
|
|
281
|
+
start = new Date(startDate);
|
|
282
|
+
if (isNaN(start.getTime())) {
|
|
283
|
+
start = null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (endDate) {
|
|
287
|
+
end = new Date(endDate);
|
|
288
|
+
if (isNaN(end.getTime())) {
|
|
289
|
+
end = null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return { start, end };
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Validate if a string is a valid ISO 8601 date.
|
|
296
|
+
*
|
|
297
|
+
* @param date - Date string to validate
|
|
298
|
+
* @returns True if valid ISO 8601 date
|
|
299
|
+
*/
|
|
300
|
+
export function isValidISODate(date) {
|
|
301
|
+
const dateObj = new Date(date);
|
|
302
|
+
return !isNaN(dateObj.getTime()) && dateObj.toISOString() === date;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Get current timestamp in ISO 8601 format.
|
|
306
|
+
*
|
|
307
|
+
* @returns Current timestamp string
|
|
308
|
+
*/
|
|
309
|
+
export function getCurrentTimestamp() {
|
|
310
|
+
return new Date().toISOString();
|
|
311
|
+
}
|
|
312
|
+
// ==================== Filter Utilities ====================
|
|
313
|
+
/**
|
|
314
|
+
* Checks if an entity's importance is within the specified range.
|
|
315
|
+
* Entities without importance are treated as not matching if any filter is set.
|
|
316
|
+
*
|
|
317
|
+
* @param importance - The entity's importance value (may be undefined)
|
|
318
|
+
* @param minImportance - Minimum importance filter (inclusive)
|
|
319
|
+
* @param maxImportance - Maximum importance filter (inclusive)
|
|
320
|
+
* @returns true if importance is within range or no filters are set
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* ```typescript
|
|
324
|
+
* // Check if entity passes importance filter
|
|
325
|
+
* if (isWithinImportanceRange(entity.importance, 5, 10)) {
|
|
326
|
+
* // Entity has importance between 5 and 10
|
|
327
|
+
* }
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
export function isWithinImportanceRange(importance, minImportance, maxImportance) {
|
|
331
|
+
// If no filters set, always pass
|
|
332
|
+
if (minImportance === undefined && maxImportance === undefined) {
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
// Check minimum importance
|
|
336
|
+
if (minImportance !== undefined) {
|
|
337
|
+
if (importance === undefined || importance < minImportance) {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Check maximum importance
|
|
342
|
+
if (maxImportance !== undefined) {
|
|
343
|
+
if (importance === undefined || importance > maxImportance) {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Filters entities by importance range.
|
|
351
|
+
* Returns all entities if no importance filters are specified.
|
|
352
|
+
*
|
|
353
|
+
* @param entities - Array of entities to filter
|
|
354
|
+
* @param minImportance - Minimum importance filter (inclusive)
|
|
355
|
+
* @param maxImportance - Maximum importance filter (inclusive)
|
|
356
|
+
* @returns Filtered entities within the importance range
|
|
357
|
+
*/
|
|
358
|
+
export function filterByImportance(entities, minImportance, maxImportance) {
|
|
359
|
+
if (minImportance === undefined && maxImportance === undefined) {
|
|
360
|
+
return entities;
|
|
361
|
+
}
|
|
362
|
+
return entities.filter(e => isWithinImportanceRange(e.importance, minImportance, maxImportance));
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Filters entities by creation date range.
|
|
366
|
+
*
|
|
367
|
+
* @param entities - Array of entities to filter
|
|
368
|
+
* @param startDate - Start of date range (inclusive)
|
|
369
|
+
* @param endDate - End of date range (inclusive)
|
|
370
|
+
* @returns Filtered entities created within the date range
|
|
371
|
+
*/
|
|
372
|
+
export function filterByCreatedDate(entities, startDate, endDate) {
|
|
373
|
+
if (!startDate && !endDate) {
|
|
374
|
+
return entities;
|
|
375
|
+
}
|
|
376
|
+
return entities.filter(e => isWithinDateRange(e.createdAt, startDate, endDate));
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Filters entities by last modified date range.
|
|
380
|
+
*
|
|
381
|
+
* @param entities - Array of entities to filter
|
|
382
|
+
* @param startDate - Start of date range (inclusive)
|
|
383
|
+
* @param endDate - End of date range (inclusive)
|
|
384
|
+
* @returns Filtered entities modified within the date range
|
|
385
|
+
*/
|
|
386
|
+
export function filterByModifiedDate(entities, startDate, endDate) {
|
|
387
|
+
if (!startDate && !endDate) {
|
|
388
|
+
return entities;
|
|
389
|
+
}
|
|
390
|
+
return entities.filter(e => isWithinDateRange(e.lastModified, startDate, endDate));
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Filters entities by entity type.
|
|
394
|
+
*
|
|
395
|
+
* @param entities - Array of entities to filter
|
|
396
|
+
* @param entityType - Entity type to filter by (case-sensitive)
|
|
397
|
+
* @returns Filtered entities of the specified type
|
|
398
|
+
*/
|
|
399
|
+
export function filterByEntityType(entities, entityType) {
|
|
400
|
+
if (!entityType) {
|
|
401
|
+
return entities;
|
|
402
|
+
}
|
|
403
|
+
return entities.filter(e => e.entityType === entityType);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Checks if an entity passes all the specified filters.
|
|
407
|
+
* Short-circuits on first failing filter for performance.
|
|
408
|
+
*
|
|
409
|
+
* Note: Tag filtering should be handled separately using hasMatchingTag
|
|
410
|
+
* as it requires special normalization logic.
|
|
411
|
+
*
|
|
412
|
+
* @param entity - Entity to check
|
|
413
|
+
* @param filters - Filters to apply
|
|
414
|
+
* @returns true if entity passes all filters
|
|
415
|
+
*/
|
|
416
|
+
export function entityPassesFilters(entity, filters) {
|
|
417
|
+
// Importance filter
|
|
418
|
+
if (!isWithinImportanceRange(entity.importance, filters.minImportance, filters.maxImportance)) {
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
// Entity type filter
|
|
422
|
+
if (filters.entityType && entity.entityType !== filters.entityType) {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
// Created date filter
|
|
426
|
+
if (!isWithinDateRange(entity.createdAt, filters.createdAfter, filters.createdBefore)) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
// Modified date filter
|
|
430
|
+
if (!isWithinDateRange(entity.lastModified, filters.modifiedAfter, filters.modifiedBefore)) {
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
// ==================== Security Utilities ====================
|
|
436
|
+
/**
|
|
437
|
+
* Dangerous keys that should never be allowed in object assignment.
|
|
438
|
+
* These can be used for prototype pollution attacks.
|
|
439
|
+
*/
|
|
440
|
+
const DANGEROUS_KEYS = new Set([
|
|
441
|
+
'__proto__',
|
|
442
|
+
'constructor',
|
|
443
|
+
'prototype',
|
|
444
|
+
]);
|
|
445
|
+
/**
|
|
446
|
+
* Sanitizes an object by removing potentially dangerous keys.
|
|
447
|
+
* This prevents prototype pollution attacks when using Object.assign() or spread operators.
|
|
448
|
+
*
|
|
449
|
+
* @param obj - The object to sanitize
|
|
450
|
+
* @returns A new object with dangerous keys removed
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```typescript
|
|
454
|
+
* // Safe usage with Object.assign
|
|
455
|
+
* const updates = sanitizeObject(userInput);
|
|
456
|
+
* Object.assign(entity, updates);
|
|
457
|
+
*
|
|
458
|
+
* // Protects against prototype pollution
|
|
459
|
+
* const malicious = { __proto__: { admin: true } };
|
|
460
|
+
* const safe = sanitizeObject(malicious); // { }
|
|
461
|
+
* ```
|
|
462
|
+
*/
|
|
463
|
+
export function sanitizeObject(obj) {
|
|
464
|
+
if (obj === null || typeof obj !== 'object') {
|
|
465
|
+
return obj;
|
|
466
|
+
}
|
|
467
|
+
const result = {};
|
|
468
|
+
for (const key of Object.keys(obj)) {
|
|
469
|
+
// Skip dangerous keys
|
|
470
|
+
if (DANGEROUS_KEYS.has(key)) {
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
// Recursively sanitize nested objects
|
|
474
|
+
const value = obj[key];
|
|
475
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
476
|
+
result[key] = sanitizeObject(value);
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
result[key] = value;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return result;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* CSV formula injection dangerous characters.
|
|
486
|
+
* These can cause spreadsheet applications to execute formulas.
|
|
487
|
+
*/
|
|
488
|
+
const CSV_FORMULA_CHARS = new Set(['=', '+', '-', '@', '\t', '\r']);
|
|
489
|
+
/**
|
|
490
|
+
* Escapes a CSV field to prevent formula injection attacks.
|
|
491
|
+
* Prepends a single quote to values that start with dangerous characters.
|
|
492
|
+
*
|
|
493
|
+
* @param field - The field value to escape
|
|
494
|
+
* @returns Escaped field value safe for CSV export
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```typescript
|
|
498
|
+
* escapeCsvFormula('=SUM(A1:A10)'); // "'=SUM(A1:A10)"
|
|
499
|
+
* escapeCsvFormula('normal text'); // 'normal text'
|
|
500
|
+
* ```
|
|
501
|
+
*/
|
|
502
|
+
export function escapeCsvFormula(field) {
|
|
503
|
+
if (field === undefined || field === null)
|
|
504
|
+
return '';
|
|
505
|
+
const str = String(field);
|
|
506
|
+
// Prefix with single quote if starts with dangerous character
|
|
507
|
+
if (str.length > 0 && CSV_FORMULA_CHARS.has(str[0])) {
|
|
508
|
+
return "'" + str;
|
|
509
|
+
}
|
|
510
|
+
return str;
|
|
511
|
+
}
|
|
512
|
+
// ==================== Path Utilities ====================
|
|
513
|
+
/**
|
|
514
|
+
* Validate and normalize a file path to prevent path traversal attacks.
|
|
515
|
+
*
|
|
516
|
+
* This function:
|
|
517
|
+
* - Normalizes the path to canonical form
|
|
518
|
+
* - Converts relative paths to absolute paths
|
|
519
|
+
* - Detects and prevents path traversal attempts (..)
|
|
520
|
+
*
|
|
521
|
+
* @param filePath - The file path to validate
|
|
522
|
+
* @param baseDir - Optional base directory for relative paths (defaults to process.cwd())
|
|
523
|
+
* @returns Validated absolute file path
|
|
524
|
+
* @throws {FileOperationError} If path traversal is detected or path is invalid
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* ```typescript
|
|
528
|
+
* // Valid paths
|
|
529
|
+
* validateFilePath('/var/data/memory.jsonl'); // Returns absolute path
|
|
530
|
+
* validateFilePath('data/memory.jsonl'); // Returns absolute path from cwd
|
|
531
|
+
*
|
|
532
|
+
* // Invalid paths (throws FileOperationError)
|
|
533
|
+
* validateFilePath('../../../etc/passwd'); // Path traversal detected
|
|
534
|
+
* validateFilePath('/var/data/../../../etc/passwd'); // Path traversal detected
|
|
535
|
+
* ```
|
|
536
|
+
*/
|
|
537
|
+
export function validateFilePath(filePath, baseDir = process.cwd()) {
|
|
538
|
+
// Normalize path to remove redundant separators and resolve . and ..
|
|
539
|
+
const normalized = path.normalize(filePath);
|
|
540
|
+
// Convert to absolute path
|
|
541
|
+
const absolute = path.isAbsolute(normalized)
|
|
542
|
+
? normalized
|
|
543
|
+
: path.join(baseDir, normalized);
|
|
544
|
+
// After normalization, check if path still contains .. which would indicate
|
|
545
|
+
// traversal beyond the base directory
|
|
546
|
+
const finalNormalized = path.normalize(absolute);
|
|
547
|
+
// Split path into segments and check for suspicious patterns
|
|
548
|
+
const segments = finalNormalized.split(path.sep);
|
|
549
|
+
if (segments.includes('..')) {
|
|
550
|
+
throw new FileOperationError(`Path traversal detected in file path: ${filePath}`, filePath);
|
|
551
|
+
}
|
|
552
|
+
return finalNormalized;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Default memory file path (in project root directory, outside dist/).
|
|
556
|
+
*/
|
|
557
|
+
export const defaultMemoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../memory.jsonl');
|
|
558
|
+
/**
|
|
559
|
+
* Ensure memory file path with backward compatibility migration.
|
|
560
|
+
*
|
|
561
|
+
* Handles:
|
|
562
|
+
* 1. Custom MEMORY_FILE_PATH environment variable (with path traversal protection)
|
|
563
|
+
* 2. Backward compatibility: migrates memory.json to memory.jsonl
|
|
564
|
+
* 3. Absolute vs relative path resolution
|
|
565
|
+
*
|
|
566
|
+
* @returns Resolved and validated memory file path
|
|
567
|
+
* @throws {FileOperationError} If path traversal is detected in MEMORY_FILE_PATH
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```typescript
|
|
571
|
+
* // Use environment variable
|
|
572
|
+
* process.env.MEMORY_FILE_PATH = '/data/memory.jsonl';
|
|
573
|
+
* const path = await ensureMemoryFilePath(); // '/data/memory.jsonl'
|
|
574
|
+
*
|
|
575
|
+
* // Use default path
|
|
576
|
+
* delete process.env.MEMORY_FILE_PATH;
|
|
577
|
+
* const path = await ensureMemoryFilePath(); // './memory.jsonl'
|
|
578
|
+
*
|
|
579
|
+
* // Invalid path (throws error)
|
|
580
|
+
* process.env.MEMORY_FILE_PATH = '../../../etc/passwd';
|
|
581
|
+
* await ensureMemoryFilePath(); // Throws FileOperationError
|
|
582
|
+
* ```
|
|
583
|
+
*/
|
|
584
|
+
export async function ensureMemoryFilePath() {
|
|
585
|
+
if (process.env.MEMORY_FILE_PATH) {
|
|
586
|
+
// Custom path provided, validate and resolve to absolute
|
|
587
|
+
const baseDir = path.dirname(fileURLToPath(import.meta.url)) + '/../';
|
|
588
|
+
const validatedPath = validateFilePath(process.env.MEMORY_FILE_PATH, baseDir);
|
|
589
|
+
return validatedPath;
|
|
590
|
+
}
|
|
591
|
+
// No custom path set, check for backward compatibility migration
|
|
592
|
+
const oldMemoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../memory.json');
|
|
593
|
+
const newMemoryPath = defaultMemoryPath;
|
|
594
|
+
try {
|
|
595
|
+
// Check if old file exists
|
|
596
|
+
await fs.access(oldMemoryPath);
|
|
597
|
+
try {
|
|
598
|
+
// Check if new file exists
|
|
599
|
+
await fs.access(newMemoryPath);
|
|
600
|
+
// Both files exist, use new one (no migration needed)
|
|
601
|
+
return newMemoryPath;
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
// Old file exists, new file doesn't - migrate
|
|
605
|
+
console.log('[INFO] Found legacy memory.json file, migrating to memory.jsonl for JSONL format compatibility');
|
|
606
|
+
await fs.rename(oldMemoryPath, newMemoryPath);
|
|
607
|
+
console.log('[INFO] Successfully migrated memory.json to memory.jsonl');
|
|
608
|
+
return newMemoryPath;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
catch {
|
|
612
|
+
// Old file doesn't exist, use new path
|
|
613
|
+
return newMemoryPath;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Error Types
|
|
3
|
+
*
|
|
4
|
+
* Defines custom error classes for better error handling and debugging.
|
|
5
|
+
*
|
|
6
|
+
* @module utils/errors
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Base error class for all knowledge graph errors.
|
|
10
|
+
* Extends the native Error class with additional context.
|
|
11
|
+
*/
|
|
12
|
+
export declare class KnowledgeGraphError extends Error {
|
|
13
|
+
readonly code?: string | undefined;
|
|
14
|
+
constructor(message: string, code?: string | undefined);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Error thrown when an entity is not found.
|
|
18
|
+
*/
|
|
19
|
+
export declare class EntityNotFoundError extends KnowledgeGraphError {
|
|
20
|
+
constructor(entityName: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown when a relation is not found.
|
|
24
|
+
*/
|
|
25
|
+
export declare class RelationNotFoundError extends KnowledgeGraphError {
|
|
26
|
+
constructor(from: string, to: string, relationType?: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error thrown when attempting to create a duplicate entity.
|
|
30
|
+
*/
|
|
31
|
+
export declare class DuplicateEntityError extends KnowledgeGraphError {
|
|
32
|
+
constructor(entityName: string);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error thrown when validation fails.
|
|
36
|
+
*/
|
|
37
|
+
export declare class ValidationError extends KnowledgeGraphError {
|
|
38
|
+
readonly errors: string[];
|
|
39
|
+
constructor(message: string, errors: string[]);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Error thrown when a cycle is detected in hierarchies.
|
|
43
|
+
*/
|
|
44
|
+
export declare class CycleDetectedError extends KnowledgeGraphError {
|
|
45
|
+
constructor(entityName: string, parentName: string);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Error thrown when an invalid importance value is provided.
|
|
49
|
+
*/
|
|
50
|
+
export declare class InvalidImportanceError extends KnowledgeGraphError {
|
|
51
|
+
constructor(value: number, min?: number, max?: number);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Error thrown when a file operation fails.
|
|
55
|
+
*/
|
|
56
|
+
export declare class FileOperationError extends KnowledgeGraphError {
|
|
57
|
+
constructor(operation: string, filePath: string, cause?: Error);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Error thrown when an import operation fails.
|
|
61
|
+
*/
|
|
62
|
+
export declare class ImportError extends KnowledgeGraphError {
|
|
63
|
+
constructor(format: string, message: string);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Error thrown when an export operation fails.
|
|
67
|
+
*/
|
|
68
|
+
export declare class ExportError extends KnowledgeGraphError {
|
|
69
|
+
constructor(format: string, message: string);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Error thrown when insufficient entities are provided for an operation.
|
|
73
|
+
*/
|
|
74
|
+
export declare class InsufficientEntitiesError extends KnowledgeGraphError {
|
|
75
|
+
constructor(operation: string, required: number, provided: number);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Phase 9B: Error thrown when an operation is cancelled via AbortSignal.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const controller = new AbortController();
|
|
83
|
+
* try {
|
|
84
|
+
* await manager.createEntities(entities, { signal: controller.signal });
|
|
85
|
+
* } catch (error) {
|
|
86
|
+
* if (error instanceof OperationCancelledError) {
|
|
87
|
+
* console.log('Operation was cancelled');
|
|
88
|
+
* }
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare class OperationCancelledError extends KnowledgeGraphError {
|
|
93
|
+
constructor(operation?: string);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aACC,IAAI,CAAC,EAAE,MAAM;gBAA9C,OAAO,EAAE,MAAM,EAAkB,IAAI,CAAC,EAAE,MAAM,YAAA;CAQ3D;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,mBAAmB;gBAC9C,UAAU,EAAE,MAAM;CAI/B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;gBAChD,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;CAO5D;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,mBAAmB;gBAC/C,UAAU,EAAE,MAAM;CAI/B;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,mBAAmB;aAGpC,MAAM,EAAE,MAAM,EAAE;gBADhC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EAAE;CAKnC;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,mBAAmB;gBAC7C,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAOnD;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,mBAAmB;gBACjD,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAU,EAAE,GAAG,GAAE,MAAW;CAO7D;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,mBAAmB;gBAEvD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,KAAK;CAWhB;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,mBAAmB;gBACtC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5C;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,mBAAmB;gBACtC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5C;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,mBAAmB;gBACpD,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAOlE;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAwB,SAAQ,mBAAmB;gBAClD,SAAS,CAAC,EAAE,MAAM;CAO/B"}
|
package/dist/utils/errors.js
CHANGED
|
@@ -119,3 +119,27 @@ export class InsufficientEntitiesError extends KnowledgeGraphError {
|
|
|
119
119
|
this.name = 'InsufficientEntitiesError';
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Phase 9B: Error thrown when an operation is cancelled via AbortSignal.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const controller = new AbortController();
|
|
128
|
+
* try {
|
|
129
|
+
* await manager.createEntities(entities, { signal: controller.signal });
|
|
130
|
+
* } catch (error) {
|
|
131
|
+
* if (error instanceof OperationCancelledError) {
|
|
132
|
+
* console.log('Operation was cancelled');
|
|
133
|
+
* }
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export class OperationCancelledError extends KnowledgeGraphError {
|
|
138
|
+
constructor(operation) {
|
|
139
|
+
const message = operation
|
|
140
|
+
? `Operation '${operation}' was cancelled`
|
|
141
|
+
: 'Operation was cancelled';
|
|
142
|
+
super(message, 'OPERATION_CANCELLED');
|
|
143
|
+
this.name = 'OperationCancelledError';
|
|
144
|
+
}
|
|
145
|
+
}
|