feat(TRUEREF-0002): implement repository management service and REST API
Add RepositoryService with full CRUD, ID resolution helpers, input validation, six SvelteKit API routes (GET/POST /api/v1/libs, GET/PATCH/DELETE /api/v1/libs/:id, POST /api/v1/libs/:id/index), and 37 unit tests covering all service operations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
42
src/lib/server/utils/id-resolver.ts
Normal file
42
src/lib/server/utils/id-resolver.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Repository ID generation utilities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse a GitHub URL into a canonical repository ID.
|
||||
* Supports:
|
||||
* https://github.com/facebook/react
|
||||
* https://github.com/facebook/react.git
|
||||
* github.com/facebook/react
|
||||
*/
|
||||
export function resolveGitHubId(url: string): string {
|
||||
const match = url.match(/github\.com\/([^/]+)\/([^/\s.]+)/);
|
||||
if (!match) throw new Error('Invalid GitHub URL — expected github.com/owner/repo');
|
||||
return `/${match[1]}/${match[2]}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a local repository ID from an absolute path.
|
||||
* Collision-resolves by appending -2, -3, etc.
|
||||
*/
|
||||
export function resolveLocalId(path: string, existingIds: string[]): string {
|
||||
const base = slugify(path.split('/').at(-1) ?? 'repo');
|
||||
let id = `/local/${base}`;
|
||||
let counter = 2;
|
||||
while (existingIds.includes(id)) {
|
||||
id = `/local/${base}-${counter++}`;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slugify a string to be safe for use in IDs.
|
||||
*/
|
||||
function slugify(str: string): string {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9-_]/g, '-')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, '')
|
||||
|| 'repo';
|
||||
}
|
||||
Reference in New Issue
Block a user