@brew-cms/api 0.2.1 → 0.2.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.
@@ -0,0 +1,13 @@
1
+ export interface ApiErrorEnvelope {
2
+ error: {
3
+ code: string;
4
+ message: string;
5
+ requestId?: string;
6
+ details?: unknown;
7
+ };
8
+ }
9
+ export declare function formatErrorResponse(err: unknown, requestId?: string): {
10
+ status: number;
11
+ body: ApiErrorEnvelope;
12
+ };
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CA2B5C"}
package/dist/errors.js ADDED
@@ -0,0 +1,29 @@
1
+ import { DomainError } from '@brew-cms/core';
2
+ export function formatErrorResponse(err, requestId) {
3
+ if (err instanceof DomainError) {
4
+ return {
5
+ status: err.statusCode,
6
+ body: {
7
+ error: {
8
+ code: err.code,
9
+ message: err.message,
10
+ requestId,
11
+ details: err.details,
12
+ },
13
+ },
14
+ };
15
+ }
16
+ // Fallback for unexpected internal errors: NEVER expose raw stack traces or internal SQL details
17
+ const fallbackMessage = err instanceof Error ? err.message : 'An unexpected internal error occurred.';
18
+ return {
19
+ status: 500,
20
+ body: {
21
+ error: {
22
+ code: 'INTERNAL_ERROR',
23
+ message: fallbackMessage,
24
+ requestId,
25
+ },
26
+ },
27
+ };
28
+ }
29
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAW7C,MAAM,UAAU,mBAAmB,CACjC,GAAY,EACZ,SAAkB;IAElB,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO;YACL,MAAM,EAAE,GAAG,CAAC,UAAU;YACtB,IAAI,EAAE;gBACJ,KAAK,EAAE;oBACL,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,SAAS;oBACT,OAAO,EAAE,GAAG,CAAC,OAAO;iBACrB;aACF;SACF,CAAC;IACJ,CAAC;IAED,iGAAiG;IACjG,MAAM,eAAe,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,wCAAwC,CAAC;IACtG,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI,EAAE;YACJ,KAAK,EAAE;gBACL,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE,eAAe;gBACxB,SAAS;aACV;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface IdempotencyRecord {
2
+ key: string;
3
+ actorId: string;
4
+ responseStatus: number;
5
+ responseBody: unknown;
6
+ expiresAt: Date;
7
+ }
8
+ export declare class InMemoryIdempotencyStore {
9
+ private cache;
10
+ get(key: string, actorId: string): IdempotencyRecord | null;
11
+ set(key: string, actorId: string, responseStatus: number, responseBody: unknown, ttlSeconds?: number): void;
12
+ }
13
+ //# sourceMappingURL=idempotency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../src/idempotency.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,KAAK,CAAwC;IAErD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAY3D,GAAG,CACD,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,OAAO,EACrB,UAAU,GAAE,MAAa,GACxB,IAAI;CAWR"}
@@ -0,0 +1,26 @@
1
+ export class InMemoryIdempotencyStore {
2
+ cache = new Map();
3
+ get(key, actorId) {
4
+ const compositeKey = `${actorId}:${key}`;
5
+ const record = this.cache.get(compositeKey);
6
+ if (!record)
7
+ return null;
8
+ if (record.expiresAt < new Date()) {
9
+ this.cache.delete(compositeKey);
10
+ return null;
11
+ }
12
+ return record;
13
+ }
14
+ set(key, actorId, responseStatus, responseBody, ttlSeconds = 3600) {
15
+ const compositeKey = `${actorId}:${key}`;
16
+ const expiresAt = new Date(Date.now() + ttlSeconds * 1000);
17
+ this.cache.set(compositeKey, {
18
+ key,
19
+ actorId,
20
+ responseStatus,
21
+ responseBody,
22
+ expiresAt,
23
+ });
24
+ }
25
+ }
26
+ //# sourceMappingURL=idempotency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../src/idempotency.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,wBAAwB;IAC3B,KAAK,GAAG,IAAI,GAAG,EAA6B,CAAC;IAErD,GAAG,CAAC,GAAW,EAAE,OAAe;QAC9B,MAAM,YAAY,GAAG,GAAG,OAAO,IAAI,GAAG,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,GAAG,CACD,GAAW,EACX,OAAe,EACf,cAAsB,EACtB,YAAqB,EACrB,aAAqB,IAAI;QAEzB,MAAM,YAAY,GAAG,GAAG,OAAO,IAAI,GAAG,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE;YAC3B,GAAG;YACH,OAAO;YACP,cAAc;YACd,YAAY;YACZ,SAAS;SACV,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -2,3 +2,4 @@ export * from './errors.js';
2
2
  export * from './idempotency.js';
