@cogenta/cli 0.1.0
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/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +31 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/doctor.d.ts +45 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +147 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/generate.d.ts +19 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +60 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/import.d.ts +22 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +77 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/migrate.d.ts +38 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +272 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/serve.d.ts +81 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +515 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/skin.d.ts +24 -0
- package/dist/commands/skin.d.ts.map +1 -0
- package/dist/commands/skin.js +199 -0
- package/dist/commands/skin.js.map +1 -0
- package/dist/commands/users.d.ts +22 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +107 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +244 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +17 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +39 -0
- package/dist/output.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { buildContentSchema, createAgentsRouter, createAuditRouter, createAuthRouter, createContentGateway, createContentService, createMediaRouter, createPermissionLayer, createRestRouter, executeGraphQL, resolveActor, } from '@cogenta/api';
|
|
6
|
+
import { createAuthStore } from '@cogenta/auth';
|
|
7
|
+
import { CogentaError, createDatabaseMediaStore, createDatabaseRegistry, createLogger, createStorageRegistry, isCogentaError, loadConfig, } from '@cogenta/core';
|
|
8
|
+
import { buildSchemaDocument, createContentStore, createRedirectStore, createSchemaTables, withReadOnlyStore, } from '@cogenta/schema';
|
|
9
|
+
const SCHEMA_FILE_CANDIDATES = [
|
|
10
|
+
'cogenta.schema.ts',
|
|
11
|
+
'cogenta.schema.mts',
|
|
12
|
+
'cogenta.schema.mjs',
|
|
13
|
+
'cogenta.schema.js',
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Loads a project's content model.
|
|
17
|
+
*
|
|
18
|
+
* `cogenta.schema.ts` next to the config file, default-exporting the
|
|
19
|
+
* collections — the same "one file, dynamic-imported, next to the config"
|
|
20
|
+
* convention `migrate.ts` already established for migrations. A project with
|
|
21
|
+
* none is invalid here, unlike a project with no migrations: a site with zero
|
|
22
|
+
* collections has nothing to serve.
|
|
23
|
+
*/
|
|
24
|
+
export async function loadCollections(projectRoot) {
|
|
25
|
+
for (const candidate of SCHEMA_FILE_CANDIDATES) {
|
|
26
|
+
const path = join(projectRoot, candidate);
|
|
27
|
+
let module;
|
|
28
|
+
try {
|
|
29
|
+
module = (await import(pathToFileURL(path).href));
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (isModuleNotFound(error, path))
|
|
33
|
+
continue;
|
|
34
|
+
throw new CogentaError({
|
|
35
|
+
code: 'SCHEMA_INVALID',
|
|
36
|
+
message: `Could not load ${path}: ${error instanceof Error ? error.message : String(error)}`,
|
|
37
|
+
hint: 'Check the file for a syntax error, and that every import it uses is installed.',
|
|
38
|
+
cause: error,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const collections = module.default;
|
|
42
|
+
if (!Array.isArray(collections)) {
|
|
43
|
+
throw new CogentaError({
|
|
44
|
+
code: 'SCHEMA_INVALID',
|
|
45
|
+
message: `${path} must default-export an array of collections.`,
|
|
46
|
+
hint: 'Export the array defineCollection() built, the same one passed to createSchemaTables in tests.',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return collections;
|
|
50
|
+
}
|
|
51
|
+
throw new CogentaError({
|
|
52
|
+
code: 'SCHEMA_INVALID',
|
|
53
|
+
message: `No schema file found next to the configuration (looked for ${SCHEMA_FILE_CANDIDATES.join(', ')}).`,
|
|
54
|
+
hint: 'Create cogenta.schema.ts, default-exporting the array of collections defineCollection() built.',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* True only when the candidate file itself does not exist — never for a
|
|
59
|
+
* missing import *inside* it, which must surface as a real error rather than
|
|
60
|
+
* silently trying the next candidate filename.
|
|
61
|
+
*/
|
|
62
|
+
function isModuleNotFound(error, path) {
|
|
63
|
+
if (!(error instanceof Error &&
|
|
64
|
+
'code' in error &&
|
|
65
|
+
error.code === 'ERR_MODULE_NOT_FOUND')) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
// Node's own message embeds the missing specifier either as the file://
|
|
69
|
+
// URL passed to import(), or — observed on Windows — as the raw OS path.
|
|
70
|
+
// Matching only the URL form left every Windows run unable to fall
|
|
71
|
+
// through the candidate list: the first missing extension (typically
|
|
72
|
+
// `.ts`) surfaced as a hard SCHEMA_INVALID instead of trying the next one.
|
|
73
|
+
return error.message.includes(pathToFileURL(path).href) || error.message.includes(path);
|
|
74
|
+
}
|
|
75
|
+
/** `relyingPartyId` is the bare host: WebAuthn ties a passkey to a domain, not a URL. */
|
|
76
|
+
function webauthnConfigFor(site) {
|
|
77
|
+
const host = new URL(site.url).hostname;
|
|
78
|
+
return { relyingPartyName: site.name, relyingPartyId: host, origin: site.url };
|
|
79
|
+
}
|
|
80
|
+
async function assembleSite(db, collections, signingKey, site, storage, health,
|
|
81
|
+
/** Optional: no caller constructs an agent registry today, and `/api/agents` simply is not mounted when this is absent — see `agentsRouter` on `Site`. */
|
|
82
|
+
agents,
|
|
83
|
+
/**
|
|
84
|
+
* "Commencer par une démo en lecture seule" (L9 tâche 12, playground). Every
|
|
85
|
+
* write REST or GraphQL could attempt refuses with `CONTENT_READ_ONLY`
|
|
86
|
+
* instead of landing — wrapped once here, at the one place both transports'
|
|
87
|
+
* stores are actually constructed, so neither can bypass it.
|
|
88
|
+
*/
|
|
89
|
+
readOnly = false) {
|
|
90
|
+
await createSchemaTables(db, collections);
|
|
91
|
+
const stores = new Map();
|
|
92
|
+
const storeFor = (collection) => {
|
|
93
|
+
const existing = stores.get(collection.name);
|
|
94
|
+
if (existing !== undefined)
|
|
95
|
+
return existing;
|
|
96
|
+
const created = createContentStore({ db, collection });
|
|
97
|
+
const stored = readOnly ? withReadOnlyStore(created) : created;
|
|
98
|
+
stores.set(collection.name, stored);
|
|
99
|
+
return stored;
|
|
100
|
+
};
|
|
101
|
+
const redirects = createRedirectStore({ db });
|
|
102
|
+
await redirects.ensureTable();
|
|
103
|
+
const permissions = createPermissionLayer({ collections });
|
|
104
|
+
const service = createContentService({
|
|
105
|
+
collections,
|
|
106
|
+
permissions,
|
|
107
|
+
storeFor,
|
|
108
|
+
routing: { locales: site.locales, defaultLocale: site.defaultLocale, redirects },
|
|
109
|
+
});
|
|
110
|
+
const auth = await createAuthStore({
|
|
111
|
+
db,
|
|
112
|
+
signingKey,
|
|
113
|
+
collections,
|
|
114
|
+
issuer: site.name,
|
|
115
|
+
webauthn: webauthnConfigFor(site),
|
|
116
|
+
});
|
|
117
|
+
const mediaStore = createDatabaseMediaStore({ db });
|
|
118
|
+
return {
|
|
119
|
+
db,
|
|
120
|
+
auth,
|
|
121
|
+
restRouter: createRestRouter({ service, siteUrl: site.url }),
|
|
122
|
+
authRouter: createAuthRouter({ auth }),
|
|
123
|
+
mediaRouter: createMediaRouter({ store: mediaStore, storage }),
|
|
124
|
+
auditRouter: createAuditRouter({ audit: auth.audit }),
|
|
125
|
+
...(agents === undefined ? {} : { agentsRouter: createAgentsRouter(agents) }),
|
|
126
|
+
mediaStore,
|
|
127
|
+
storage,
|
|
128
|
+
graphqlSchema: buildContentSchema({ collections }),
|
|
129
|
+
gateway: createContentGateway({ collections, stores, permissions }),
|
|
130
|
+
schemaDocument: buildSchemaDocument(collections, {
|
|
131
|
+
locales: site.locales,
|
|
132
|
+
defaultLocale: site.defaultLocale,
|
|
133
|
+
}),
|
|
134
|
+
health,
|
|
135
|
+
dispose: async () => {
|
|
136
|
+
await db.close();
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async function readBody(req) {
|
|
141
|
+
const chunks = [];
|
|
142
|
+
for await (const chunk of req)
|
|
143
|
+
chunks.push(chunk);
|
|
144
|
+
if (chunks.length === 0)
|
|
145
|
+
return undefined;
|
|
146
|
+
const text = Buffer.concat(chunks).toString('utf8');
|
|
147
|
+
if (text.trim().length === 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
try {
|
|
150
|
+
return JSON.parse(text);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
throw new CogentaError({
|
|
154
|
+
code: 'QUERY_INVALID',
|
|
155
|
+
message: 'The request body is not valid JSON.',
|
|
156
|
+
hint: 'Send a JSON body with a matching Content-Type, or no body at all.',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function toRestRequest(req, url, body) {
|
|
161
|
+
const query = {};
|
|
162
|
+
for (const key of url.searchParams.keys()) {
|
|
163
|
+
const values = url.searchParams.getAll(key);
|
|
164
|
+
query[key] = values.length > 1 ? values : values[0];
|
|
165
|
+
}
|
|
166
|
+
const headers = {};
|
|
167
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
168
|
+
headers[key] = Array.isArray(value) ? value.join(', ') : value;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
method: req.method ?? 'GET',
|
|
172
|
+
path: url.pathname,
|
|
173
|
+
query,
|
|
174
|
+
headers,
|
|
175
|
+
...(body === undefined ? {} : { body }),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function responseId(response) {
|
|
179
|
+
const data = response.body?.data;
|
|
180
|
+
return typeof data?.id === 'string' ? data.id : undefined;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Every mutation lands in `@cogenta/auth`'s hash-chained audit log
|
|
184
|
+
* (`packages/auth/src/audit.ts`), which existed since L2's own `AuthStore`
|
|
185
|
+
* was built but had no writer until now. Recording here, at the transport
|
|
186
|
+
* boundary, rather than inside `ContentService`/`MediaRouter`, means every
|
|
187
|
+
* route that mutates something is covered by one place instead of every
|
|
188
|
+
* write path remembering to call it — the same reasoning that keeps actor
|
|
189
|
+
* resolution itself at this layer rather than duplicated per route.
|
|
190
|
+
*
|
|
191
|
+
* Never blocks or fails the response it is auditing: a write that succeeded
|
|
192
|
+
* must reach the caller whether or not the audit row could be appended, and
|
|
193
|
+
* a broken audit log is something `verify()` surfaces on its own.
|
|
194
|
+
*/
|
|
195
|
+
async function recordContentAudit(site, actor, method, pathname, body, response, logger) {
|
|
196
|
+
if (response.status < 200 || response.status >= 300)
|
|
197
|
+
return;
|
|
198
|
+
const segments = pathname
|
|
199
|
+
.replace(/^\/api\/content\/?/u, '')
|
|
200
|
+
.split('/')
|
|
201
|
+
.filter((segment) => segment.length > 0);
|
|
202
|
+
const [collection, id, subAction] = segments;
|
|
203
|
+
if (collection === undefined || collection === '-')
|
|
204
|
+
return;
|
|
205
|
+
const action = subAction === 'publish'
|
|
206
|
+
? 'content.publish'
|
|
207
|
+
: subAction === 'restore'
|
|
208
|
+
? 'content.restore'
|
|
209
|
+
: subAction !== undefined
|
|
210
|
+
? null // history/diff/preview/translations are reads
|
|
211
|
+
: method === 'POST'
|
|
212
|
+
? 'content.create'
|
|
213
|
+
: method === 'PATCH' || method === 'PUT'
|
|
214
|
+
? 'content.update'
|
|
215
|
+
: method === 'DELETE'
|
|
216
|
+
? 'content.delete'
|
|
217
|
+
: null;
|
|
218
|
+
if (action === null)
|
|
219
|
+
return;
|
|
220
|
+
const entryId = id ?? responseId(response);
|
|
221
|
+
const values = typeof body === 'object' && body !== null && 'values' in body
|
|
222
|
+
? body.values
|
|
223
|
+
: undefined;
|
|
224
|
+
await site.auth.audit
|
|
225
|
+
.record({
|
|
226
|
+
actorId: actor.id,
|
|
227
|
+
actorRoles: actor.roles,
|
|
228
|
+
action,
|
|
229
|
+
collection,
|
|
230
|
+
...(entryId === undefined ? {} : { entryId }),
|
|
231
|
+
...(values === undefined ? {} : { diff: values }),
|
|
232
|
+
})
|
|
233
|
+
.catch((error) => logger.error('audit record failed', { error: String(error) }));
|
|
234
|
+
}
|
|
235
|
+
async function recordMediaAudit(site, actor, method, pathname, response, logger) {
|
|
236
|
+
if (response.status < 200 || response.status >= 300)
|
|
237
|
+
return;
|
|
238
|
+
const [id] = pathname
|
|
239
|
+
.replace(/^\/api\/media\/?/u, '')
|
|
240
|
+
.split('/')
|
|
241
|
+
.filter((segment) => segment.length > 0);
|
|
242
|
+
const action = method === 'POST'
|
|
243
|
+
? 'media.upload'
|
|
244
|
+
: method === 'PATCH' || method === 'PUT'
|
|
245
|
+
? 'media.update'
|
|
246
|
+
: method === 'DELETE'
|
|
247
|
+
? 'media.delete'
|
|
248
|
+
: null;
|
|
249
|
+
if (action === null)
|
|
250
|
+
return;
|
|
251
|
+
const entryId = id ?? responseId(response);
|
|
252
|
+
await site.auth.audit
|
|
253
|
+
.record({
|
|
254
|
+
actorId: actor.id,
|
|
255
|
+
actorRoles: actor.roles,
|
|
256
|
+
action,
|
|
257
|
+
...(entryId === undefined ? {} : { entryId }),
|
|
258
|
+
})
|
|
259
|
+
.catch((error) => logger.error('audit record failed', { error: String(error) }));
|
|
260
|
+
}
|
|
261
|
+
async function recordAuthAudit(site, actor, method, pathname, response, logger) {
|
|
262
|
+
if (response.status < 200 || response.status >= 300)
|
|
263
|
+
return;
|
|
264
|
+
if (pathname.endsWith('/api/auth/session') && method === 'DELETE') {
|
|
265
|
+
await site.auth.audit
|
|
266
|
+
.record({ actorId: actor.id, actorRoles: actor.roles, action: 'auth.logout' })
|
|
267
|
+
.catch((error) => logger.error('audit record failed', { error: String(error) }));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// Login, TOTP completion and passkey completion all land here the same
|
|
271
|
+
// way: whichever step actually produced a session is the one worth
|
|
272
|
+
// recording, not every intermediate MFA round trip.
|
|
273
|
+
const data = response.body?.data;
|
|
274
|
+
if (data?.status !== 'session')
|
|
275
|
+
return;
|
|
276
|
+
const user = data
|
|
277
|
+
.user;
|
|
278
|
+
const userId = typeof user?.id === 'string' ? user.id : null;
|
|
279
|
+
const roles = Array.isArray(user?.roles) ? user.roles : [];
|
|
280
|
+
await site.auth.audit
|
|
281
|
+
.record({ actorId: userId, actorRoles: roles, action: 'auth.login' })
|
|
282
|
+
.catch((error) => logger.error('audit record failed', { error: String(error) }));
|
|
283
|
+
}
|
|
284
|
+
function writeRestResponse(res, response) {
|
|
285
|
+
res.writeHead(response.status, response.headers);
|
|
286
|
+
res.end(response.body === null || response.body === undefined
|
|
287
|
+
? undefined
|
|
288
|
+
: JSON.stringify(response.body));
|
|
289
|
+
}
|
|
290
|
+
function jsonError(res, status, code, message) {
|
|
291
|
+
res.writeHead(status, { 'content-type': 'application/json; charset=utf-8' });
|
|
292
|
+
res.end(JSON.stringify({ error: { code, message } }));
|
|
293
|
+
}
|
|
294
|
+
/** Same authentication gate as every other `/api/media` route — the file itself is not public. */
|
|
295
|
+
async function serveMediaFile(site, actor, id, req, res) {
|
|
296
|
+
if (req.method !== 'GET') {
|
|
297
|
+
res.writeHead(405, { allow: 'GET' }).end();
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (actor.id === null) {
|
|
301
|
+
jsonError(res, 401, 'UNAUTHENTICATED', 'Sign in to view media.');
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const asset = await site.mediaStore.get(id);
|
|
305
|
+
if (asset === null) {
|
|
306
|
+
jsonError(res, 404, 'MEDIA_NOT_FOUND', `No media asset with id "${id}".`);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const stream = await site.storage.get(asset.storageKey);
|
|
310
|
+
res.writeHead(200, {
|
|
311
|
+
'content-type': asset.mimeType,
|
|
312
|
+
'cache-control': 'private, max-age=3600',
|
|
313
|
+
});
|
|
314
|
+
stream.on('error', () => res.destroy());
|
|
315
|
+
stream.pipe(res);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Builds the Node request handler from an already-assembled site.
|
|
319
|
+
*
|
|
320
|
+
* All the actual logic — routing, permissions, actor resolution — was already
|
|
321
|
+
* tested as plain values in `@cogenta/api` and `@cogenta/auth`; this function
|
|
322
|
+
* is deliberately just the translation from `IncomingMessage`/`ServerResponse`
|
|
323
|
+
* to that shape and back, so a serverless adapter later is the same kind of
|
|
324
|
+
* thin layer rather than a second implementation of any of it.
|
|
325
|
+
*/
|
|
326
|
+
export function createRequestListener(site, logger) {
|
|
327
|
+
return async (req, res) => {
|
|
328
|
+
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
329
|
+
try {
|
|
330
|
+
const actor = await resolveActor(site.auth, Object.fromEntries(Object.entries(req.headers).map(([key, value]) => [
|
|
331
|
+
key,
|
|
332
|
+
Array.isArray(value) ? value.join(', ') : value,
|
|
333
|
+
])));
|
|
334
|
+
const context = { actor };
|
|
335
|
+
if (url.pathname.startsWith('/api/auth/')) {
|
|
336
|
+
const body = req.method === 'GET' || req.method === 'DELETE' ? undefined : await readBody(req);
|
|
337
|
+
const request = toRestRequest(req, url, body);
|
|
338
|
+
const response = await site.authRouter.handle(request);
|
|
339
|
+
writeRestResponse(res, response);
|
|
340
|
+
await recordAuthAudit(site, actor, req.method ?? 'GET', url.pathname, response, logger);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// Public and read-only: `schema.json` describes collection shapes and
|
|
344
|
+
// which role names an action needs, never any content — the admin
|
|
345
|
+
// reads this to know what to show before it has ever signed in.
|
|
346
|
+
if (url.pathname === '/api/schema') {
|
|
347
|
+
if (req.method !== 'GET') {
|
|
348
|
+
res.writeHead(405, { allow: 'GET' }).end();
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8' });
|
|
352
|
+
res.end(JSON.stringify({ data: site.schemaDocument }));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
// Serving the file itself sits outside `mediaRouter`: its `RestResponse`
|
|
356
|
+
// is JSON-only, and a binary body has no shape to fit into that without
|
|
357
|
+
// widening the transport contract every other route relies on.
|
|
358
|
+
const fileMatch = /^\/api\/media\/([^/]+)\/file$/u.exec(url.pathname);
|
|
359
|
+
if (fileMatch !== null) {
|
|
360
|
+
await serveMediaFile(site, actor, decodeURIComponent(fileMatch[1] ?? ''), req, res);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
if (url.pathname === '/api/graphql') {
|
|
364
|
+
if (req.method !== 'POST') {
|
|
365
|
+
res.writeHead(405, { allow: 'POST' }).end();
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const body = (await readBody(req));
|
|
369
|
+
const query = typeof body?.query === 'string' ? body.query : '';
|
|
370
|
+
const result = await executeGraphQL({
|
|
371
|
+
query,
|
|
372
|
+
variables: typeof body?.variables === 'object' && body.variables !== null
|
|
373
|
+
? body.variables
|
|
374
|
+
: undefined,
|
|
375
|
+
operationName: typeof body?.operationName === 'string' ? body.operationName : undefined,
|
|
376
|
+
}, { schema: site.graphqlSchema, gateway: site.gateway, access: context, logger });
|
|
377
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8' });
|
|
378
|
+
res.end(JSON.stringify(result));
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (url.pathname.startsWith('/api/content')) {
|
|
382
|
+
const body = req.method === 'GET' || req.method === 'DELETE' ? undefined : await readBody(req);
|
|
383
|
+
const request = toRestRequest(req, url, body);
|
|
384
|
+
const response = await site.restRouter.handle(request, context);
|
|
385
|
+
writeRestResponse(res, response);
|
|
386
|
+
await recordContentAudit(site, actor, req.method ?? 'GET', url.pathname, body, response, logger);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (url.pathname.startsWith('/api/media')) {
|
|
390
|
+
const body = req.method === 'GET' || req.method === 'DELETE' ? undefined : await readBody(req);
|
|
391
|
+
const request = toRestRequest(req, url, body);
|
|
392
|
+
const response = await site.mediaRouter.handle(request, context.actor);
|
|
393
|
+
writeRestResponse(res, response);
|
|
394
|
+
await recordMediaAudit(site, actor, req.method ?? 'GET', url.pathname, response, logger);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (url.pathname.startsWith('/api/audit')) {
|
|
398
|
+
const request = toRestRequest(req, url, undefined);
|
|
399
|
+
writeRestResponse(res, await site.auditRouter.handle(request, context.actor));
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (url.pathname.startsWith('/api/agents') && site.agentsRouter !== undefined) {
|
|
403
|
+
const request = toRestRequest(req, url, undefined);
|
|
404
|
+
writeRestResponse(res, await site.agentsRouter.handle(request, context.actor));
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
// Driver connectivity/latency, not process metrics or uptime — the
|
|
408
|
+
// same two live selections `cogenta doctor` reports from a terminal,
|
|
409
|
+
// here queried from the running server instead. Admin-only: a
|
|
410
|
+
// driver's `message`/`details` are documented as credential-free, but
|
|
411
|
+
// naming which driver and tier is running is still information the
|
|
412
|
+
// `public` role has no reason to see.
|
|
413
|
+
if (url.pathname === '/api/health') {
|
|
414
|
+
if (req.method !== 'GET') {
|
|
415
|
+
res.writeHead(405, { allow: 'GET' }).end();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (!actor.roles.includes('admin')) {
|
|
419
|
+
jsonError(res, 403, 'FORBIDDEN', 'Only the admin role may read site health.');
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const health = await site.health();
|
|
423
|
+
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8' });
|
|
424
|
+
res.end(JSON.stringify({ data: health }));
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
res.writeHead(404, { 'content-type': 'application/json; charset=utf-8' });
|
|
428
|
+
res.end(JSON.stringify({
|
|
429
|
+
error: { code: 'CONTENT_NOT_FOUND', message: 'No route matches this path.' },
|
|
430
|
+
}));
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
logger.error('request failed', {
|
|
434
|
+
error: isCogentaError(error) ? error.toJSON() : String(error),
|
|
435
|
+
});
|
|
436
|
+
res.writeHead(500, { 'content-type': 'application/json; charset=utf-8' });
|
|
437
|
+
res.end(JSON.stringify({
|
|
438
|
+
error: { code: 'INTERNAL', message: 'The request could not be completed.' },
|
|
439
|
+
}));
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
const DEFAULT_PORT = 4000;
|
|
444
|
+
const DEFAULT_HOST = '127.0.0.1';
|
|
445
|
+
/**
|
|
446
|
+
* Runs until `options.signal` aborts. Returns 0 on a clean shutdown, 1 if
|
|
447
|
+
* startup failed — nothing here calls `process.exit` (same convention as
|
|
448
|
+
* every other command), so an embedder controls the process lifecycle.
|
|
449
|
+
*/
|
|
450
|
+
export async function runServe(options) {
|
|
451
|
+
const { out, stderr } = options;
|
|
452
|
+
const env = options.env ?? process.env;
|
|
453
|
+
const logger = options.logger ?? createLogger({ level: 'silent' });
|
|
454
|
+
const loaded = await loadConfig({
|
|
455
|
+
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
|
|
456
|
+
env,
|
|
457
|
+
});
|
|
458
|
+
const projectRoot = loaded.path === null ? (options.cwd ?? process.cwd()) : dirname(loaded.path);
|
|
459
|
+
if (loaded.config.auth.signingKey === undefined) {
|
|
460
|
+
stderr('COGENTA_AUTH_SIGNING_KEY is not set.\n');
|
|
461
|
+
stderr('Generate a random 32-byte value (openssl rand -base64 32 works) and export it as\n');
|
|
462
|
+
stderr('COGENTA_AUTH_SIGNING_KEY before running serve again.\n');
|
|
463
|
+
return 1;
|
|
464
|
+
}
|
|
465
|
+
let collections;
|
|
466
|
+
try {
|
|
467
|
+
collections = await loadCollections(projectRoot);
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
if (isCogentaError(error)) {
|
|
471
|
+
stderr(`${error.code}: ${error.message}\n`);
|
|
472
|
+
if (error.hint !== undefined)
|
|
473
|
+
stderr(`${error.hint}\n`);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
stderr(`${error instanceof Error ? error.stack : String(error)}\n`);
|
|
477
|
+
}
|
|
478
|
+
return 1;
|
|
479
|
+
}
|
|
480
|
+
const selection = await createDatabaseRegistry({ logger }).select(loaded.config.database);
|
|
481
|
+
const storageSelection = await createStorageRegistry({ logger }).select(loaded.config.storage);
|
|
482
|
+
const site = await assembleSite(selection.instance, collections, loaded.config.auth.signingKey, loaded.config.site, storageSelection.instance, async () => ({ database: await selection.health(), storage: await storageSelection.health() }), undefined, options.readOnly ?? false);
|
|
483
|
+
const server = createServer(createRequestListener(site, logger));
|
|
484
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
485
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
486
|
+
await new Promise((resolve, reject) => {
|
|
487
|
+
server.once('error', reject);
|
|
488
|
+
server.listen(port, host, () => {
|
|
489
|
+
server.off('error', reject);
|
|
490
|
+
resolve();
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
const address = server.address();
|
|
494
|
+
const boundPort = typeof address === 'object' && address !== null ? address.port : port;
|
|
495
|
+
out.ok(`Listening on http://${host}:${boundPort}`);
|
|
496
|
+
out.detail(`${collections.length} collection(s), db driver: ${selection.driver}, storage driver: ${storageSelection.driver}`);
|
|
497
|
+
options.onListening?.({ port: boundPort, host });
|
|
498
|
+
await new Promise((resolve) => {
|
|
499
|
+
if (options.signal === undefined)
|
|
500
|
+
return;
|
|
501
|
+
if (options.signal.aborted) {
|
|
502
|
+
resolve();
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
options.signal.addEventListener('abort', () => resolve(), { once: true });
|
|
506
|
+
});
|
|
507
|
+
await new Promise((resolve, reject) => {
|
|
508
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
509
|
+
});
|
|
510
|
+
await selection.dispose();
|
|
511
|
+
await storageSelection.dispose();
|
|
512
|
+
await site.dispose().catch(() => undefined); // selection.dispose() already closed the same handle
|
|
513
|
+
return 0;
|
|
514
|
+
}
|
|
515
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Logger } from '@cogenta/core';
|
|
2
|
+
import type { Output, Writer } from '../output.js';
|
|
3
|
+
export type SkinSubcommand = 'list' | 'validate' | 'apply' | 'generate';
|
|
4
|
+
export interface SkinOptions {
|
|
5
|
+
readonly subcommand: string | undefined;
|
|
6
|
+
/** `validate`/`apply`: path to a tokens.json file. Ignored by `list`/`generate`. */
|
|
7
|
+
readonly file: string | undefined;
|
|
8
|
+
readonly cwd?: string;
|
|
9
|
+
readonly env?: Record<string, string | undefined>;
|
|
10
|
+
readonly logger?: Logger;
|
|
11
|
+
readonly out: Output;
|
|
12
|
+
readonly stderr: Writer;
|
|
13
|
+
/** `generate` only: free text — sector, mood, audience, brand colours. */
|
|
14
|
+
readonly description?: string;
|
|
15
|
+
/** `generate` only: test seam, never used outside tests. */
|
|
16
|
+
readonly fetchImpl?: typeof fetch;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* `cogenta skin` — 0 the operation succeeded (including a valid `validate`).
|
|
20
|
+
* 1 an invalid skin, a missing file, or a real failure. 2 the command line
|
|
21
|
+
* was wrong.
|
|
22
|
+
*/
|
|
23
|
+
export declare function runSkin(options: SkinOptions): Promise<number>;
|
|
24
|
+
//# sourceMappingURL=skin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skin.d.ts","sourceRoot":"","sources":["../../src/commands/skin.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgC,KAAK,MAAM,EAAc,MAAM,eAAe,CAAA;AAErF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAA;AAEvE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAClC;AA0MD;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAcnE"}
|