@reaatech/prompt-version-control-server 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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/api/routes/deployments.d.ts +4 -0
- package/dist/api/routes/deployments.d.ts.map +1 -0
- package/dist/api/routes/deployments.js +48 -0
- package/dist/api/routes/deployments.js.map +1 -0
- package/dist/api/routes/docs.d.ts +4 -0
- package/dist/api/routes/docs.d.ts.map +1 -0
- package/dist/api/routes/docs.js +75 -0
- package/dist/api/routes/docs.js.map +1 -0
- package/dist/api/routes/evaluations.d.ts +4 -0
- package/dist/api/routes/evaluations.d.ts.map +1 -0
- package/dist/api/routes/evaluations.js +63 -0
- package/dist/api/routes/evaluations.js.map +1 -0
- package/dist/api/routes/metrics.d.ts +4 -0
- package/dist/api/routes/metrics.d.ts.map +1 -0
- package/dist/api/routes/metrics.js +38 -0
- package/dist/api/routes/metrics.js.map +1 -0
- package/dist/api/routes/promotions.d.ts +4 -0
- package/dist/api/routes/promotions.d.ts.map +1 -0
- package/dist/api/routes/promotions.js +95 -0
- package/dist/api/routes/promotions.js.map +1 -0
- package/dist/api/routes/prompts.d.ts +4 -0
- package/dist/api/routes/prompts.d.ts.map +1 -0
- package/dist/api/routes/prompts.js +80 -0
- package/dist/api/routes/prompts.js.map +1 -0
- package/dist/api/routes/render.d.ts +4 -0
- package/dist/api/routes/render.d.ts.map +1 -0
- package/dist/api/routes/render.js +44 -0
- package/dist/api/routes/render.js.map +1 -0
- package/dist/api/routes/tags.d.ts +4 -0
- package/dist/api/routes/tags.d.ts.map +1 -0
- package/dist/api/routes/tags.js +41 -0
- package/dist/api/routes/tags.js.map +1 -0
- package/dist/api/routes/webhooks.d.ts +4 -0
- package/dist/api/routes/webhooks.d.ts.map +1 -0
- package/dist/api/routes/webhooks.js +49 -0
- package/dist/api/routes/webhooks.js.map +1 -0
- package/dist/db/client.d.ts +3 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +21 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/redis.d.ts +3 -0
- package/dist/db/redis.d.ts.map +1 -0
- package/dist/db/redis.js +18 -0
- package/dist/db/redis.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/audit.d.ts +3 -0
- package/dist/middleware/audit.d.ts.map +1 -0
- package/dist/middleware/audit.js +39 -0
- package/dist/middleware/audit.js.map +1 -0
- package/dist/middleware/auth.d.ts +3 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +49 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +3 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +36 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/metrics.d.ts +3 -0
- package/dist/middleware/metrics.d.ts.map +1 -0
- package/dist/middleware/metrics.js +13 -0
- package/dist/middleware/metrics.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +8 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +89 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-id.d.ts +3 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +10 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/services/audit.service.d.ts +6 -0
- package/dist/services/audit.service.d.ts.map +1 -0
- package/dist/services/audit.service.js +26 -0
- package/dist/services/audit.service.js.map +1 -0
- package/dist/services/deployment.service.d.ts +101 -0
- package/dist/services/deployment.service.d.ts.map +1 -0
- package/dist/services/deployment.service.js +127 -0
- package/dist/services/deployment.service.js.map +1 -0
- package/dist/services/diff.engine.d.ts +13 -0
- package/dist/services/diff.engine.d.ts.map +1 -0
- package/dist/services/diff.engine.js +101 -0
- package/dist/services/diff.engine.js.map +1 -0
- package/dist/services/eval.service.d.ts +55 -0
- package/dist/services/eval.service.d.ts.map +1 -0
- package/dist/services/eval.service.js +151 -0
- package/dist/services/eval.service.js.map +1 -0
- package/dist/services/event.bus.d.ts +18 -0
- package/dist/services/event.bus.d.ts.map +1 -0
- package/dist/services/event.bus.js +35 -0
- package/dist/services/event.bus.js.map +1 -0
- package/dist/services/metric.service.d.ts +33 -0
- package/dist/services/metric.service.d.ts.map +1 -0
- package/dist/services/metric.service.js +64 -0
- package/dist/services/metric.service.js.map +1 -0
- package/dist/services/prometheus.service.d.ts +7 -0
- package/dist/services/prometheus.service.d.ts.map +1 -0
- package/dist/services/prometheus.service.js +27 -0
- package/dist/services/prometheus.service.js.map +1 -0
- package/dist/services/prompt.service.d.ts +59 -0
- package/dist/services/prompt.service.d.ts.map +1 -0
- package/dist/services/prompt.service.js +144 -0
- package/dist/services/prompt.service.js.map +1 -0
- package/dist/services/tag.service.d.ts +46 -0
- package/dist/services/tag.service.d.ts.map +1 -0
- package/dist/services/tag.service.js +84 -0
- package/dist/services/tag.service.js.map +1 -0
- package/dist/services/webhook.service.d.ts +50 -0
- package/dist/services/webhook.service.d.ts.map +1 -0
- package/dist/services/webhook.service.js +196 -0
- package/dist/services/webhook.service.js.map +1 -0
- package/dist/types/hono.d.ts +10 -0
- package/dist/types/hono.d.ts.map +1 -0
- package/dist/types/hono.js +2 -0
- package/dist/types/hono.js.map +1 -0
- package/dist/utils/context.d.ts +3 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +9 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +20 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pagination.d.ts +10 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +10 -0
- package/dist/utils/pagination.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { prisma } from '../../db/client.js';
|
|
5
|
+
import { AppError, NotFoundError } from '../../errors.js';
|
|
6
|
+
import { auditMiddleware } from '../../middleware/audit.js';
|
|
7
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
8
|
+
import { evalService } from '../../services/eval.service.js';
|
|
9
|
+
import { tagService } from '../../services/tag.service.js';
|
|
10
|
+
import { getProjectId } from '../../utils/context.js';
|
|
11
|
+
const router = new Hono();
|
|
12
|
+
router.use('*', authMiddleware);
|
|
13
|
+
router.post('/prompts/:id/promote', auditMiddleware('prompt', 'promote'), async (c) => {
|
|
14
|
+
const projectId = getProjectId(c);
|
|
15
|
+
const promptId = c.req.param('id');
|
|
16
|
+
let stagingTag;
|
|
17
|
+
try {
|
|
18
|
+
stagingTag = await tagService.getTag(projectId, promptId, 'staging');
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err instanceof NotFoundError) {
|
|
22
|
+
stagingTag = null;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!stagingTag) {
|
|
29
|
+
throw new AppError('NO_STAGING', 400, 'No staging version found for this prompt');
|
|
30
|
+
}
|
|
31
|
+
const gate = await evalService.getPromotionGateStatus(projectId, stagingTag.versionId);
|
|
32
|
+
if (!gate.canPromote) {
|
|
33
|
+
throw new AppError('PROMOTION_BLOCKED', 409, gate.reason || 'Promotion blocked by eval gate');
|
|
34
|
+
}
|
|
35
|
+
await tagService.moveTag(projectId, promptId, 'production', stagingTag.versionId);
|
|
36
|
+
return c.json({
|
|
37
|
+
promoted: true,
|
|
38
|
+
fromVersion: stagingTag.version.number,
|
|
39
|
+
reason: 'Eval gate passed',
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
const OverrideSchema = z.object({
|
|
43
|
+
versionId: z.string(),
|
|
44
|
+
reason: z.string().min(1),
|
|
45
|
+
});
|
|
46
|
+
router.post('/prompts/:id/promote/override', auditMiddleware('prompt', 'promote'), zValidator('json', OverrideSchema), async (c) => {
|
|
47
|
+
const projectId = getProjectId(c);
|
|
48
|
+
const promptId = c.req.param('id');
|
|
49
|
+
const body = c.req.valid('json');
|
|
50
|
+
await tagService.moveTag(projectId, promptId, 'production', body.versionId);
|
|
51
|
+
return c.json({
|
|
52
|
+
promoted: true,
|
|
53
|
+
versionId: body.versionId,
|
|
54
|
+
reason: body.reason,
|
|
55
|
+
overridden: true,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
router.post('/prompts/:id/rollback', auditMiddleware('prompt', 'rollback'), async (c) => {
|
|
59
|
+
const projectId = getProjectId(c);
|
|
60
|
+
const promptId = c.req.param('id');
|
|
61
|
+
let prodTag;
|
|
62
|
+
try {
|
|
63
|
+
prodTag = await tagService.getTag(projectId, promptId, 'production');
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (err instanceof NotFoundError) {
|
|
67
|
+
prodTag = null;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (!prodTag) {
|
|
74
|
+
throw new AppError('NO_PRODUCTION', 400, 'No production version found');
|
|
75
|
+
}
|
|
76
|
+
const previousVersion = await prisma.version.findFirst({
|
|
77
|
+
where: {
|
|
78
|
+
promptId,
|
|
79
|
+
number: { lt: prodTag.version.number },
|
|
80
|
+
prompt: { projectId },
|
|
81
|
+
},
|
|
82
|
+
orderBy: { number: 'desc' },
|
|
83
|
+
});
|
|
84
|
+
if (!previousVersion) {
|
|
85
|
+
throw new AppError('NO_PREVIOUS', 400, 'No previous version to rollback to');
|
|
86
|
+
}
|
|
87
|
+
await tagService.moveTag(projectId, promptId, 'production', previousVersion.id);
|
|
88
|
+
return c.json({
|
|
89
|
+
rolledBack: true,
|
|
90
|
+
fromVersion: prodTag.version.number,
|
|
91
|
+
toVersion: previousVersion.number,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
export { router as promotionRoutes };
|
|
95
|
+
//# sourceMappingURL=promotions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promotions.js","sourceRoot":"","sources":["../../../src/api/routes/promotions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/api/routes/prompts.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAgG1B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { CreatePromptSchema, CreateVersionSchema, DiffRequestSchema, PaginationSchema, UpdatePromptSchema, } from '@reaatech/prompt-version-control-shared';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { auditMiddleware } from '../../middleware/audit.js';
|
|
5
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
6
|
+
import { diffEngine } from '../../services/diff.engine.js';
|
|
7
|
+
import { promptService } from '../../services/prompt.service.js';
|
|
8
|
+
import { tagService } from '../../services/tag.service.js';
|
|
9
|
+
import { getProjectId } from '../../utils/context.js';
|
|
10
|
+
import { tagRoutes } from './tags.js';
|
|
11
|
+
const router = new Hono();
|
|
12
|
+
router.use('*', authMiddleware);
|
|
13
|
+
router.route('/:id/tags', tagRoutes);
|
|
14
|
+
router.get('/', zValidator('query', PaginationSchema), async (c) => {
|
|
15
|
+
const projectId = getProjectId(c);
|
|
16
|
+
const query = c.req.valid('query');
|
|
17
|
+
const result = await promptService.listPrompts(projectId, query);
|
|
18
|
+
return c.json(result);
|
|
19
|
+
});
|
|
20
|
+
router.post('/', auditMiddleware('prompt', 'create'), zValidator('json', CreatePromptSchema), async (c) => {
|
|
21
|
+
const projectId = getProjectId(c);
|
|
22
|
+
const body = c.req.valid('json');
|
|
23
|
+
const prompt = await promptService.createPrompt(projectId, body);
|
|
24
|
+
return c.json(prompt, 201);
|
|
25
|
+
});
|
|
26
|
+
router.get('/:id', async (c) => {
|
|
27
|
+
const projectId = getProjectId(c);
|
|
28
|
+
const id = c.req.param('id');
|
|
29
|
+
const prompt = await promptService.getPrompt(projectId, id);
|
|
30
|
+
return c.json(prompt);
|
|
31
|
+
});
|
|
32
|
+
router.put('/:id', auditMiddleware('prompt', 'update'), zValidator('json', UpdatePromptSchema), async (c) => {
|
|
33
|
+
const projectId = getProjectId(c);
|
|
34
|
+
const id = c.req.param('id');
|
|
35
|
+
const body = c.req.valid('json');
|
|
36
|
+
const prompt = await promptService.updatePrompt(projectId, id, body);
|
|
37
|
+
return c.json(prompt);
|
|
38
|
+
});
|
|
39
|
+
router.delete('/:id', auditMiddleware('prompt', 'delete'), async (c) => {
|
|
40
|
+
const projectId = getProjectId(c);
|
|
41
|
+
const id = c.req.param('id');
|
|
42
|
+
const prompt = await promptService.archivePrompt(projectId, id);
|
|
43
|
+
return c.json(prompt);
|
|
44
|
+
});
|
|
45
|
+
router.get('/:id/versions', zValidator('query', PaginationSchema), async (c) => {
|
|
46
|
+
const projectId = getProjectId(c);
|
|
47
|
+
const id = c.req.param('id');
|
|
48
|
+
const query = c.req.valid('query');
|
|
49
|
+
const result = await promptService.listVersions(projectId, id, query);
|
|
50
|
+
return c.json(result);
|
|
51
|
+
});
|
|
52
|
+
router.post('/:id/versions', auditMiddleware('version', 'create'), zValidator('json', CreateVersionSchema), async (c) => {
|
|
53
|
+
const projectId = getProjectId(c);
|
|
54
|
+
const id = c.req.param('id');
|
|
55
|
+
const body = c.req.valid('json');
|
|
56
|
+
const version = await promptService.createVersion(projectId, id, body);
|
|
57
|
+
return c.json(version, 201);
|
|
58
|
+
});
|
|
59
|
+
router.get('/:id/production', async (c) => {
|
|
60
|
+
const projectId = getProjectId(c);
|
|
61
|
+
const promptId = c.req.param('id');
|
|
62
|
+
const version = await tagService.getProductionVersion(projectId, promptId);
|
|
63
|
+
return c.json(version);
|
|
64
|
+
});
|
|
65
|
+
router.get('/:id/versions/:vid', async (c) => {
|
|
66
|
+
const projectId = getProjectId(c);
|
|
67
|
+
const promptId = c.req.param('id');
|
|
68
|
+
const versionId = c.req.param('vid');
|
|
69
|
+
const version = await promptService.getVersion(projectId, promptId, versionId);
|
|
70
|
+
return c.json(version);
|
|
71
|
+
});
|
|
72
|
+
router.get('/:id/diff', zValidator('query', DiffRequestSchema), async (c) => {
|
|
73
|
+
const projectId = getProjectId(c);
|
|
74
|
+
const promptId = c.req.param('id');
|
|
75
|
+
const query = c.req.valid('query');
|
|
76
|
+
const diff = await diffEngine.diff(projectId, promptId, query.fromVersion, query.toVersion);
|
|
77
|
+
return c.json(diff);
|
|
78
|
+
});
|
|
79
|
+
export { router as promptRoutes };
|
|
80
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/api/routes/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/api/routes/render.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAO5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AA4C1B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { renderTemplate } from '@reaatech/prompt-version-control-shared';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
6
|
+
import { promptService } from '../../services/prompt.service.js';
|
|
7
|
+
import { tagService } from '../../services/tag.service.js';
|
|
8
|
+
import { getProjectId } from '../../utils/context.js';
|
|
9
|
+
const router = new Hono();
|
|
10
|
+
router.use('*', authMiddleware);
|
|
11
|
+
const RenderSchema = z.object({
|
|
12
|
+
variables: z.record(z.string()).optional(),
|
|
13
|
+
});
|
|
14
|
+
router.post('/prompts/:id/versions/:number/render', zValidator('json', RenderSchema), async (c) => {
|
|
15
|
+
const projectId = getProjectId(c);
|
|
16
|
+
const promptId = c.req.param('id');
|
|
17
|
+
const number = Number(c.req.param('number'));
|
|
18
|
+
const body = c.req.valid('json');
|
|
19
|
+
const version = await promptService.getVersionByNumber(projectId, promptId, number);
|
|
20
|
+
const result = renderTemplate(version.template, body.variables ?? {});
|
|
21
|
+
return c.json({
|
|
22
|
+
version: version.number,
|
|
23
|
+
content: version.content,
|
|
24
|
+
rendered: result.rendered,
|
|
25
|
+
variablesUsed: result.variablesUsed,
|
|
26
|
+
missingVariables: result.missingVariables,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
router.post('/prompts/:id/render', zValidator('json', RenderSchema), async (c) => {
|
|
30
|
+
const projectId = getProjectId(c);
|
|
31
|
+
const promptId = c.req.param('id');
|
|
32
|
+
const body = c.req.valid('json');
|
|
33
|
+
const version = await tagService.getProductionVersion(projectId, promptId);
|
|
34
|
+
const result = renderTemplate(version.template, body.variables ?? {});
|
|
35
|
+
return c.json({
|
|
36
|
+
version: version.number,
|
|
37
|
+
content: version.content,
|
|
38
|
+
rendered: result.rendered,
|
|
39
|
+
variablesUsed: result.variablesUsed,
|
|
40
|
+
missingVariables: result.missingVariables,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
export { router as renderRoutes };
|
|
44
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/api/routes/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../src/api/routes/tags.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAwC1B,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { MoveTagSchema, TagNameSchema } from '@reaatech/prompt-version-control-shared';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
5
|
+
import { tagService } from '../../services/tag.service.js';
|
|
6
|
+
import { getProjectId } from '../../utils/context.js';
|
|
7
|
+
const router = new Hono();
|
|
8
|
+
router.use('*', authMiddleware);
|
|
9
|
+
router.get('/', async (c) => {
|
|
10
|
+
const projectId = getProjectId(c);
|
|
11
|
+
const promptId = c.req.param('id');
|
|
12
|
+
const tags = await tagService.listTags(projectId, promptId);
|
|
13
|
+
return c.json({ data: tags });
|
|
14
|
+
});
|
|
15
|
+
router.post('/:name', zValidator('json', MoveTagSchema), async (c) => {
|
|
16
|
+
const projectId = getProjectId(c);
|
|
17
|
+
const promptId = c.req.param('id');
|
|
18
|
+
const name = c.req.param('name');
|
|
19
|
+
const body = c.req.valid('json');
|
|
20
|
+
const parsedName = TagNameSchema.parse(name);
|
|
21
|
+
const tag = await tagService.moveTag(projectId, promptId, parsedName, body.versionId);
|
|
22
|
+
return c.json(tag, 200);
|
|
23
|
+
});
|
|
24
|
+
router.get('/:name', async (c) => {
|
|
25
|
+
const projectId = getProjectId(c);
|
|
26
|
+
const promptId = c.req.param('id');
|
|
27
|
+
const name = c.req.param('name');
|
|
28
|
+
const parsedName = TagNameSchema.parse(name);
|
|
29
|
+
const tag = await tagService.getTag(projectId, promptId, parsedName);
|
|
30
|
+
return c.json(tag);
|
|
31
|
+
});
|
|
32
|
+
router.delete('/:name', async (c) => {
|
|
33
|
+
const projectId = getProjectId(c);
|
|
34
|
+
const promptId = c.req.param('id');
|
|
35
|
+
const name = c.req.param('name');
|
|
36
|
+
const parsedName = TagNameSchema.parse(name);
|
|
37
|
+
await tagService.removeTag(projectId, promptId, parsedName);
|
|
38
|
+
return c.body(null, 204);
|
|
39
|
+
});
|
|
40
|
+
export { router as tagRoutes };
|
|
41
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/api/routes/tags.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../../src/api/routes/webhooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,QAAA,MAAM,MAAM,4EAAa,CAAC;AAkD1B,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { zValidator } from '@hono/zod-validator';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { authMiddleware } from '../../middleware/auth.js';
|
|
5
|
+
import { webhookService } from '../../services/webhook.service.js';
|
|
6
|
+
import { getProjectId } from '../../utils/context.js';
|
|
7
|
+
const router = new Hono();
|
|
8
|
+
router.use('*', authMiddleware);
|
|
9
|
+
// Create webhook subscription
|
|
10
|
+
const CreateWebhookSchema = z.object({
|
|
11
|
+
url: z.string().url(),
|
|
12
|
+
events: z.array(z.enum([
|
|
13
|
+
'version.created',
|
|
14
|
+
'tag.moved',
|
|
15
|
+
'eval.completed',
|
|
16
|
+
'promotion.requested',
|
|
17
|
+
'promotion.approved',
|
|
18
|
+
'promotion.rejected',
|
|
19
|
+
])),
|
|
20
|
+
secret: z.string().min(16),
|
|
21
|
+
});
|
|
22
|
+
router.post('/', zValidator('json', CreateWebhookSchema), async (c) => {
|
|
23
|
+
const projectId = getProjectId(c);
|
|
24
|
+
const body = c.req.valid('json');
|
|
25
|
+
const sub = await webhookService.createSubscription(projectId, body);
|
|
26
|
+
return c.json(sub, 201);
|
|
27
|
+
});
|
|
28
|
+
// List subscriptions
|
|
29
|
+
router.get('/', async (c) => {
|
|
30
|
+
const projectId = getProjectId(c);
|
|
31
|
+
const subs = await webhookService.listSubscriptions(projectId);
|
|
32
|
+
return c.json({ data: subs });
|
|
33
|
+
});
|
|
34
|
+
// Delete subscription
|
|
35
|
+
router.delete('/:id', async (c) => {
|
|
36
|
+
const projectId = getProjectId(c);
|
|
37
|
+
const id = c.req.param('id');
|
|
38
|
+
await webhookService.deleteSubscription(projectId, id);
|
|
39
|
+
return c.body(null, 204);
|
|
40
|
+
});
|
|
41
|
+
// Test delivery
|
|
42
|
+
router.post('/:id/test', async (c) => {
|
|
43
|
+
const projectId = getProjectId(c);
|
|
44
|
+
const id = c.req.param('id');
|
|
45
|
+
const result = await webhookService.testDelivery(projectId, id);
|
|
46
|
+
return c.json(result);
|
|
47
|
+
});
|
|
48
|
+
export { router as webhookRoutes };
|
|
49
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../../src/api/routes/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;AAE1B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;AAEhC,8BAA8B;AAC9B,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,IAAI,CAAC;QACL,iBAAiB;QACjB,WAAW;QACX,gBAAgB;QAChB,qBAAqB;QACrB,oBAAoB;QACpB,oBAAoB;KACrB,CAAC,CACH;IACD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;CAC3B,CAAC,CAAC;AAEH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACpE,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,qBAAqB;AACrB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1B,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,sBAAsB;AACtB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC;IACvC,MAAM,cAAc,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEH,gBAAgB;AAChB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnC,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC;IACvC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9C,eAAO,MAAM,MAAM,gIAWf,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PrismaClient } from '@prisma/client';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
const globalForPrisma = globalThis;
|
|
4
|
+
export const prisma = globalForPrisma.prisma ??
|
|
5
|
+
new PrismaClient({
|
|
6
|
+
log: process.env.NODE_ENV === 'development'
|
|
7
|
+
? [
|
|
8
|
+
{ emit: 'event', level: 'query' },
|
|
9
|
+
{ emit: 'stdout', level: 'error' },
|
|
10
|
+
{ emit: 'stdout', level: 'warn' },
|
|
11
|
+
]
|
|
12
|
+
: [{ emit: 'stdout', level: 'error' }],
|
|
13
|
+
});
|
|
14
|
+
if (process.env.NODE_ENV === 'development') {
|
|
15
|
+
// biome-ignore lint/suspicious/noExplicitAny: Prisma internal event type
|
|
16
|
+
prisma.$on('query', (e) => {
|
|
17
|
+
logger.debug({ query: e.query, duration: e.duration }, 'prisma query');
|
|
18
|
+
});
|
|
19
|
+
globalForPrisma.prisma = prisma;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,eAAe,GAAG,UAEvB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GACjB,eAAe,CAAC,MAAM;IACtB,IAAI,YAAY,CAAC;QACf,GAAG,EACD,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;YACpC,CAAC,CAAC;gBACE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;gBACjC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE;gBAClC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE;aAClC;YACH,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KAC3C,CAAC,CAAC;AAEL,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;IAC3C,yEAAyE;IACxE,MAAc,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAsC,EAAE,EAAE;QACtE,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,cAAc,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IACH,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/db/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKhC,eAAO,MAAM,KAAK,cAQV,CAAC"}
|
package/dist/db/redis.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Redis } from 'ioredis';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
const redisUrl = process.env.REDIS_URL;
|
|
4
|
+
export const redis = redisUrl
|
|
5
|
+
? new Redis(redisUrl, {
|
|
6
|
+
retryStrategy: (times) => Math.min(times * 50, 2000),
|
|
7
|
+
reconnectOnError: (err) => {
|
|
8
|
+
logger.warn({ err: err.message }, 'redis reconnect');
|
|
9
|
+
return true;
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
: null;
|
|
13
|
+
if (redis) {
|
|
14
|
+
redis.on('error', (err) => {
|
|
15
|
+
logger.error({ err: err.message }, 'redis error');
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/db/redis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;AAEvC,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ;IAC3B,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE;QAClB,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,EAAE,IAAI,CAAC;QACpD,gBAAgB,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;IACJ,CAAC,CAAC,IAAI,CAAC;AAET,IAAI,KAAK,EAAE,CAAC;IACV,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class AppError extends Error {
|
|
2
|
+
code: string;
|
|
3
|
+
status: number;
|
|
4
|
+
details?: Record<string, unknown> | undefined;
|
|
5
|
+
constructor(code: string, status: number, message: string, details?: Record<string, unknown> | undefined);
|
|
6
|
+
}
|
|
7
|
+
export declare class ValidationError extends AppError {
|
|
8
|
+
constructor(details: Record<string, string[]>);
|
|
9
|
+
}
|
|
10
|
+
export declare class NotFoundError extends AppError {
|
|
11
|
+
constructor(resource: string, id: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class ConflictError extends AppError {
|
|
14
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
15
|
+
}
|
|
16
|
+
export declare class UnauthorizedError extends AppError {
|
|
17
|
+
constructor(message?: string);
|
|
18
|
+
}
|
|
19
|
+
export declare class RateLimitError extends AppError {
|
|
20
|
+
constructor(retryAfter: number);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,MAAM;IAEd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAHjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAM3C;AAED,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAG9C;AAED,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAGzC;AAED,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAG/D;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,SAAiB;CAGrC;AAED,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,UAAU,EAAE,MAAM;CAG/B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export class AppError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
status;
|
|
4
|
+
details;
|
|
5
|
+
constructor(code, status, message, details) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.details = details;
|
|
10
|
+
this.name = this.constructor.name;
|
|
11
|
+
Error.captureStackTrace(this, this.constructor);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class ValidationError extends AppError {
|
|
15
|
+
constructor(details) {
|
|
16
|
+
super('VALIDATION_ERROR', 400, 'Request validation failed', { fields: details });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class NotFoundError extends AppError {
|
|
20
|
+
constructor(resource, id) {
|
|
21
|
+
super('NOT_FOUND', 404, `${resource} with id ${id} not found`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class ConflictError extends AppError {
|
|
25
|
+
constructor(message, details) {
|
|
26
|
+
super('CONFLICT', 409, message, details);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export class UnauthorizedError extends AppError {
|
|
30
|
+
constructor(message = 'Unauthorized') {
|
|
31
|
+
super('UNAUTHORIZED', 401, message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class RateLimitError extends AppError {
|
|
35
|
+
constructor(retryAfter) {
|
|
36
|
+
super('RATE_LIMIT_EXCEEDED', 429, 'Rate limit exceeded', { retryAfter });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IAExB;IACA;IAEA;IAJT,YACS,IAAY,EACZ,MAAc,EACrB,OAAe,EACR,OAAiC;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QALR,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;QAEd,YAAO,GAAP,OAAO,CAA0B;QAGxC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,OAAiC;QAC3C,KAAK,CAAC,kBAAkB,EAAE,GAAG,EAAE,2BAA2B,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACnF,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACzC,YAAY,QAAgB,EAAE,EAAU;QACtC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,QAAQ,YAAY,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACzC,YAAY,OAAe,EAAE,OAAiC;QAC5D,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,QAAQ;IAC7C,YAAY,OAAO,GAAG,cAAc;QAClC,KAAK,CAAC,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAC1C,YAAY,UAAkB;QAC5B,KAAK,CAAC,qBAAqB,EAAE,GAAG,EAAE,qBAAqB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAkB5B,QAAA,MAAM,GAAG,4EAAa,CAAC;AA8EvB,OAAO,EAAE,GAAG,EAAE,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { serve } from '@hono/node-server';
|
|
2
|
+
import { Hono } from 'hono';
|
|
3
|
+
import { compress } from 'hono/compress';
|
|
4
|
+
import { cors } from 'hono/cors';
|
|
5
|
+
import { deploymentRoutes } from './api/routes/deployments.js';
|
|
6
|
+
import { docsRoutes } from './api/routes/docs.js';
|
|
7
|
+
import { evaluationRoutes } from './api/routes/evaluations.js';
|
|
8
|
+
import { metricRoutes } from './api/routes/metrics.js';
|
|
9
|
+
import { promotionRoutes } from './api/routes/promotions.js';
|
|
10
|
+
import { promptRoutes } from './api/routes/prompts.js';
|
|
11
|
+
import { renderRoutes } from './api/routes/render.js';
|
|
12
|
+
import { webhookRoutes } from './api/routes/webhooks.js';
|
|
13
|
+
import { errorHandler } from './middleware/error-handler.js';
|
|
14
|
+
import { metricsMiddleware } from './middleware/metrics.js';
|
|
15
|
+
import { rateLimit } from './middleware/rate-limit.js';
|
|
16
|
+
import { requestIdMiddleware } from './middleware/request-id.js';
|
|
17
|
+
import { getMetrics } from './services/prometheus.service.js';
|
|
18
|
+
import { logger } from './utils/logger.js';
|
|
19
|
+
const app = new Hono();
|
|
20
|
+
// Build a strict CORS origin allow-list. Defaults to "no cross-origin" — set
|
|
21
|
+
// CORS_ALLOWED_ORIGINS to a comma-separated list (or "*" to allow any).
|
|
22
|
+
const corsOriginEnv = process.env.CORS_ALLOWED_ORIGINS?.trim();
|
|
23
|
+
const corsOrigin = (() => {
|
|
24
|
+
if (!corsOriginEnv)
|
|
25
|
+
return [];
|
|
26
|
+
if (corsOriginEnv === '*')
|
|
27
|
+
return '*';
|
|
28
|
+
const allowed = corsOriginEnv
|
|
29
|
+
.split(',')
|
|
30
|
+
.map((s) => s.trim())
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
return (origin) => (allowed.includes(origin) ? origin : null);
|
|
33
|
+
})();
|
|
34
|
+
app.use(requestIdMiddleware);
|
|
35
|
+
app.use(compress());
|
|
36
|
+
app.use(cors({ origin: corsOrigin }));
|
|
37
|
+
app.use(rateLimit({ windowMs: 60_000, max: 100 }));
|
|
38
|
+
app.use(metricsMiddleware);
|
|
39
|
+
app.get('/health', (c) => c.json({ status: 'ok', timestamp: new Date().toISOString() }));
|
|
40
|
+
app.get('/ready', (c) => c.json({ status: 'ready' }));
|
|
41
|
+
app.get('/metrics', async (c) => {
|
|
42
|
+
const metrics = await getMetrics();
|
|
43
|
+
return c.text(metrics);
|
|
44
|
+
});
|
|
45
|
+
app.route('/api/v1/prompts', promptRoutes);
|
|
46
|
+
app.route('/api/v1/evaluations', evaluationRoutes);
|
|
47
|
+
app.route('/api/v1/metrics', metricRoutes);
|
|
48
|
+
app.route('/api/v1/deployments', deploymentRoutes);
|
|
49
|
+
app.route('/api/v1/webhooks', webhookRoutes);
|
|
50
|
+
app.route('/api/v1', renderRoutes);
|
|
51
|
+
app.route('/api/v1', promotionRoutes);
|
|
52
|
+
app.route('/api/v1/docs', docsRoutes);
|
|
53
|
+
app.onError(errorHandler);
|
|
54
|
+
app.notFound((c) => {
|
|
55
|
+
return c.json({
|
|
56
|
+
error: { code: 'NOT_FOUND', message: `Route ${c.req.url} not found` },
|
|
57
|
+
requestId: c.get('requestId'),
|
|
58
|
+
timestamp: new Date().toISOString(),
|
|
59
|
+
}, 404);
|
|
60
|
+
});
|
|
61
|
+
if (!process.env.PUBLIC_API_URL && process.env.NODE_ENV !== 'development') {
|
|
62
|
+
logger.warn('PUBLIC_API_URL is not set — eval harness callbacks will use localhost');
|
|
63
|
+
}
|
|
64
|
+
if (!process.env.API_KEY_PEPPER && process.env.NODE_ENV !== 'development') {
|
|
65
|
+
logger.warn('API_KEY_PEPPER is not set — API keys will be hashed with unsalted SHA-256');
|
|
66
|
+
}
|
|
67
|
+
const port = Number(process.env.PORT) || 3000;
|
|
68
|
+
logger.info(`Server starting on port ${port}`);
|
|
69
|
+
const server = serve({
|
|
70
|
+
fetch: app.fetch,
|
|
71
|
+
port,
|
|
72
|
+
});
|
|
73
|
+
const shutdown = (signal) => {
|
|
74
|
+
logger.info({ signal }, 'shutting down gracefully');
|
|
75
|
+
server.close(() => {
|
|
76
|
+
logger.info('server closed');
|
|
77
|
+
process.exit(0);
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
81
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
82
|
+
export { app };
|
|
83
|
+
//# sourceMappingURL=index.js.map
|