@sourcepress/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/.omc/state/agent-replay-31d84b63-606a-4368-b9e6-93fe4f5ae0f7.jsonl +2 -0
- package/.omc/state/last-tool-error.json +7 -0
- package/.omc/state/mission-state.json +53 -0
- package/.omc/state/subagent-tracking.json +17 -0
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test.log +26 -0
- package/dist/__tests__/app-integration.test.d.ts +2 -0
- package/dist/__tests__/app-integration.test.d.ts.map +1 -0
- package/dist/__tests__/app-integration.test.js +71 -0
- package/dist/__tests__/app-integration.test.js.map +1 -0
- package/dist/__tests__/approval.test.d.ts +2 -0
- package/dist/__tests__/approval.test.d.ts.map +1 -0
- package/dist/__tests__/approval.test.js +170 -0
- package/dist/__tests__/approval.test.js.map +1 -0
- package/dist/__tests__/content.test.d.ts +2 -0
- package/dist/__tests__/content.test.d.ts.map +1 -0
- package/dist/__tests__/content.test.js +187 -0
- package/dist/__tests__/content.test.js.map +1 -0
- package/dist/__tests__/engine.test.d.ts +2 -0
- package/dist/__tests__/engine.test.d.ts.map +1 -0
- package/dist/__tests__/engine.test.js +77 -0
- package/dist/__tests__/engine.test.js.map +1 -0
- package/dist/__tests__/eval.test.d.ts +2 -0
- package/dist/__tests__/eval.test.d.ts.map +1 -0
- package/dist/__tests__/eval.test.js +320 -0
- package/dist/__tests__/eval.test.js.map +1 -0
- package/dist/__tests__/graph.test.d.ts +2 -0
- package/dist/__tests__/graph.test.d.ts.map +1 -0
- package/dist/__tests__/graph.test.js +169 -0
- package/dist/__tests__/graph.test.js.map +1 -0
- package/dist/__tests__/health.test.d.ts +2 -0
- package/dist/__tests__/health.test.d.ts.map +1 -0
- package/dist/__tests__/health.test.js +56 -0
- package/dist/__tests__/health.test.js.map +1 -0
- package/dist/__tests__/import.test.d.ts +2 -0
- package/dist/__tests__/import.test.d.ts.map +1 -0
- package/dist/__tests__/import.test.js +138 -0
- package/dist/__tests__/import.test.js.map +1 -0
- package/dist/__tests__/intent.test.d.ts +2 -0
- package/dist/__tests__/intent.test.d.ts.map +1 -0
- package/dist/__tests__/intent.test.js +122 -0
- package/dist/__tests__/intent.test.js.map +1 -0
- package/dist/__tests__/jobs.test.d.ts +2 -0
- package/dist/__tests__/jobs.test.d.ts.map +1 -0
- package/dist/__tests__/jobs.test.js +96 -0
- package/dist/__tests__/jobs.test.js.map +1 -0
- package/dist/__tests__/knowledge.test.d.ts +2 -0
- package/dist/__tests__/knowledge.test.d.ts.map +1 -0
- package/dist/__tests__/knowledge.test.js +110 -0
- package/dist/__tests__/knowledge.test.js.map +1 -0
- package/dist/__tests__/media-routes.test.d.ts +2 -0
- package/dist/__tests__/media-routes.test.d.ts.map +1 -0
- package/dist/__tests__/media-routes.test.js +88 -0
- package/dist/__tests__/media-routes.test.js.map +1 -0
- package/dist/__tests__/schema.test.d.ts +2 -0
- package/dist/__tests__/schema.test.d.ts.map +1 -0
- package/dist/__tests__/schema.test.js +92 -0
- package/dist/__tests__/schema.test.js.map +1 -0
- package/dist/app.d.ts +7 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +85 -0
- package/dist/app.js.map +1 -0
- package/dist/engine.d.ts +38 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +106 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +17 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +54 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts +2 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +13 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +24 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +30 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/index.d.ts +7 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +5 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +11 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +26 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/route-error-handler.d.ts +12 -0
- package/dist/middleware/route-error-handler.d.ts.map +1 -0
- package/dist/middleware/route-error-handler.js +9 -0
- package/dist/middleware/route-error-handler.js.map +1 -0
- package/dist/routes/approval.d.ts +4 -0
- package/dist/routes/approval.d.ts.map +1 -0
- package/dist/routes/approval.js +70 -0
- package/dist/routes/approval.js.map +1 -0
- package/dist/routes/content.d.ts +4 -0
- package/dist/routes/content.d.ts.map +1 -0
- package/dist/routes/content.js +145 -0
- package/dist/routes/content.js.map +1 -0
- package/dist/routes/eval.d.ts +4 -0
- package/dist/routes/eval.d.ts.map +1 -0
- package/dist/routes/eval.js +178 -0
- package/dist/routes/eval.js.map +1 -0
- package/dist/routes/graph.d.ts +4 -0
- package/dist/routes/graph.d.ts.map +1 -0
- package/dist/routes/graph.js +90 -0
- package/dist/routes/graph.js.map +1 -0
- package/dist/routes/health.d.ts +13 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +19 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/import.d.ts +4 -0
- package/dist/routes/import.d.ts.map +1 -0
- package/dist/routes/import.js +85 -0
- package/dist/routes/import.js.map +1 -0
- package/dist/routes/index.d.ts +12 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +12 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/intent.d.ts +4 -0
- package/dist/routes/intent.d.ts.map +1 -0
- package/dist/routes/intent.js +80 -0
- package/dist/routes/intent.js.map +1 -0
- package/dist/routes/jobs.d.ts +4 -0
- package/dist/routes/jobs.d.ts.map +1 -0
- package/dist/routes/jobs.js +67 -0
- package/dist/routes/jobs.js.map +1 -0
- package/dist/routes/knowledge.d.ts +4 -0
- package/dist/routes/knowledge.d.ts.map +1 -0
- package/dist/routes/knowledge.js +48 -0
- package/dist/routes/knowledge.js.map +1 -0
- package/dist/routes/media.d.ts +4 -0
- package/dist/routes/media.d.ts.map +1 -0
- package/dist/routes/media.js +87 -0
- package/dist/routes/media.js.map +1 -0
- package/dist/routes/schema.d.ts +4 -0
- package/dist/routes/schema.d.ts.map +1 -0
- package/dist/routes/schema.js +54 -0
- package/dist/routes/schema.js.map +1 -0
- package/dist/standalone.d.ts +2 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +115 -0
- package/dist/standalone.js.map +1 -0
- package/package.json +36 -0
- package/src/__tests__/app-integration.test.ts +80 -0
- package/src/__tests__/approval.test.ts +195 -0
- package/src/__tests__/content.test.ts +202 -0
- package/src/__tests__/engine.test.ts +86 -0
- package/src/__tests__/eval.test.ts +343 -0
- package/src/__tests__/graph.test.ts +182 -0
- package/src/__tests__/health.test.ts +68 -0
- package/src/__tests__/import.test.ts +148 -0
- package/src/__tests__/intent.test.ts +133 -0
- package/src/__tests__/jobs.test.ts +107 -0
- package/src/__tests__/knowledge.test.ts +121 -0
- package/src/__tests__/media-routes.test.ts +109 -0
- package/src/__tests__/schema.test.ts +100 -0
- package/src/app.ts +92 -0
- package/src/engine.ts +168 -0
- package/src/index.ts +31 -0
- package/src/middleware/auth.ts +66 -0
- package/src/middleware/cors.ts +15 -0
- package/src/middleware/error-handler.ts +42 -0
- package/src/middleware/index.ts +6 -0
- package/src/middleware/rate-limit.ts +27 -0
- package/src/middleware/route-error-handler.ts +13 -0
- package/src/routes/approval.ts +90 -0
- package/src/routes/content.ts +256 -0
- package/src/routes/eval.ts +262 -0
- package/src/routes/graph.ts +111 -0
- package/src/routes/health.ts +33 -0
- package/src/routes/import.ts +122 -0
- package/src/routes/index.ts +11 -0
- package/src/routes/intent.ts +105 -0
- package/src/routes/jobs.ts +84 -0
- package/src/routes/knowledge.ts +73 -0
- package/src/routes/media.ts +117 -0
- package/src/routes/schema.ts +75 -0
- package/src/standalone.ts +130 -0
- package/tsconfig.json +8 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { mediaRoutes } from "../routes/media.js";
|
|
4
|
+
const sampleRef = {
|
|
5
|
+
path: "assets/hero.webp",
|
|
6
|
+
content_type: "image/webp",
|
|
7
|
+
size_bytes: 50000,
|
|
8
|
+
hash: "abc123",
|
|
9
|
+
source: "uploaded",
|
|
10
|
+
uploaded_at: "2026-04-04T10:00:00Z",
|
|
11
|
+
uploaded_by: "test-user",
|
|
12
|
+
alt: "Hero image",
|
|
13
|
+
};
|
|
14
|
+
function createMockMedia() {
|
|
15
|
+
return {
|
|
16
|
+
upload: vi.fn().mockResolvedValue(sampleRef),
|
|
17
|
+
get: vi.fn().mockResolvedValue(Buffer.from("data")),
|
|
18
|
+
delete: vi.fn().mockResolvedValue(undefined),
|
|
19
|
+
list: vi.fn().mockResolvedValue([sampleRef]),
|
|
20
|
+
getMeta: vi.fn().mockResolvedValue(sampleRef),
|
|
21
|
+
updateMeta: vi.fn().mockResolvedValue({ ...sampleRef, alt: "Updated" }),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function createApp(media) {
|
|
25
|
+
const engine = { media };
|
|
26
|
+
const app = new Hono().basePath("/api");
|
|
27
|
+
app.route("/", mediaRoutes(engine));
|
|
28
|
+
return app;
|
|
29
|
+
}
|
|
30
|
+
describe("media routes", () => {
|
|
31
|
+
it("GET /api/media — lists media", async () => {
|
|
32
|
+
const media = createMockMedia();
|
|
33
|
+
const app = createApp(media);
|
|
34
|
+
const res = await app.request("/api/media");
|
|
35
|
+
expect(res.status).toBe(200);
|
|
36
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
37
|
+
const body = (await res.json());
|
|
38
|
+
expect(body.items).toHaveLength(1);
|
|
39
|
+
expect(body.items[0].path).toBe("assets/hero.webp");
|
|
40
|
+
});
|
|
41
|
+
it("GET /api/media/:path — returns metadata", async () => {
|
|
42
|
+
const media = createMockMedia();
|
|
43
|
+
const app = createApp(media);
|
|
44
|
+
const res = await app.request("/api/media/assets/hero.webp");
|
|
45
|
+
expect(res.status).toBe(200);
|
|
46
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
47
|
+
const body = (await res.json());
|
|
48
|
+
expect(body.path).toBe("assets/hero.webp");
|
|
49
|
+
expect(body.alt).toBe("Hero image");
|
|
50
|
+
});
|
|
51
|
+
it("GET /api/media/:path — 404 for missing file", async () => {
|
|
52
|
+
const media = createMockMedia();
|
|
53
|
+
media.getMeta.mockResolvedValueOnce(null);
|
|
54
|
+
const app = createApp(media);
|
|
55
|
+
const res = await app.request("/api/media/assets/missing.webp");
|
|
56
|
+
expect(res.status).toBe(404);
|
|
57
|
+
});
|
|
58
|
+
it("PUT /api/media/:path — updates metadata", async () => {
|
|
59
|
+
const media = createMockMedia();
|
|
60
|
+
const app = createApp(media);
|
|
61
|
+
const res = await app.request("/api/media/assets/hero.webp", {
|
|
62
|
+
method: "PUT",
|
|
63
|
+
headers: { "Content-Type": "application/json" },
|
|
64
|
+
body: JSON.stringify({ alt: "Updated" }),
|
|
65
|
+
});
|
|
66
|
+
expect(res.status).toBe(200);
|
|
67
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
68
|
+
const body = (await res.json());
|
|
69
|
+
expect(body.alt).toBe("Updated");
|
|
70
|
+
});
|
|
71
|
+
it("DELETE /api/media/:path — deletes file", async () => {
|
|
72
|
+
const media = createMockMedia();
|
|
73
|
+
const app = createApp(media);
|
|
74
|
+
const res = await app.request("/api/media/assets/hero.webp", {
|
|
75
|
+
method: "DELETE",
|
|
76
|
+
});
|
|
77
|
+
expect(res.status).toBe(200);
|
|
78
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
79
|
+
const body = (await res.json());
|
|
80
|
+
expect(body.deleted).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it("returns 501 when media is not configured", async () => {
|
|
83
|
+
const app = createApp(undefined);
|
|
84
|
+
const res = await app.request("/api/media");
|
|
85
|
+
expect(res.status).toBe(501);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=media-routes.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-routes.test.js","sourceRoot":"","sources":["../../src/__tests__/media-routes.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { errorHandler } from "../middleware/error-handler.js";
|
|
4
|
+
import { schemaRoutes } from "../routes/schema.js";
|
|
5
|
+
const mockCollections = {
|
|
6
|
+
posts: {
|
|
7
|
+
name: "Blog Posts",
|
|
8
|
+
path: "content/posts",
|
|
9
|
+
format: "mdx",
|
|
10
|
+
fields: {
|
|
11
|
+
title: { type: "string", required: true },
|
|
12
|
+
draft: { type: "boolean", default: true },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
team: {
|
|
16
|
+
name: "Team",
|
|
17
|
+
path: "content/team",
|
|
18
|
+
format: "yaml",
|
|
19
|
+
fields: {
|
|
20
|
+
name: { type: "string", required: true },
|
|
21
|
+
role: { type: "string" },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
function createMockEngine() {
|
|
26
|
+
return {
|
|
27
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
28
|
+
config: {},
|
|
29
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
30
|
+
github: {},
|
|
31
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
32
|
+
knowledge: {},
|
|
33
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
34
|
+
knowledgeStore: {},
|
|
35
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
36
|
+
cache: {},
|
|
37
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
38
|
+
budget: {},
|
|
39
|
+
// biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
|
|
40
|
+
provider: {},
|
|
41
|
+
listContent: vi.fn().mockResolvedValue([]),
|
|
42
|
+
getContent: vi.fn().mockResolvedValue(null),
|
|
43
|
+
getCollectionDef: vi.fn().mockImplementation((name) => {
|
|
44
|
+
// biome-ignore lint/suspicious/noExplicitAny: index access on typed const object
|
|
45
|
+
return mockCollections[name] ?? null;
|
|
46
|
+
}),
|
|
47
|
+
listCollections: vi.fn().mockReturnValue(["posts", "team"]),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function createTestApp(engine) {
|
|
51
|
+
const app = new Hono().basePath("/api");
|
|
52
|
+
app.use("*", errorHandler());
|
|
53
|
+
app.route("/", schemaRoutes(engine));
|
|
54
|
+
return app;
|
|
55
|
+
}
|
|
56
|
+
describe("Schema routes", () => {
|
|
57
|
+
let engine;
|
|
58
|
+
let app;
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
engine = createMockEngine();
|
|
61
|
+
app = createTestApp(engine);
|
|
62
|
+
});
|
|
63
|
+
describe("GET /api/schema", () => {
|
|
64
|
+
it("returns all collection schemas", async () => {
|
|
65
|
+
const res = await app.request("/api/schema");
|
|
66
|
+
expect(res.status).toBe(200);
|
|
67
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
68
|
+
const body = (await res.json());
|
|
69
|
+
expect(body.total).toBe(2);
|
|
70
|
+
expect(body.collections.posts.name).toBe("Blog Posts");
|
|
71
|
+
expect(body.collections.team.name).toBe("Team");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe("GET /api/schema/:collection", () => {
|
|
75
|
+
it("returns schema for a valid collection", async () => {
|
|
76
|
+
const res = await app.request("/api/schema/posts");
|
|
77
|
+
expect(res.status).toBe(200);
|
|
78
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
79
|
+
const body = (await res.json());
|
|
80
|
+
expect(body.name).toBe("Blog Posts");
|
|
81
|
+
expect(body.fields.title.type).toBe("string");
|
|
82
|
+
});
|
|
83
|
+
it("returns 404 for unknown collection", async () => {
|
|
84
|
+
const res = await app.request("/api/schema/unknown");
|
|
85
|
+
expect(res.status).toBe(404);
|
|
86
|
+
// biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
|
|
87
|
+
const body = (await res.json());
|
|
88
|
+
expect(body.code).toBe("COLLECTION_NOT_FOUND");
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=schema.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.test.js","sourceRoot":"","sources":["../../src/__tests__/schema.test.ts"],"names":[],"mappings":"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"}
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { EngineContext } from "./engine.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a fully wired SourcePress API app.
|
|
4
|
+
* If no engine is provided, only health endpoint is available.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createApp(engine?: EngineContext, apiKeys?: string[]): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/api", "/api">;
|
|
7
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAejD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,sHAsEnE"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { secureHeaders } from "hono/secure-headers";
|
|
3
|
+
import { authMiddleware, corsMiddleware, errorHandler, requireAuth } from "./middleware/index.js";
|
|
4
|
+
import { aiRateLimit, generalRateLimit } from "./middleware/rate-limit.js";
|
|
5
|
+
import { approvalRoutes } from "./routes/approval.js";
|
|
6
|
+
import { contentRoutes } from "./routes/content.js";
|
|
7
|
+
import { evalRoutes } from "./routes/eval.js";
|
|
8
|
+
import { graphRoutes } from "./routes/graph.js";
|
|
9
|
+
import { healthRoutes } from "./routes/health.js";
|
|
10
|
+
import { importRoutes } from "./routes/import.js";
|
|
11
|
+
import { intentRoutes } from "./routes/intent.js";
|
|
12
|
+
import { jobRoutes } from "./routes/jobs.js";
|
|
13
|
+
import { knowledgeRoutes } from "./routes/knowledge.js";
|
|
14
|
+
import { mediaRoutes } from "./routes/media.js";
|
|
15
|
+
import { schemaRoutes } from "./routes/schema.js";
|
|
16
|
+
/**
|
|
17
|
+
* Create a fully wired SourcePress API app.
|
|
18
|
+
* If no engine is provided, only health endpoint is available.
|
|
19
|
+
*/
|
|
20
|
+
export function createApp(engine, apiKeys) {
|
|
21
|
+
const app = new Hono().basePath("/api");
|
|
22
|
+
// Global middleware
|
|
23
|
+
app.use("*", secureHeaders());
|
|
24
|
+
app.use("*", corsMiddleware());
|
|
25
|
+
app.use("*", errorHandler());
|
|
26
|
+
app.use("*", authMiddleware(apiKeys));
|
|
27
|
+
app.use("*", generalRateLimit());
|
|
28
|
+
// Tighter rate limits for AI-consuming endpoints
|
|
29
|
+
app.use("/eval/*", aiRateLimit());
|
|
30
|
+
app.use("/knowledge", aiRateLimit());
|
|
31
|
+
app.use("/knowledge/import/*", aiRateLimit());
|
|
32
|
+
app.use("/knowledge/import", aiRateLimit());
|
|
33
|
+
app.use("/graph/rebuild", aiRateLimit());
|
|
34
|
+
// Protect all write endpoints
|
|
35
|
+
app.use("/content/*", async (c, next) => {
|
|
36
|
+
if (c.req.method === "POST" || c.req.method === "PUT" || c.req.method === "DELETE") {
|
|
37
|
+
return requireAuth()(c, next);
|
|
38
|
+
}
|
|
39
|
+
await next();
|
|
40
|
+
});
|
|
41
|
+
app.use("/knowledge", async (c, next) => {
|
|
42
|
+
if (c.req.method === "POST") {
|
|
43
|
+
return requireAuth()(c, next);
|
|
44
|
+
}
|
|
45
|
+
await next();
|
|
46
|
+
});
|
|
47
|
+
app.use("/knowledge/import/*", requireAuth());
|
|
48
|
+
app.use("/knowledge/import", requireAuth());
|
|
49
|
+
app.use("/graph/rebuild", requireAuth());
|
|
50
|
+
app.use("/eval/*", async (c, next) => {
|
|
51
|
+
if (c.req.method === "POST" || c.req.method === "PUT") {
|
|
52
|
+
return requireAuth()(c, next);
|
|
53
|
+
}
|
|
54
|
+
await next();
|
|
55
|
+
});
|
|
56
|
+
app.use("/approval/*", async (c, next) => {
|
|
57
|
+
if (c.req.method === "POST" || c.req.method === "PUT" || c.req.method === "DELETE") {
|
|
58
|
+
return requireAuth()(c, next);
|
|
59
|
+
}
|
|
60
|
+
await next();
|
|
61
|
+
});
|
|
62
|
+
app.use("/media/*", async (c, next) => {
|
|
63
|
+
if (c.req.method === "POST" || c.req.method === "PUT" || c.req.method === "DELETE") {
|
|
64
|
+
return requireAuth()(c, next);
|
|
65
|
+
}
|
|
66
|
+
await next();
|
|
67
|
+
});
|
|
68
|
+
// Health is always available
|
|
69
|
+
app.route("/", healthRoutes());
|
|
70
|
+
// Engine-dependent routes
|
|
71
|
+
if (engine) {
|
|
72
|
+
app.route("/", contentRoutes(engine));
|
|
73
|
+
app.route("/", knowledgeRoutes(engine));
|
|
74
|
+
app.route("/", graphRoutes(engine));
|
|
75
|
+
app.route("/", schemaRoutes(engine));
|
|
76
|
+
app.route("/", intentRoutes(engine));
|
|
77
|
+
app.route("/", evalRoutes(engine));
|
|
78
|
+
app.route("/", mediaRoutes(engine));
|
|
79
|
+
app.route("/", jobRoutes(engine));
|
|
80
|
+
app.route("/", importRoutes(engine));
|
|
81
|
+
app.route("/", approvalRoutes(engine));
|
|
82
|
+
}
|
|
83
|
+
return app;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BudgetTracker } from "@sourcepress/ai";
|
|
2
|
+
import type { ResolvedProvider } from "@sourcepress/ai";
|
|
3
|
+
import type { CacheProvider } from "@sourcepress/cache";
|
|
4
|
+
import type { ApprovalProvider, CollectionDefinition, ContentFile, SourcePressConfig } from "@sourcepress/core";
|
|
5
|
+
import { GitHubClient } from "@sourcepress/github";
|
|
6
|
+
import type { JobProvider } from "@sourcepress/jobs";
|
|
7
|
+
import { KnowledgeEngine } from "@sourcepress/knowledge";
|
|
8
|
+
import type { KnowledgeStoreBackend } from "@sourcepress/knowledge";
|
|
9
|
+
import type { MediaStorage } from "@sourcepress/media";
|
|
10
|
+
export interface EngineContext {
|
|
11
|
+
config: SourcePressConfig;
|
|
12
|
+
github: GitHubClient;
|
|
13
|
+
knowledge: KnowledgeEngine;
|
|
14
|
+
knowledgeStore: KnowledgeStoreBackend;
|
|
15
|
+
cache: CacheProvider;
|
|
16
|
+
budget: BudgetTracker;
|
|
17
|
+
provider: ResolvedProvider;
|
|
18
|
+
media?: MediaStorage;
|
|
19
|
+
jobs?: JobProvider;
|
|
20
|
+
approval?: ApprovalProvider;
|
|
21
|
+
listContent(collection: string): Promise<ContentFile[]>;
|
|
22
|
+
getContent(collection: string, slug: string): Promise<ContentFile | null>;
|
|
23
|
+
getCollectionDef(collection: string): CollectionDefinition | null;
|
|
24
|
+
listCollections(): string[];
|
|
25
|
+
}
|
|
26
|
+
export declare function resolveApprovalRule(config: SourcePressConfig, collection: string, path: string): "pr" | "direct";
|
|
27
|
+
export interface CreateEngineOptions {
|
|
28
|
+
config: SourcePressConfig;
|
|
29
|
+
githubToken: string;
|
|
30
|
+
aiApiKey?: string;
|
|
31
|
+
apiKeys?: string[];
|
|
32
|
+
knowledgeStore?: KnowledgeStoreBackend;
|
|
33
|
+
cache?: CacheProvider;
|
|
34
|
+
media?: MediaStorage;
|
|
35
|
+
jobs?: JobProvider;
|
|
36
|
+
}
|
|
37
|
+
export declare function createEngine(options: CreateEngineOptions): Promise<EngineContext>;
|
|
38
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACX,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,YAAY,EAKZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAyC,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAkB,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,cAAc,EAAE,qBAAqB,CAAC;IACtC,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAG5B,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1E,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAAC;IAClE,eAAe,IAAI,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACV,IAAI,GAAG,QAAQ,CAQjB;AAED,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,WAAW,CAAC;CACnB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkGvF"}
|
package/dist/engine.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { BudgetTracker, resolveProvider } from "@sourcepress/ai";
|
|
3
|
+
import { MemoryCache } from "@sourcepress/cache";
|
|
4
|
+
import { GitHubClient, GitHubPRApprovalProvider, getContentFile, listContentFiles, } from "@sourcepress/github";
|
|
5
|
+
import { InProcessJobProvider } from "@sourcepress/jobs";
|
|
6
|
+
import { InMemoryKnowledgeStore, JsonFileStore, KnowledgeEngine } from "@sourcepress/knowledge";
|
|
7
|
+
import { GitMediaStorage } from "@sourcepress/media";
|
|
8
|
+
export function resolveApprovalRule(config, collection, path) {
|
|
9
|
+
if (!config.approval?.rules)
|
|
10
|
+
return "direct";
|
|
11
|
+
for (const [pattern, rule] of Object.entries(config.approval.rules)) {
|
|
12
|
+
if (path.startsWith(pattern.replace("/*", "/")) || path === pattern) {
|
|
13
|
+
return rule;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return "direct";
|
|
17
|
+
}
|
|
18
|
+
export async function createEngine(options) {
|
|
19
|
+
const { config, githubToken, aiApiKey } = options;
|
|
20
|
+
// GitHub client
|
|
21
|
+
const github = new GitHubClient({
|
|
22
|
+
owner: config.repository.owner,
|
|
23
|
+
repo: config.repository.repo,
|
|
24
|
+
branch: config.repository.branch,
|
|
25
|
+
token: githubToken,
|
|
26
|
+
});
|
|
27
|
+
// AI provider + budget
|
|
28
|
+
const provider = resolveProvider({
|
|
29
|
+
provider: config.ai.provider,
|
|
30
|
+
model: config.ai.model,
|
|
31
|
+
apiKey: aiApiKey,
|
|
32
|
+
});
|
|
33
|
+
const budget = new BudgetTracker({
|
|
34
|
+
daily_limit_usd: config.ai.daily_limit_usd ?? 5.0,
|
|
35
|
+
warn_at_usd: config.ai.warn_at_usd ?? 3.0,
|
|
36
|
+
});
|
|
37
|
+
// Knowledge store + engine
|
|
38
|
+
const knowledgeStore = options.knowledgeStore ??
|
|
39
|
+
(config.knowledge.graph.backend === "local"
|
|
40
|
+
? new JsonFileStore(join(process.cwd(), ".sourcepress"))
|
|
41
|
+
: new InMemoryKnowledgeStore());
|
|
42
|
+
const knowledge = new KnowledgeEngine(knowledgeStore, provider, budget);
|
|
43
|
+
await knowledge.initialize();
|
|
44
|
+
// Cache
|
|
45
|
+
const cache = options.cache ?? new MemoryCache();
|
|
46
|
+
// Media storage (optional — only if configured)
|
|
47
|
+
let media;
|
|
48
|
+
if (config.media) {
|
|
49
|
+
media = options.media ?? new GitMediaStorage(github, config.media);
|
|
50
|
+
}
|
|
51
|
+
// Job provider (always available, default is in-process)
|
|
52
|
+
const jobs = options.jobs ?? new InProcessJobProvider();
|
|
53
|
+
// Approval provider (optional — only if configured)
|
|
54
|
+
let approval;
|
|
55
|
+
if (config.approval?.provider === "github-pr") {
|
|
56
|
+
approval = new GitHubPRApprovalProvider(github);
|
|
57
|
+
}
|
|
58
|
+
// Convenience methods
|
|
59
|
+
async function listContent(collection) {
|
|
60
|
+
const collDef = config.collections[collection];
|
|
61
|
+
if (!collDef)
|
|
62
|
+
return [];
|
|
63
|
+
const paths = await listContentFiles(github, collDef.path);
|
|
64
|
+
const files = [];
|
|
65
|
+
for (const path of paths) {
|
|
66
|
+
const file = await getContentFile(github, path, collection);
|
|
67
|
+
if (file)
|
|
68
|
+
files.push(file);
|
|
69
|
+
}
|
|
70
|
+
return files;
|
|
71
|
+
}
|
|
72
|
+
async function getContent(collection, slug) {
|
|
73
|
+
const collDef = config.collections[collection];
|
|
74
|
+
if (!collDef)
|
|
75
|
+
return null;
|
|
76
|
+
if (!/^[a-z0-9-]+$/.test(slug))
|
|
77
|
+
return null;
|
|
78
|
+
const ext = collDef.format === "yaml" ? "yaml" : collDef.format === "json" ? "json" : collDef.format;
|
|
79
|
+
const basePath = collDef.path.replace(/\/+$/, "");
|
|
80
|
+
const path = `${basePath}/${slug}.${ext}`;
|
|
81
|
+
return getContentFile(github, path, collection);
|
|
82
|
+
}
|
|
83
|
+
function getCollectionDef(collection) {
|
|
84
|
+
return config.collections[collection] ?? null;
|
|
85
|
+
}
|
|
86
|
+
function listCollections() {
|
|
87
|
+
return Object.keys(config.collections);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
config,
|
|
91
|
+
github,
|
|
92
|
+
knowledge,
|
|
93
|
+
knowledgeStore,
|
|
94
|
+
cache,
|
|
95
|
+
budget,
|
|
96
|
+
provider,
|
|
97
|
+
media,
|
|
98
|
+
jobs,
|
|
99
|
+
approval,
|
|
100
|
+
listContent,
|
|
101
|
+
getContent,
|
|
102
|
+
getCollectionDef,
|
|
103
|
+
listCollections,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQjD,OAAO,EACN,YAAY,EACZ,wBAAwB,EACxB,cAAc,EACd,gBAAgB,GAEhB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAsBrD,MAAM,UAAU,mBAAmB,CAClC,MAAyB,EACzB,UAAkB,EAClB,IAAY;IAEZ,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC7C,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrE,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAaD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC9D,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAElD,gBAAgB;IAChB,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK;QAC9B,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI;QAC5B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;QAChC,KAAK,EAAE,WAAW;KAClB,CAAC,CAAC;IAEH,uBAAuB;IACvB,MAAM,QAAQ,GAAG,eAAe,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ;QAC5B,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK;QACtB,MAAM,EAAE,QAAQ;KAChB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC;QAChC,eAAe,EAAE,MAAM,CAAC,EAAE,CAAC,eAAe,IAAI,GAAG;QACjD,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,IAAI,GAAG;KACzC,CAAC,CAAC;IAEH,2BAA2B;IAC3B,MAAM,cAAc,GACnB,OAAO,CAAC,cAAc;QACtB,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO;YAC1C,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;YACxD,CAAC,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,cAAc,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxE,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAE7B,QAAQ;IACR,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,WAAW,EAAE,CAAC;IAEjD,gDAAgD;IAChD,IAAI,KAA+B,CAAC;IACpC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC;IAED,yDAAyD;IACzD,MAAM,IAAI,GAAgB,OAAO,CAAC,IAAI,IAAI,IAAI,oBAAoB,EAAE,CAAC;IAErE,oDAAoD;IACpD,IAAI,QAAsC,CAAC;IAC3C,IAAI,MAAM,CAAC,QAAQ,EAAE,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC/C,QAAQ,GAAG,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,sBAAsB;IACtB,KAAK,UAAU,WAAW,CAAC,UAAkB;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAkB,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YAC5D,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,UAAkB,EAAE,IAAY;QACzD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,MAAM,GAAG,GACR,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1F,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;QAC1C,OAAO,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,SAAS,gBAAgB,CAAC,UAAkB;QAC3C,OAAO,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;IAC/C,CAAC;IAED,SAAS,eAAe;QACvB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAED,OAAO;QACN,MAAM;QACN,MAAM;QACN,SAAS;QACT,cAAc;QACd,KAAK;QACL,MAAM;QACN,QAAQ;QACR,KAAK;QACL,IAAI;QACJ,QAAQ;QACR,WAAW;QACX,UAAU;QACV,gBAAgB;QAChB,eAAe;KACf,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createApp } from "./app.js";
|
|
2
|
+
export { createEngine, resolveApprovalRule } from "./engine.js";
|
|
3
|
+
export type { EngineContext, CreateEngineOptions } from "./engine.js";
|
|
4
|
+
export { approvalRoutes, healthRoutes, contentRoutes, knowledgeRoutes, graphRoutes, schemaRoutes, intentRoutes, evalRoutes, mediaRoutes, jobRoutes, importRoutes, } from "./routes/index.js";
|
|
5
|
+
export type { HealthStatus } from "./routes/health.js";
|
|
6
|
+
export { corsMiddleware, errorHandler, authMiddleware, SourcePressError, } from "./middleware/index.js";
|
|
7
|
+
export type { ApiError, AuthContext } from "./middleware/index.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EACN,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EACN,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,GAChB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// App factory
|
|
2
|
+
export { createApp } from "./app.js";
|
|
3
|
+
// Engine
|
|
4
|
+
export { createEngine, resolveApprovalRule } from "./engine.js";
|
|
5
|
+
// Routes
|
|
6
|
+
export { approvalRoutes, healthRoutes, contentRoutes, knowledgeRoutes, graphRoutes, schemaRoutes, intentRoutes, evalRoutes, mediaRoutes, jobRoutes, importRoutes, } from "./routes/index.js";
|
|
7
|
+
// Middleware
|
|
8
|
+
export { corsMiddleware, errorHandler, authMiddleware, SourcePressError, } from "./middleware/index.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGhE,SAAS;AACT,OAAO,EACN,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAG3B,aAAa;AACb,OAAO,EACN,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,GAChB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Context, Next } from "hono";
|
|
2
|
+
export interface AuthContext {
|
|
3
|
+
authenticated: boolean;
|
|
4
|
+
user?: string;
|
|
5
|
+
method?: "api-key" | "bearer" | "none";
|
|
6
|
+
}
|
|
7
|
+
export declare function authMiddleware(apiKeys?: string[]): (c: Context, next: Next) => Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Middleware that rejects unauthenticated requests with 401.
|
|
10
|
+
* Apply to write endpoints (POST, PUT, DELETE).
|
|
11
|
+
*/
|
|
12
|
+
export declare function requireAuth(): (c: Context, next: Next) => Promise<(Response & import("hono").TypedResponse<{
|
|
13
|
+
status: number;
|
|
14
|
+
message: string;
|
|
15
|
+
code: string;
|
|
16
|
+
}, 401, "json">) | undefined>;
|
|
17
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;CACvC;AAaD,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAClC,GAAG,OAAO,EAAE,MAAM,IAAI,mBA8BpC;AAED;;;GAGG;AACH,wBAAgB,WAAW,KACZ,GAAG,OAAO,EAAE,MAAM,IAAI;;;;8BAOpC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
function safeCompare(a, b) {
|
|
3
|
+
const aBuf = Buffer.from(a, "utf-8");
|
|
4
|
+
const bBuf = Buffer.from(b, "utf-8");
|
|
5
|
+
if (aBuf.length !== bBuf.length) {
|
|
6
|
+
// Still run comparison on equal-length buffers to avoid timing leak on length
|
|
7
|
+
timingSafeEqual(aBuf, aBuf);
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
return timingSafeEqual(aBuf, bBuf);
|
|
11
|
+
}
|
|
12
|
+
export function authMiddleware(apiKeys) {
|
|
13
|
+
return async (c, next) => {
|
|
14
|
+
const authHeader = c.req.header("Authorization");
|
|
15
|
+
const auth = {
|
|
16
|
+
authenticated: false,
|
|
17
|
+
method: "none",
|
|
18
|
+
};
|
|
19
|
+
if (authHeader?.startsWith("Bearer ") || authHeader?.startsWith("ApiKey ")) {
|
|
20
|
+
const scheme = authHeader.startsWith("Bearer ") ? "bearer" : "api-key";
|
|
21
|
+
const token = authHeader.slice(scheme === "bearer" ? 7 : 7);
|
|
22
|
+
if (!apiKeys || apiKeys.length === 0) {
|
|
23
|
+
// No keys configured — accept any token (warn once is gone; engine should configure keys)
|
|
24
|
+
auth.authenticated = true;
|
|
25
|
+
auth.method = scheme;
|
|
26
|
+
auth.user = "anonymous";
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const matched = apiKeys.some((key) => safeCompare(token, key));
|
|
30
|
+
if (matched) {
|
|
31
|
+
auth.authenticated = true;
|
|
32
|
+
auth.method = scheme;
|
|
33
|
+
auth.user = "api-client";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
c.set("auth", auth);
|
|
38
|
+
await next();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Middleware that rejects unauthenticated requests with 401.
|
|
43
|
+
* Apply to write endpoints (POST, PUT, DELETE).
|
|
44
|
+
*/
|
|
45
|
+
export function requireAuth() {
|
|
46
|
+
return async (c, next) => {
|
|
47
|
+
const auth = c.get("auth");
|
|
48
|
+
if (!auth?.authenticated) {
|
|
49
|
+
return c.json({ status: 401, message: "Unauthorized", code: "UNAUTHORIZED" }, 401);
|
|
50
|
+
}
|
|
51
|
+
await next();
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAS9C,SAAS,WAAW,CAAC,CAAS,EAAE,CAAS;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACjC,8EAA8E;QAC9E,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAkB;IAChD,OAAO,KAAK,EAAE,CAAU,EAAE,IAAU,EAAE,EAAE;QACvC,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAgB;YACzB,aAAa,EAAE,KAAK;YACpB,MAAM,EAAE,MAAM;SACd,CAAC;QAEF,IAAI,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5E,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAE5D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtC,0FAA0F;gBAC1F,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;gBACrB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACP,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBAC/D,IAAI,OAAO,EAAE,CAAC;oBACb,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;oBAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;oBACrB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;gBAC1B,CAAC;YACF,CAAC;QACF,CAAC;QAED,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACpB,MAAM,IAAI,EAAE,CAAC;IACd,CAAC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IAC1B,OAAO,KAAK,EAAE,CAAU,EAAE,IAAU,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAA4B,CAAC;QACtD,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC;YAC1B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,IAAI,EAAE,CAAC;IACd,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAKA,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,oCASzD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cors } from "hono/cors";
|
|
2
|
+
// Default to localhost only when no origins are configured (deny-by-default in production)
|
|
3
|
+
const DEFAULT_ORIGINS = ["http://localhost:3000", "http://localhost:4321", "http://localhost:5173"];
|
|
4
|
+
export function corsMiddleware(origins) {
|
|
5
|
+
const origin = origins ?? DEFAULT_ORIGINS;
|
|
6
|
+
return cors({
|
|
7
|
+
origin,
|
|
8
|
+
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
9
|
+
allowHeaders: ["Content-Type", "Authorization"],
|
|
10
|
+
maxAge: 86400,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,2FAA2F;AAC3F,MAAM,eAAe,GAAG,CAAC,uBAAuB,EAAE,uBAAuB,EAAE,uBAAuB,CAAC,CAAC;AAEpG,MAAM,UAAU,cAAc,CAAC,OAA2B;IACzD,MAAM,MAAM,GAAG,OAAO,IAAI,eAAe,CAAC;IAE1C,OAAO,IAAI,CAAC;QACX,MAAM;QACN,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC;QACzD,YAAY,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;QAC/C,MAAM,EAAE,KAAK;KACb,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Context, Next } from "hono";
|
|
2
|
+
export interface ApiError {
|
|
3
|
+
status: number;
|
|
4
|
+
message: string;
|
|
5
|
+
code: string;
|
|
6
|
+
details?: unknown;
|
|
7
|
+
}
|
|
8
|
+
export declare class SourcePressError extends Error {
|
|
9
|
+
status: number;
|
|
10
|
+
code: string;
|
|
11
|
+
details?: unknown;
|
|
12
|
+
constructor(status: number, code: string, message: string, details?: unknown);
|
|
13
|
+
}
|
|
14
|
+
export declare function errorHandler(): (c: Context, next: Next) => Promise<(Response & import("hono").TypedResponse<{
|
|
15
|
+
status: number;
|
|
16
|
+
message: string;
|
|
17
|
+
code: string;
|
|
18
|
+
}, 500, "json">) | (Response & import("hono").TypedResponse<{
|
|
19
|
+
status: number;
|
|
20
|
+
message: string;
|
|
21
|
+
code: string;
|
|
22
|
+
details?: import("hono/utils/types").JSONValue | undefined;
|
|
23
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | undefined>;
|
|
24
|
+
//# sourceMappingURL=error-handler.d.ts.map
|