3
3
  export * from './validators.js';
4
4
  export * from './router.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { Actor, DocumentService, WorkflowService, AgentService, AuditService, TaxonomyService, RevisionRepository, MediaProvider, MediaAssetRepository, AgentRepository } from '@brew-cms/core';
2
+ import type { SourceRegistry, IndexingService, HybridRetrievalService, CanonicalSourceResolver } from '@brew-cms/intelligence';
3
+ import { InMemoryIdempotencyStore } from './idempotency.js';
4
+ export interface ApiRequest {
5
+ method: string;
6
+ path: string;
7
+ query?: Record<string, string | undefined>;
8
+ headers?: Record<string, string | undefined>;
9
+ body?: unknown;
10
+ actor: Actor;
11
+ }
12
+ export interface ApiResponse {
13
+ status: number;
14
+ headers?: Record<string, string>;
15
+ body: unknown;
16
+ }
17
+ export interface ApiContext {
18
+ documentService: DocumentService;
19
+ workflowService: WorkflowService;
20
+ agentService: AgentService;
21
+ auditService: AuditService;
22
+ taxonomyService: TaxonomyService;
23
+ revisionRepo: RevisionRepository;
24
+ mediaProvider?: MediaProvider;
25
+ mediaRepo?: MediaAssetRepository;
26
+ agentRepo?: AgentRepository;
27
+ idempotencyStore?: InMemoryIdempotencyStore;
28
+ sourceRegistry?: SourceRegistry;
29
+ indexingService?: IndexingService;
30
+ retrievalService?: HybridRetrievalService;
31
+ canonicalResolver?: CanonicalSourceResolver;
32
+ }
33
+ export declare function handleApiRequest(req: ApiRequest, ctx: ApiContext): Promise<ApiResponse>;
34
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,eAAe,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAW5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,EAAE,kBAAkB,CAAC;IACjC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IAC5C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;CAC7C;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,WAAW,CAAC,CAiCtB"}
package/dist/router.js ADDED
@@ -0,0 +1,436 @@
1
+ import { compileContent } from '@brew-cms/content';
2
+ import { formatErrorResponse } from './errors.js';
3
+ import { CreateDocumentRequestSchema, UpdateDocumentRequestSchema, PublishDocumentRequestSchema, ScheduleDocumentRequestSchema, CreateTopicRequestSchema, CreateTagRequestSchema, CreateSeriesRequestSchema, } from './validators.js';
4
+ export async function handleApiRequest(req, ctx) {
5
+ const idempotencyKey = req.headers?.['idempotency-key'];
6
+ const idempotencyStore = ctx.idempotencyStore;
7
+ // 1. Idempotency Check for mutations
8
+ if (idempotencyKey && req.method !== 'GET' && idempotencyStore) {
9
+ const cached = idempotencyStore.get(idempotencyKey, req.actor.id);
10
+ if (cached) {
11
+ return {
12
+ status: cached.responseStatus,
13
+ headers: { 'X-Cache-Lookup': 'HIT', 'Idempotency-Key': idempotencyKey },
14
+ body: cached.responseBody,
15
+ };
16
+ }
17
+ }
18
+ try {
19
+ const response = await dispatchRoute(req, ctx);
20
+ // Save in idempotency store if mutation
21
+ if (idempotencyKey && req.method !== 'GET' && idempotencyStore && response.status < 400) {
22
+ idempotencyStore.set(idempotencyKey, req.actor.id, response.status, response.body);
23
+ }
24
+ return response;
25
+ }
26
+ catch (err) {
27
+ const errorFormatted = formatErrorResponse(err, req.headers?.['x-request-id']);
28
+ return {
29
+ status: errorFormatted.status,
30
+ headers: { 'Content-Type': 'application/json' },
31
+ body: errorFormatted.body,
32
+ };
33
+ }
34
+ }
35
+ async function dispatchRoute(req, ctx) {
36
+ const { path: rawPath, method, actor } = req;
37
+ const urlPath = rawPath.replace(/\/$/, '');
38
+ // 1. Health Endpoints
39
+ if (urlPath === '/api/health/live' && method === 'GET') {
40
+ return { status: 200, body: { status: 'live', timestamp: new Date().toISOString() } };
41
+ }
42
+ if (urlPath === '/api/health/ready' && method === 'GET') {
43
+ return { status: 200, body: { status: 'ready', database: 'connected', timestamp: new Date().toISOString() } };
44
+ }
45
+ // 2. Documents
46
+ if (urlPath === '/api/v1/documents') {
47
+ if (method === 'GET') {
48
+ const result = await ctx.documentService.listDocuments({
49
+ type: req.query?.type,
50
+ status: req.query?.status,
51
+ query: req.query?.q,
52
+ limit: req.query?.limit ? Number(req.query.limit) : undefined,
53
+ });
54
+ return { status: 200, body: result };
55
+ }
56
+ if (method === 'POST') {
57
+ const validated = CreateDocumentRequestSchema.parse(req.body);
58
+ const compiled = compileContent(validated.sourceMarkdown, {
59
+ frontmatterDefaults: validated.frontmatter,
60
+ });
61
+ const res = await ctx.documentService.createDraft(actor, {
62
+ type: validated.type,
63
+ slug: validated.slug,
64
+ title: validated.title,
65
+ excerpt: validated.excerpt,
66
+ sourceMarkdown: compiled.sourceMarkdown,
67
+ frontmatter: compiled.frontmatter,
68
+ contentIr: compiled.contentIr,
69
+ contentHash: compiled.contentHash,
70
+ compilerVersion: compiled.compilerVersion,
71
+ wordCount: compiled.wordCount,
72
+ readingTimeSeconds: compiled.readingTimeSeconds,
73
+ seo: validated.seo,
74
+ });
75
+ return { status: 201, body: res };
76
+ }
77
+ }
78
+ // Document by ID: /api/v1/documents/:id
79
+ const docIdMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)$/);
80
+ if (docIdMatch) {
81
+ const id = docIdMatch[1];
82
+ if (method === 'GET') {
83
+ const doc = await ctx.documentService.getDocument(id);
84
+ return { status: 200, body: doc };
85
+ }
86
+ if (method === 'PUT') {
87
+ const validated = UpdateDocumentRequestSchema.parse(req.body);
88
+ let compiled;
89
+ if (validated.sourceMarkdown !== undefined) {
90
+ compiled = compileContent(validated.sourceMarkdown, {
91
+ frontmatterDefaults: validated.frontmatter,
92
+ });
93
+ }
94
+ const res = await ctx.documentService.updateDraft(actor, id, {
95
+ title: validated.title,
96
+ slug: validated.slug,
97
+ excerpt: validated.excerpt,
98
+ sourceMarkdown: compiled?.sourceMarkdown,
99
+ frontmatter: compiled?.frontmatter,
100
+ contentIr: compiled?.contentIr,
101
+ contentHash: compiled?.contentHash,
102
+ compilerVersion: compiled?.compilerVersion,
103
+ wordCount: compiled?.wordCount,
104
+ readingTimeSeconds: compiled?.readingTimeSeconds,
105
+ seo: validated.seo,
106
+ changeSummary: validated.changeSummary,
107
+ });
108
+ return { status: 200, body: res };
109
+ }
110
+ if (method === 'DELETE') {
111
+ await ctx.documentService.deleteDocument(actor, id);
112
+ return { status: 200, body: { success: true, id } };
113
+ }
114
+ }
115
+ // Revisions for document: /api/v1/documents/:id/revisions
116
+ const revMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/revisions$/);
117
+ if (revMatch && method === 'GET') {
118
+ const id = revMatch[1];
119
+ const revisions = await ctx.revisionRepo.listByDocumentId(id);
120
+ return { status: 200, body: { revisions } };
121
+ }
122
+ // Publish: /api/v1/documents/:id/publish
123
+ const publishMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/publish$/);
124
+ if (publishMatch && method === 'POST') {
125
+ const id = publishMatch[1];
126
+ const validated = PublishDocumentRequestSchema.parse(req.body || {});
127
+ const res = await ctx.workflowService.publish(actor, id, validated.revisionId);
128
+ return { status: 200, body: res };
129
+ }
130
+ // Submit for review: /api/v1/documents/:id/submit
131
+ const submitMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/submit$/);
132
+ if (submitMatch && method === 'POST') {
133
+ const id = submitMatch[1];
134
+ const revisionId = req.body?.revisionId;
135
+ const res = await ctx.workflowService.submitForReview(actor, id, revisionId);
136
+ return { status: 200, body: res };
137
+ }
138
+ // Approve: /api/v1/documents/:id/approve
139
+ const approveMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/approve$/);
140
+ if (approveMatch && method === 'POST') {
141
+ const id = approveMatch[1];
142
+ const revisionId = req.body?.revisionId;
143
+ const res = await ctx.workflowService.approve(actor, id, revisionId);
144
+ return { status: 200, body: res };
145
+ }
146
+ // Request Changes: /api/v1/documents/:id/request-changes
147
+ const reqChangesMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/request-changes$/);
148
+ if (reqChangesMatch && method === 'POST') {
149
+ const id = reqChangesMatch[1];
150
+ const reason = req.body?.reason;
151
+ const res = await ctx.workflowService.requestChanges(actor, id, reason);
152
+ return { status: 200, body: res };
153
+ }
154
+ // Unpublish: /api/v1/documents/:id/unpublish
155
+ const unpublishMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/unpublish$/);
156
+ if (unpublishMatch && method === 'POST') {
157
+ const id = unpublishMatch[1];
158
+ const res = await ctx.workflowService.unpublish(actor, id);
159
+ return { status: 200, body: res };
160
+ }
161
+ // Archive: /api/v1/documents/:id/archive
162
+ const archiveMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/archive$/);
163
+ if (archiveMatch && method === 'POST') {
164
+ const id = archiveMatch[1];
165
+ const res = await ctx.workflowService.archive(actor, id);
166
+ return { status: 200, body: res };
167
+ }
168
+ // Restore Revision: /api/v1/documents/:id/restore
169
+ const restoreMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/restore$/);
170
+ if (restoreMatch && method === 'POST') {
171
+ const id = restoreMatch[1];
172
+ const targetRevId = req.body?.revisionId;
173
+ const changeSummary = req.body?.changeSummary;
174
+ const res = await ctx.workflowService.restoreRevision(actor, id, targetRevId, changeSummary);
175
+ return { status: 200, body: res };
176
+ }
177
+ // Schedule: /api/v1/documents/:id/schedule
178
+ const scheduleMatch = urlPath.match(/^\/api\/v1\/documents\/([^/]+)\/schedule$/);
179
+ if (scheduleMatch && method === 'POST') {
180
+ const id = scheduleMatch[1];
181
+ const validated = ScheduleDocumentRequestSchema.parse(req.body);
182
+ const res = await ctx.workflowService.schedule(actor, id, new Date(validated.scheduledAt), validated.revisionId);
183
+ return { status: 200, body: res };
184
+ }
185
+ // Taxonomies: Topics
186
+ if (urlPath === '/api/v1/topics') {
187
+ if (method === 'GET') {
188
+ const items = await ctx.taxonomyService.listTopics();
189
+ return { status: 200, body: { items } };
190
+ }
191
+ if (method === 'POST') {
192
+ const validated = CreateTopicRequestSchema.parse(req.body);
193
+ const res = await ctx.taxonomyService.createTopic({
194
+ id: `top_${validated.slug}`,
195
+ ...validated,
196
+ });
197
+ return { status: 201, body: res };
198
+ }
199
+ }
200
+ // Taxonomies: Tags
201
+ if (urlPath === '/api/v1/tags') {
202
+ if (method === 'GET') {
203
+ const items = await ctx.taxonomyService.listTags();
204
+ return { status: 200, body: { items } };
205
+ }
206
+ if (method === 'POST') {
207
+ const validated = CreateTagRequestSchema.parse(req.body);
208
+ const res = await ctx.taxonomyService.createTag({
209
+ id: `tag_${validated.slug}`,
210
+ ...validated,
211
+ });
212
+ return { status: 201, body: res };
213
+ }
214
+ }
215
+ // Taxonomies: Series
216
+ if (urlPath === '/api/v1/series') {
217
+ if (method === 'GET') {
218
+ const items = await ctx.taxonomyService.listSeries();
219
+ return { status: 200, body: { items } };
220
+ }
221
+ if (method === 'POST') {
222
+ const validated = CreateSeriesRequestSchema.parse(req.body);
223
+ const res = await ctx.taxonomyService.createSeries({
224
+ id: `ser_${validated.slug}`,
225
+ ...validated,
226
+ });
227
+ return { status: 201, body: res };
228
+ }
229
+ }
230
+ // Media: /api/v1/media
231
+ if (urlPath === '/api/v1/media') {
232
+ if (method === 'GET') {
233
+ const items = ctx.mediaRepo
234
+ ? await ctx.mediaRepo.list({
235
+ mimeType: req.query?.mimeType,
236
+ limit: req.query?.limit ? Number(req.query.limit) : 50,
237
+ })
238
+ : [];
239
+ return { status: 200, body: { items } };
240
+ }
241
+ if (method === 'POST') {
242
+ const body = req.body;
243
+ if (!ctx.mediaRepo) {
244
+ return { status: 500, body: { error: { code: 'NO_MEDIA_REPO', message: 'Media repository not configured.' } } };
245
+ }
246
+ let stored = null;
247
+ if (ctx.mediaProvider && body.contentBase64) {
248
+ stored = await ctx.mediaProvider.put({
249
+ filename: body.filename,
250
+ mimeType: body.mimeType,
251
+ content: Buffer.from(body.contentBase64, 'base64'),
252
+ prefix: body.prefix,
253
+ });
254
+ }
255
+ const asset = await ctx.mediaRepo.create({
256
+ id: body.id || `med_${Date.now()}`,
257
+ provider: stored?.provider || 'local',
258
+ providerKey: stored?.providerKey || body.providerKey || body.filename,
259
+ mimeType: body.mimeType || 'application/octet-stream',
260
+ sizeBytes: stored?.sizeBytes || body.sizeBytes || 0,
261
+ width: body.width ?? null,
262
+ height: body.height ?? null,
263
+ altText: body.altText ?? null,
264
+ caption: body.caption ?? null,
265
+ metadata: body.metadata ?? null,
266
+ createdBy: actor.id,
267
+ });
268
+ return { status: 201, body: asset };
269
+ }
270
+ }
271
+ // Audit Events
272
+ if (urlPath === '/api/v1/audit' && method === 'GET') {
273
+ const events = await ctx.auditService.listEvents({
274
+ resourceType: req.query?.resourceType,
275
+ resourceId: req.query?.resourceId,
276
+ actorId: req.query?.actorId,
277
+ limit: req.query?.limit ? Number(req.query.limit) : 50,
278
+ });
279
+ return { status: 200, body: { items: events } };
280
+ }
281
+ // Agents: /api/v1/agents
282
+ if (urlPath === '/api/v1/agents') {
283
+ if (method === 'GET') {
284
+ const agents = await ctx.agentService.listAgents();
285
+ return { status: 200, body: { items: agents } };
286
+ }
287
+ if (method === 'POST') {
288
+ const body = req.body;
289
+ const agent = await ctx.agentService.registerAgent(actor, {
290
+ id: body.id,
291
+ name: body.name,
292
+ description: body.description,
293
+ scopes: body.scopes || [],
294
+ });
295
+ return { status: 201, body: agent };
296
+ }
297
+ }
298
+ // Agent Action Runs: /api/v1/agent/runs
299
+ if (urlPath === '/api/v1/agent/runs') {
300
+ if (method === 'GET') {
301
+ const runs = ctx.agentRepo
302
+ ? await ctx.agentRepo.listActionRuns({ limit: req.query?.limit ? Number(req.query.limit) : 50 })
303
+ : [];
304
+ return { status: 200, body: { items: runs } };
305
+ }
306
+ }
307
+ // Agent Action Run Approval: /api/v1/agent/runs/:id/approve
308
+ const approveRunMatch = urlPath.match(/^\/api\/v1\/agent\/runs\/([^/]+)\/approve$/);
309
+ if (approveRunMatch && method === 'POST') {
310
+ const runId = approveRunMatch[1];
311
+ const res = await ctx.agentService.approveActionRun(actor, runId, req.body?.reason);
312
+ return { status: 200, body: res };
313
+ }
314
+ // Agent Action Run Rejection: /api/v1/agent/runs/:id/reject
315
+ const rejectRunMatch = urlPath.match(/^\/api\/v1\/agent\/runs\/([^/]+)\/reject$/);
316
+ if (rejectRunMatch && method === 'POST') {
317
+ const runId = rejectRunMatch[1];
318
+ const res = await ctx.agentService.rejectActionRun(actor, runId, req.body?.reason);
319
+ return { status: 200, body: res };
320
+ }
321
+ // Intelligence: Status / Sources
322
+ if (urlPath === '/api/v1/intelligence/status' && method === 'GET') {
323
+ const registry = ctx.sourceRegistry ?? ctx.indexingService?.registry;
324
+ return {
325
+ status: 200,
326
+ body: {
327
+ status: 'operational',
328
+ hasIndexingService: Boolean(ctx.indexingService),
329
+ hasRetrievalService: Boolean(ctx.retrievalService),
330
+ hasCanonicalResolver: Boolean(ctx.canonicalResolver),
331
+ sources: registry
332
+ ? registry.list().map((s) => ({
333
+ id: s.sourceId,
334
+ capabilities: s.capabilities,
335
+ }))
336
+ : [],
337
+ },
338
+ };
339
+ }
340
+ // Intelligence: Hybrid Retrieval
341
+ if (urlPath === '/api/v1/intelligence/search' && method === 'GET') {
342
+ if (!ctx.retrievalService) {
343
+ return {
344
+ status: 503,
345
+ body: {
346
+ error: {
347
+ code: 'INTELLIGENCE_UNAVAILABLE',
348
+ message: 'Retrieval service is not configured.',
349
+ },
350
+ },
351
+ };
352
+ }
353
+ const q = req.query?.q;
354
+ if (!q || typeof q !== 'string') {
355
+ return {
356
+ status: 400,
357
+ body: {
358
+ error: {
359
+ code: 'INVALID_QUERY',
360
+ message: "Query parameter 'q' is required.",
361
+ },
362
+ },
363
+ };
364
+ }
365
+ const limit = req.query?.limit ? Number(req.query.limit) : 10;
366
+ const minScore = req.query?.minScore ? Number(req.query.minScore) : undefined;
367
+ const sourceId = req.query?.sourceId;
368
+ const results = await ctx.retrievalService.search({
369
+ query: q,
370
+ limit,
371
+ minScore,
372
+ sourceId,
373
+ });
374
+ const shouldResolve = req.query?.resolve === 'true' && ctx.canonicalResolver;
375
+ if (shouldResolve && ctx.canonicalResolver) {
376
+ const resolved = await ctx.canonicalResolver.resolveMany(results);
377
+ return {
378
+ status: 200,
379
+ body: {
380
+ query: q,
381
+ total: results.length,
382
+ items: resolved.map((r) => ({
383
+ reference: r.reference,
384
+ canonical: r.content,
385
+ error: r.error,
386
+ })),
387
+ },
388
+ };
389
+ }
390
+ return {
391
+ status: 200,
392
+ body: {
393
+ query: q,
394
+ total: results.length,
395
+ items: results,
396
+ },
397
+ };
398
+ }
399
+ // Intelligence: Indexing
400
+ if (urlPath === '/api/v1/intelligence/index' && method === 'POST') {
401
+ if (!ctx.indexingService) {
402
+ return {
403
+ status: 503,
404
+ body: {
405
+ error: {
406
+ code: 'INTELLIGENCE_UNAVAILABLE',
407
+ message: 'Indexing service is not configured.',
408
+ },
409
+ },
410
+ };
411
+ }
412
+ const body = (req.body || {});
413
+ if (body.sourceId && body.contentId) {
414
+ const result = await ctx.indexingService.indexDocument(body.sourceId, body.contentId, body.revisionId);
415
+ return { status: 200, body: { success: true, result } };
416
+ }
417
+ else if (body.sourceId) {
418
+ const summary = await ctx.indexingService.syncSource(body.sourceId);
419
+ return { status: 200, body: { success: true, summary } };
420
+ }
421
+ else {
422
+ const summaries = await ctx.indexingService.syncAll();
423
+ return { status: 200, body: { success: true, summaries } };
424
+ }
425
+ }
426
+ return {
427
+ status: 404,
428
+ body: {
429
+ error: {
430
+ code: 'ROUTE_NOT_FOUND',
431
+ message: `Endpoint '${method} ${urlPath}' was not found.`,
432
+ },
433
+ },
434
+ };
435
+ }
436
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}