@prmichaelsen/remember-mcp 3.13.0 → 3.14.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.
- package/CHANGELOG.md +22 -0
- package/agent/milestones/milestone-17-remember-core-migration.md +140 -0
- package/agent/progress.yaml +123 -6
- package/agent/tasks/milestone-17-remember-core-migration/task-193-foundation-setup.md +58 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-194-migrate-relationship-tools.md +47 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-195-migrate-preference-tools.md +34 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-196-migrate-memory-tools.md +46 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-197-migrate-space-confirmation-tools.md +49 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-198-migrate-space-search-moderate.md +46 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-199-migrate-delete-memory.md +43 -0
- package/agent/tasks/milestone-17-remember-core-migration/task-200-code-cleanup-verification.md +52 -0
- package/dist/core-services.d.ts +25 -0
- package/dist/server-factory.js +3208 -3978
- package/dist/server.js +3708 -4474
- package/dist/tools/confirm-publish-moderation.spec.d.ts +3 -2
- package/dist/tools/create-memory.d.ts +1 -1
- package/dist/tools/query-space.d.ts +1 -1
- package/dist/tools/search-space.d.ts +10 -14
- package/jest.config.js +11 -0
- package/package.json +3 -1
- package/src/core-services.ts +50 -0
- package/src/tools/confirm-publish-moderation.spec.ts +120 -176
- package/src/tools/confirm.ts +70 -1035
- package/src/tools/create-memory.ts +16 -67
- package/src/tools/create-relationship.ts +13 -181
- package/src/tools/delete-memory.ts +7 -72
- package/src/tools/delete-relationship.ts +7 -91
- package/src/tools/deny.ts +4 -14
- package/src/tools/find-similar.ts +16 -110
- package/src/tools/get-preferences.ts +3 -8
- package/src/tools/moderate.spec.ts +65 -81
- package/src/tools/moderate.ts +18 -121
- package/src/tools/publish.ts +7 -204
- package/src/tools/query-space.ts +28 -140
- package/src/tools/retract.ts +7 -185
- package/src/tools/revise.ts +4 -136
- package/src/tools/search-relationship.ts +17 -116
- package/src/tools/search-space.ts +58 -304
- package/src/tools/set-preference.ts +3 -8
- package/src/tools/update-memory.ts +22 -190
- package/src/tools/update-relationship.ts +16 -90
- package/src/v2-smoke.e2e.ts +3 -2
- package/dist/collections/composite-ids.d.ts +0 -106
- package/dist/collections/core-infrastructure.spec.d.ts +0 -11
- package/dist/collections/dot-notation.d.ts +0 -106
- package/dist/collections/tracking-arrays.d.ts +0 -176
- package/dist/constants/content-types.d.ts +0 -61
- package/dist/services/confirmation-token.service.d.ts +0 -99
- package/dist/services/confirmation-token.service.spec.d.ts +0 -5
- package/dist/services/preferences-database.service.d.ts +0 -22
- package/dist/services/space-config.service.d.ts +0 -23
- package/dist/services/space-config.service.spec.d.ts +0 -2
- package/src/collections/composite-ids.ts +0 -193
- package/src/collections/core-infrastructure.spec.ts +0 -353
- package/src/collections/dot-notation.ts +0 -212
- package/src/collections/tracking-arrays.ts +0 -298
- package/src/constants/content-types.ts +0 -490
- package/src/services/confirmation-token.service.spec.ts +0 -254
- package/src/services/confirmation-token.service.ts +0 -328
- package/src/services/preferences-database.service.ts +0 -120
- package/src/services/space-config.service.spec.ts +0 -102
- package/src/services/space-config.service.ts +0 -79
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for Memory Collection Pattern v2 Core Infrastructure
|
|
3
|
-
*
|
|
4
|
-
* Tests core functionality of:
|
|
5
|
-
* - Dot notation collection utilities
|
|
6
|
-
* - Composite ID utilities
|
|
7
|
-
* - Tracking array management
|
|
8
|
-
* - Schema definitions
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
CollectionType,
|
|
13
|
-
getCollectionName,
|
|
14
|
-
parseCollectionName,
|
|
15
|
-
validateCollectionName,
|
|
16
|
-
isUserCollection,
|
|
17
|
-
isSpacesCollection,
|
|
18
|
-
isGroupCollection,
|
|
19
|
-
} from './dot-notation.js';
|
|
20
|
-
|
|
21
|
-
import {
|
|
22
|
-
generateCompositeId,
|
|
23
|
-
parseCompositeId,
|
|
24
|
-
isCompositeId,
|
|
25
|
-
validateCompositeId,
|
|
26
|
-
} from './composite-ids.js';
|
|
27
|
-
|
|
28
|
-
import {
|
|
29
|
-
addToSpaceIds,
|
|
30
|
-
removeFromSpaceIds,
|
|
31
|
-
addToGroupIds,
|
|
32
|
-
removeFromGroupIds,
|
|
33
|
-
isPublishedToSpace,
|
|
34
|
-
isPublishedToGroup,
|
|
35
|
-
getPublishedLocations,
|
|
36
|
-
isPublished,
|
|
37
|
-
getPublishedCount,
|
|
38
|
-
initializeTracking,
|
|
39
|
-
addMultipleSpaceIds,
|
|
40
|
-
addMultipleGroupIds,
|
|
41
|
-
type MemoryWithTracking,
|
|
42
|
-
} from './tracking-arrays.js';
|
|
43
|
-
|
|
44
|
-
import {
|
|
45
|
-
createUserCollectionSchema,
|
|
46
|
-
createSpaceCollectionSchema,
|
|
47
|
-
createGroupCollectionSchema,
|
|
48
|
-
getUserCollectionProperties,
|
|
49
|
-
getPublishedCollectionProperties,
|
|
50
|
-
validateV2CollectionName,
|
|
51
|
-
getCollectionType,
|
|
52
|
-
extractIdFromCollectionName,
|
|
53
|
-
} from '../schema/v2-collections.js';
|
|
54
|
-
|
|
55
|
-
// ============================================================================
|
|
56
|
-
// Dot Notation Collection Utilities Tests
|
|
57
|
-
// ============================================================================
|
|
58
|
-
|
|
59
|
-
describe('Dot Notation Collection Utilities', () => {
|
|
60
|
-
describe('getCollectionName', () => {
|
|
61
|
-
it('should generate user collection name', () => {
|
|
62
|
-
expect(getCollectionName(CollectionType.USERS, 'user123')).toBe('Memory_users_user123');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should generate spaces collection name', () => {
|
|
66
|
-
expect(getCollectionName(CollectionType.SPACES)).toBe('Memory_spaces_public');
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should generate group collection name', () => {
|
|
70
|
-
expect(getCollectionName(CollectionType.GROUPS, 'group456')).toBe('Memory_groups_group456');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should throw error for user collection without ID', () => {
|
|
74
|
-
expect(() => getCollectionName(CollectionType.USERS)).toThrow('User ID is required');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should throw error for ID with invalid characters', () => {
|
|
78
|
-
expect(() => getCollectionName(CollectionType.USERS, 'user.123')).toThrow();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('parseCollectionName', () => {
|
|
83
|
-
it('should parse user collection name', () => {
|
|
84
|
-
const result = parseCollectionName('Memory_users_user123');
|
|
85
|
-
expect(result.type).toBe(CollectionType.USERS);
|
|
86
|
-
expect(result.id).toBe('user123');
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('should parse spaces collection name', () => {
|
|
90
|
-
const result = parseCollectionName('Memory_spaces_public');
|
|
91
|
-
expect(result.type).toBe(CollectionType.SPACES);
|
|
92
|
-
expect(result.id).toBeUndefined();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('should parse group collection name', () => {
|
|
96
|
-
const result = parseCollectionName('Memory_groups_group456');
|
|
97
|
-
expect(result.type).toBe(CollectionType.GROUPS);
|
|
98
|
-
expect(result.id).toBe('group456');
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
describe('Collection type checkers', () => {
|
|
103
|
-
it('should identify user collections', () => {
|
|
104
|
-
expect(isUserCollection('Memory_users_user123')).toBe(true);
|
|
105
|
-
expect(isUserCollection('Memory_spaces_public')).toBe(false);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('should identify spaces collection', () => {
|
|
109
|
-
expect(isSpacesCollection('Memory_spaces_public')).toBe(true);
|
|
110
|
-
expect(isSpacesCollection('Memory_users_user123')).toBe(false);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('should identify group collections', () => {
|
|
114
|
-
expect(isGroupCollection('Memory_groups_group456')).toBe(true);
|
|
115
|
-
expect(isGroupCollection('Memory_users_user123')).toBe(false);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// ============================================================================
|
|
121
|
-
// Composite ID Utilities Tests
|
|
122
|
-
// ============================================================================
|
|
123
|
-
|
|
124
|
-
describe('Composite ID Utilities', () => {
|
|
125
|
-
describe('generateCompositeId', () => {
|
|
126
|
-
it('should generate composite ID', () => {
|
|
127
|
-
expect(generateCompositeId('user123', 'my-recipe')).toBe('user123.my-recipe');
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should throw error for userId with dots', () => {
|
|
131
|
-
expect(() => generateCompositeId('user.123', 'recipe')).toThrow('cannot contain dots');
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should throw error for empty userId', () => {
|
|
135
|
-
expect(() => generateCompositeId('', 'recipe')).toThrow('cannot be empty');
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('parseCompositeId', () => {
|
|
140
|
-
it('should parse composite ID', () => {
|
|
141
|
-
const result = parseCompositeId('user123.my-recipe');
|
|
142
|
-
expect(result.userId).toBe('user123');
|
|
143
|
-
expect(result.memoryId).toBe('my-recipe');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should throw error for invalid format', () => {
|
|
147
|
-
expect(() => parseCompositeId('invalid')).toThrow('must be exactly 2 parts');
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
describe('isCompositeId', () => {
|
|
152
|
-
it('should identify valid composite IDs', () => {
|
|
153
|
-
expect(isCompositeId('user123.my-recipe')).toBe(true);
|
|
154
|
-
expect(isCompositeId('simple-id')).toBe(false);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
describe('validateCompositeId', () => {
|
|
159
|
-
it('should validate correct composite IDs', () => {
|
|
160
|
-
expect(validateCompositeId('user123.my-recipe')).toBe(true);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('should throw error for invalid IDs', () => {
|
|
164
|
-
expect(() => validateCompositeId('invalid')).toThrow();
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// ============================================================================
|
|
170
|
-
// Tracking Array Management Tests
|
|
171
|
-
// ============================================================================
|
|
172
|
-
|
|
173
|
-
describe('Tracking Array Management', () => {
|
|
174
|
-
describe('addToSpaceIds', () => {
|
|
175
|
-
it('should add space ID to existing arrays', () => {
|
|
176
|
-
const memory: MemoryWithTracking = { space_ids: [], group_ids: [] };
|
|
177
|
-
const result = addToSpaceIds(memory, 'cooking');
|
|
178
|
-
expect(result.space_ids).toEqual(['cooking']);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('should not add duplicate space IDs', () => {
|
|
182
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking'], group_ids: [] };
|
|
183
|
-
const result = addToSpaceIds(memory, 'cooking');
|
|
184
|
-
expect(result.space_ids).toEqual(['cooking']);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('should be immutable', () => {
|
|
188
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking'], group_ids: [] };
|
|
189
|
-
const result = addToSpaceIds(memory, 'recipes');
|
|
190
|
-
expect(memory.space_ids).toEqual(['cooking']); // Original unchanged
|
|
191
|
-
expect(result.space_ids).toEqual(['cooking', 'recipes']);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe('removeFromSpaceIds', () => {
|
|
196
|
-
it('should remove space ID', () => {
|
|
197
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking', 'recipes'], group_ids: [] };
|
|
198
|
-
const result = removeFromSpaceIds(memory, 'cooking');
|
|
199
|
-
expect(result.space_ids).toEqual(['recipes']);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
describe('addToGroupIds', () => {
|
|
204
|
-
it('should add group ID', () => {
|
|
205
|
-
const memory: MemoryWithTracking = { space_ids: [], group_ids: ['family'] };
|
|
206
|
-
const result = addToGroupIds(memory, 'friends');
|
|
207
|
-
expect(result.group_ids).toEqual(['family', 'friends']);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
describe('removeFromGroupIds', () => {
|
|
212
|
-
it('should remove group ID', () => {
|
|
213
|
-
const memory: MemoryWithTracking = { space_ids: [], group_ids: ['family', 'friends'] };
|
|
214
|
-
const result = removeFromGroupIds(memory, 'family');
|
|
215
|
-
expect(result.group_ids).toEqual(['friends']);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('Publication checks', () => {
|
|
220
|
-
it('should check if published to space', () => {
|
|
221
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking'], group_ids: [] };
|
|
222
|
-
expect(isPublishedToSpace(memory, 'cooking')).toBe(true);
|
|
223
|
-
expect(isPublishedToSpace(memory, 'travel')).toBe(false);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('should check if published to group', () => {
|
|
227
|
-
const memory: MemoryWithTracking = { space_ids: [], group_ids: ['family'] };
|
|
228
|
-
expect(isPublishedToGroup(memory, 'family')).toBe(true);
|
|
229
|
-
expect(isPublishedToGroup(memory, 'coworkers')).toBe(false);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it('should get publication locations', () => {
|
|
233
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking'], group_ids: ['family'] };
|
|
234
|
-
const result = getPublishedLocations(memory);
|
|
235
|
-
expect(result).toEqual({ spaces: ['cooking'], groups: ['family'] });
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it('should check if published anywhere', () => {
|
|
239
|
-
const memory1: MemoryWithTracking = { space_ids: ['cooking'], group_ids: [] };
|
|
240
|
-
expect(isPublished(memory1)).toBe(true);
|
|
241
|
-
|
|
242
|
-
const memory2: MemoryWithTracking = { space_ids: [], group_ids: [] };
|
|
243
|
-
expect(isPublished(memory2)).toBe(false);
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it('should count publications', () => {
|
|
247
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking', 'recipes'], group_ids: ['family'] };
|
|
248
|
-
expect(getPublishedCount(memory)).toBe(3);
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
describe('Batch operations', () => {
|
|
253
|
-
it('should add multiple space IDs', () => {
|
|
254
|
-
const memory: MemoryWithTracking = { space_ids: ['cooking'], group_ids: [] };
|
|
255
|
-
const result = addMultipleSpaceIds(memory, ['recipes', 'baking']);
|
|
256
|
-
expect(result.space_ids).toEqual(['cooking', 'recipes', 'baking']);
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it('should add multiple group IDs', () => {
|
|
260
|
-
const memory: MemoryWithTracking = { space_ids: [], group_ids: ['family'] };
|
|
261
|
-
const result = addMultipleGroupIds(memory, ['friends', 'coworkers']);
|
|
262
|
-
expect(result.group_ids).toEqual(['family', 'friends', 'coworkers']);
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
describe('Utility functions', () => {
|
|
267
|
-
it('should initialize tracking arrays', () => {
|
|
268
|
-
const memory = { content: 'My recipe' };
|
|
269
|
-
const result = initializeTracking(memory);
|
|
270
|
-
expect(result.space_ids).toEqual([]);
|
|
271
|
-
expect(result.group_ids).toEqual([]);
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
// ============================================================================
|
|
277
|
-
// Schema Definitions Tests
|
|
278
|
-
// ============================================================================
|
|
279
|
-
|
|
280
|
-
describe('Schema Definitions', () => {
|
|
281
|
-
describe('Schema creation', () => {
|
|
282
|
-
it('should create user collection schema', () => {
|
|
283
|
-
const schema = createUserCollectionSchema('user123');
|
|
284
|
-
expect(schema.name).toBe('Memory_users_user123');
|
|
285
|
-
expect(schema.description).toContain('user123');
|
|
286
|
-
expect(schema.properties).toBeDefined();
|
|
287
|
-
expect(schema.vectorizers).toBeDefined();
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
it('should create space collection schema', () => {
|
|
291
|
-
const schema = createSpaceCollectionSchema();
|
|
292
|
-
expect(schema.name).toBe('Memory_spaces_public');
|
|
293
|
-
expect(schema.properties).toBeDefined();
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
it('should create group collection schema', () => {
|
|
297
|
-
const schema = createGroupCollectionSchema('group456');
|
|
298
|
-
expect(schema.name).toBe('Memory_groups_group456');
|
|
299
|
-
expect(schema.properties).toBeDefined();
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
describe('Property lists', () => {
|
|
304
|
-
it('should get user collection properties', () => {
|
|
305
|
-
const props = getUserCollectionProperties();
|
|
306
|
-
expect(props).not.toContain('id'); // 'id' is reserved by Weaviate
|
|
307
|
-
expect(props).toContain('content');
|
|
308
|
-
expect(props).toContain('space_ids');
|
|
309
|
-
expect(props).toContain('group_ids');
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it('should get published collection properties', () => {
|
|
313
|
-
const props = getPublishedCollectionProperties();
|
|
314
|
-
expect(props).not.toContain('id'); // 'id' is reserved by Weaviate
|
|
315
|
-
expect(props).toContain('published_at');
|
|
316
|
-
expect(props).toContain('author_id');
|
|
317
|
-
});
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
describe('Collection name validation', () => {
|
|
321
|
-
it('should validate v2 collection names', () => {
|
|
322
|
-
expect(validateV2CollectionName('Memory_users_user123')).toBe(true);
|
|
323
|
-
expect(validateV2CollectionName('Memory_spaces_public')).toBe(true);
|
|
324
|
-
expect(validateV2CollectionName('Memory_groups_group456')).toBe(true);
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
it('should reject invalid collection names', () => {
|
|
328
|
-
expect(() => validateV2CollectionName('InvalidName')).toThrow('Invalid v2 collection name');
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
describe('Collection type detection', () => {
|
|
333
|
-
it('should detect collection types', () => {
|
|
334
|
-
expect(getCollectionType('Memory_users_user123')).toBe('users');
|
|
335
|
-
expect(getCollectionType('Memory_spaces_public')).toBe('spaces');
|
|
336
|
-
expect(getCollectionType('Memory_groups_group456')).toBe('groups');
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
describe('ID extraction', () => {
|
|
341
|
-
it('should extract user ID', () => {
|
|
342
|
-
expect(extractIdFromCollectionName('Memory_users_user123')).toBe('user123');
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
it('should extract group ID', () => {
|
|
346
|
-
expect(extractIdFromCollectionName('Memory_groups_group456')).toBe('group456');
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
it('should return null for spaces collection', () => {
|
|
350
|
-
expect(extractIdFromCollectionName('Memory_spaces_public')).toBeNull();
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
});
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dot Notation Collection Utilities
|
|
3
|
-
*
|
|
4
|
-
* Provides utilities for working with Memory Collection Pattern v2's
|
|
5
|
-
* dot notation collection naming scheme.
|
|
6
|
-
*
|
|
7
|
-
* Collection Types:
|
|
8
|
-
* - USERS: Memory_users_{userId} - Private user memories
|
|
9
|
-
* - SPACES: Memory_spaces_public - All public space memories
|
|
10
|
-
* - GROUPS: Memory_groups_{groupId} - Group memories
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Collection type enum for Memory Collection Pattern v2
|
|
15
|
-
*/
|
|
16
|
-
export enum CollectionType {
|
|
17
|
-
USERS = 'USERS',
|
|
18
|
-
SPACES = 'SPACES',
|
|
19
|
-
GROUPS = 'GROUPS',
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Metadata about a parsed collection
|
|
24
|
-
*/
|
|
25
|
-
export interface CollectionMetadata {
|
|
26
|
-
type: CollectionType
|
|
27
|
-
id?: string
|
|
28
|
-
name: string
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Error thrown when collection name is invalid
|
|
33
|
-
*/
|
|
34
|
-
export class InvalidCollectionNameError extends Error {
|
|
35
|
-
constructor(message: string) {
|
|
36
|
-
super(message)
|
|
37
|
-
this.name = 'InvalidCollectionNameError'
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get the Weaviate collection name for a given type and optional ID
|
|
43
|
-
*
|
|
44
|
-
* @param type - Collection type (USERS, SPACES, or GROUPS)
|
|
45
|
-
* @param id - Optional ID (required for USERS and GROUPS, not used for SPACES)
|
|
46
|
-
* @returns Weaviate collection name
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* getCollectionName(CollectionType.USERS, 'user123')
|
|
50
|
-
* // Returns: 'Memory_users_user123'
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* getCollectionName(CollectionType.SPACES)
|
|
54
|
-
* // Returns: 'Memory_spaces_public'
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* getCollectionName(CollectionType.GROUPS, 'group456')
|
|
58
|
-
* // Returns: 'Memory_groups_group456'
|
|
59
|
-
*/
|
|
60
|
-
export function getCollectionName(type: CollectionType, id?: string): string {
|
|
61
|
-
switch (type) {
|
|
62
|
-
case CollectionType.USERS:
|
|
63
|
-
if (!id) {
|
|
64
|
-
throw new InvalidCollectionNameError('User ID is required for USERS collection type')
|
|
65
|
-
}
|
|
66
|
-
if (id.includes('.')) {
|
|
67
|
-
throw new InvalidCollectionNameError(`User ID cannot contain dots: ${id}`)
|
|
68
|
-
}
|
|
69
|
-
return `Memory_users_${id}`
|
|
70
|
-
|
|
71
|
-
case CollectionType.SPACES:
|
|
72
|
-
// SPACES collection is always public, ID is not used
|
|
73
|
-
return 'Memory_spaces_public'
|
|
74
|
-
|
|
75
|
-
case CollectionType.GROUPS:
|
|
76
|
-
if (!id) {
|
|
77
|
-
throw new InvalidCollectionNameError('Group ID is required for GROUPS collection type')
|
|
78
|
-
}
|
|
79
|
-
if (id.includes('.')) {
|
|
80
|
-
throw new InvalidCollectionNameError(`Group ID cannot contain dots: ${id}`)
|
|
81
|
-
}
|
|
82
|
-
return `Memory_groups_${id}`
|
|
83
|
-
|
|
84
|
-
default:
|
|
85
|
-
throw new InvalidCollectionNameError(`Unknown collection type: ${type}`)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Parse a collection name into its components
|
|
91
|
-
*
|
|
92
|
-
* @param name - Weaviate collection name
|
|
93
|
-
* @returns Collection metadata with type, optional ID, and name
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* parseCollectionName('Memory_users_user123')
|
|
97
|
-
* // Returns: { type: CollectionType.USERS, id: 'user123', name: 'Memory_users_user123' }
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* parseCollectionName('Memory_spaces_public')
|
|
101
|
-
* // Returns: { type: CollectionType.SPACES, id: undefined, name: 'Memory_spaces_public' }
|
|
102
|
-
*
|
|
103
|
-
* @example
|
|
104
|
-
* parseCollectionName('Memory_groups_group456')
|
|
105
|
-
* // Returns: { type: CollectionType.GROUPS, id: 'group456', name: 'Memory_groups_group456' }
|
|
106
|
-
*/
|
|
107
|
-
export function parseCollectionName(name: string): CollectionMetadata {
|
|
108
|
-
// Match pattern: Memory_{type}_{id} or Memory_{type}_public
|
|
109
|
-
const match = name.match(/^Memory_(users|spaces|groups)_(.+)$/)
|
|
110
|
-
|
|
111
|
-
if (!match) {
|
|
112
|
-
throw new InvalidCollectionNameError(
|
|
113
|
-
`Invalid collection name format: ${name}. Expected format: Memory_{type}_{id}`
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const [, typeStr, idOrPublic] = match
|
|
118
|
-
|
|
119
|
-
switch (typeStr) {
|
|
120
|
-
case 'users':
|
|
121
|
-
return {
|
|
122
|
-
type: CollectionType.USERS,
|
|
123
|
-
id: idOrPublic,
|
|
124
|
-
name,
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
case 'spaces':
|
|
128
|
-
if (idOrPublic !== 'public') {
|
|
129
|
-
throw new InvalidCollectionNameError(
|
|
130
|
-
`Invalid SPACES collection name: ${name}. Expected: Memory_spaces_public`
|
|
131
|
-
)
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
type: CollectionType.SPACES,
|
|
135
|
-
id: undefined,
|
|
136
|
-
name,
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
case 'groups':
|
|
140
|
-
return {
|
|
141
|
-
type: CollectionType.GROUPS,
|
|
142
|
-
id: idOrPublic,
|
|
143
|
-
name,
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
default:
|
|
147
|
-
throw new InvalidCollectionNameError(`Unknown collection type: ${typeStr}`)
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Validate a collection name
|
|
153
|
-
*
|
|
154
|
-
* @param name - Collection name to validate
|
|
155
|
-
* @returns true if valid, false otherwise
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* validateCollectionName('Memory_users_user123') // true
|
|
159
|
-
* validateCollectionName('Memory_spaces_public') // true
|
|
160
|
-
* validateCollectionName('Invalid_name') // false
|
|
161
|
-
*/
|
|
162
|
-
export function validateCollectionName(name: string): boolean {
|
|
163
|
-
try {
|
|
164
|
-
parseCollectionName(name)
|
|
165
|
-
return true
|
|
166
|
-
} catch (error) {
|
|
167
|
-
if (error instanceof InvalidCollectionNameError) {
|
|
168
|
-
return false
|
|
169
|
-
}
|
|
170
|
-
throw error
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Check if a collection name is a user collection
|
|
176
|
-
*
|
|
177
|
-
* @param name - Collection name to check
|
|
178
|
-
* @returns true if user collection, false otherwise
|
|
179
|
-
*/
|
|
180
|
-
export function isUserCollection(name: string): boolean {
|
|
181
|
-
try {
|
|
182
|
-
const metadata = parseCollectionName(name)
|
|
183
|
-
return metadata.type === CollectionType.USERS
|
|
184
|
-
} catch {
|
|
185
|
-
return false
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Check if a collection name is the spaces collection
|
|
191
|
-
*
|
|
192
|
-
* @param name - Collection name to check
|
|
193
|
-
* @returns true if spaces collection, false otherwise
|
|
194
|
-
*/
|
|
195
|
-
export function isSpacesCollection(name: string): boolean {
|
|
196
|
-
return name === 'Memory_spaces_public'
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Check if a collection name is a group collection
|
|
201
|
-
*
|
|
202
|
-
* @param name - Collection name to check
|
|
203
|
-
* @returns true if group collection, false otherwise
|
|
204
|
-
*/
|
|
205
|
-
export function isGroupCollection(name: string): boolean {
|
|
206
|
-
try {
|
|
207
|
-
const metadata = parseCollectionName(name)
|
|
208
|
-
return metadata.type === CollectionType.GROUPS
|
|
209
|
-
} catch {
|
|
210
|
-
return false
|
|
211
|
-
}
|
|
212
|
-
}
|