@webmaster-droid/server 0.1.0 → 0.2.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/agent/index.d.ts +5 -0
- package/dist/agent/index.js +1 -1
- package/dist/api-aws/index.js +3 -2
- package/dist/api-supabase/index.d.ts +3 -0
- package/dist/api-supabase/index.js +12 -0
- package/dist/{chunk-6RB7H6PA.js → chunk-6M55DMUE.js} +35 -136
- package/dist/chunk-JIGCFERP.js +509 -0
- package/dist/chunk-OWXROQ4O.js +416 -0
- package/dist/{chunk-IK36OUJQ.js → chunk-PS4GESOZ.js} +10 -2
- package/dist/chunk-SIXK4BMG.js +138 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -2
- package/dist/storage-supabase/index.d.ts +50 -0
- package/dist/storage-supabase/index.js +6 -0
- package/package.json +12 -3
package/dist/agent/index.d.ts
CHANGED
|
@@ -28,6 +28,11 @@ interface AgentRunnerResult {
|
|
|
28
28
|
}>;
|
|
29
29
|
updatedDraft: CmsDocument;
|
|
30
30
|
mutationsApplied: boolean;
|
|
31
|
+
mutationSummary?: {
|
|
32
|
+
contentOperations: number;
|
|
33
|
+
themeTokenChanges: number;
|
|
34
|
+
imageOperations: number;
|
|
35
|
+
};
|
|
31
36
|
}
|
|
32
37
|
declare const STATIC_TOOL_NAMES: readonly ["patch_content", "patch_theme_tokens", "get_page", "get_section", "search_content", "generate_image"];
|
|
33
38
|
type StaticToolName = (typeof STATIC_TOOL_NAMES)[number];
|
package/dist/agent/index.js
CHANGED
package/dist/api-aws/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handler,
|
|
3
3
|
streamHandler
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-6M55DMUE.js";
|
|
5
|
+
import "../chunk-SIXK4BMG.js";
|
|
6
|
+
import "../chunk-PS4GESOZ.js";
|
|
6
7
|
import "../chunk-EYY23AAK.js";
|
|
7
8
|
import "../chunk-MLID7STX.js";
|
|
8
9
|
export {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
api_supabase_default,
|
|
3
|
+
handler
|
|
4
|
+
} from "../chunk-JIGCFERP.js";
|
|
5
|
+
import "../chunk-SIXK4BMG.js";
|
|
6
|
+
import "../chunk-PS4GESOZ.js";
|
|
7
|
+
import "../chunk-EYY23AAK.js";
|
|
8
|
+
import "../chunk-OWXROQ4O.js";
|
|
9
|
+
export {
|
|
10
|
+
api_supabase_default as default,
|
|
11
|
+
handler
|
|
12
|
+
};
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getBearerToken,
|
|
3
|
+
normalizeEditablePath,
|
|
4
|
+
verifyAdminToken
|
|
5
|
+
} from "./chunk-SIXK4BMG.js";
|
|
1
6
|
import {
|
|
2
7
|
runAgentTurn
|
|
3
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PS4GESOZ.js";
|
|
4
9
|
import {
|
|
5
10
|
CmsService
|
|
6
11
|
} from "./chunk-EYY23AAK.js";
|
|
@@ -8,122 +13,6 @@ import {
|
|
|
8
13
|
S3CmsStorage
|
|
9
14
|
} from "./chunk-MLID7STX.js";
|
|
10
15
|
|
|
11
|
-
// src/api-aws/auth.ts
|
|
12
|
-
import { createRemoteJWKSet, decodeProtectedHeader, jwtVerify } from "jose";
|
|
13
|
-
var jwksCache = null;
|
|
14
|
-
function getJwks() {
|
|
15
|
-
const jwksUrl = process.env.SUPABASE_JWKS_URL;
|
|
16
|
-
if (!jwksUrl) {
|
|
17
|
-
throw new Error("SUPABASE_JWKS_URL is not configured");
|
|
18
|
-
}
|
|
19
|
-
if (!jwksCache) {
|
|
20
|
-
jwksCache = createRemoteJWKSet(new URL(jwksUrl));
|
|
21
|
-
}
|
|
22
|
-
return jwksCache;
|
|
23
|
-
}
|
|
24
|
-
function buildSupabaseUserEndpoint() {
|
|
25
|
-
const explicitBaseUrl = process.env.SUPABASE_URL?.trim();
|
|
26
|
-
if (explicitBaseUrl) {
|
|
27
|
-
return `${explicitBaseUrl.replace(/\/$/, "")}/auth/v1/user`;
|
|
28
|
-
}
|
|
29
|
-
const jwksUrl = process.env.SUPABASE_JWKS_URL?.trim();
|
|
30
|
-
if (!jwksUrl) {
|
|
31
|
-
throw new Error("SUPABASE_JWKS_URL is not configured");
|
|
32
|
-
}
|
|
33
|
-
const parsed = new URL(jwksUrl);
|
|
34
|
-
return `${parsed.origin}/auth/v1/user`;
|
|
35
|
-
}
|
|
36
|
-
function getSupabaseAnonKey() {
|
|
37
|
-
const key = process.env.SUPABASE_ANON_KEY?.trim() ?? process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY?.trim();
|
|
38
|
-
if (!key) {
|
|
39
|
-
throw new Error("SUPABASE_ANON_KEY is required for HS256 token verification fallback.");
|
|
40
|
-
}
|
|
41
|
-
return key;
|
|
42
|
-
}
|
|
43
|
-
async function verifyHs256ViaSupabase(token) {
|
|
44
|
-
const response = await fetch(buildSupabaseUserEndpoint(), {
|
|
45
|
-
method: "GET",
|
|
46
|
-
headers: {
|
|
47
|
-
authorization: `Bearer ${token}`,
|
|
48
|
-
apikey: getSupabaseAnonKey()
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
if (!response.ok) {
|
|
52
|
-
const detail = await response.text();
|
|
53
|
-
throw new Error(`Supabase token verification failed: ${response.status} ${detail}`);
|
|
54
|
-
}
|
|
55
|
-
const user = await response.json();
|
|
56
|
-
const sub = typeof user.id === "string" ? user.id : "";
|
|
57
|
-
if (!sub) {
|
|
58
|
-
throw new Error("Supabase token verification returned no user id.");
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
sub,
|
|
62
|
-
email: typeof user.email === "string" ? user.email : void 0,
|
|
63
|
-
role: typeof user.role === "string" ? user.role : void 0
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function getBearerToken(headers) {
|
|
67
|
-
const value = headers.authorization ?? headers.Authorization;
|
|
68
|
-
if (!value) {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
const [prefix, token] = value.split(" ");
|
|
72
|
-
if (prefix?.toLowerCase() !== "bearer" || !token) {
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
return token;
|
|
76
|
-
}
|
|
77
|
-
async function verifyAdminToken(token) {
|
|
78
|
-
const header = decodeProtectedHeader(token);
|
|
79
|
-
const algorithm = typeof header.alg === "string" ? header.alg : "";
|
|
80
|
-
if (algorithm === "HS256") {
|
|
81
|
-
const secret = process.env.SUPABASE_JWT_SECRET?.trim();
|
|
82
|
-
if (secret) {
|
|
83
|
-
const result2 = await jwtVerify(token, new TextEncoder().encode(secret), {
|
|
84
|
-
algorithms: ["HS256"]
|
|
85
|
-
});
|
|
86
|
-
const payload2 = result2.payload;
|
|
87
|
-
const identity3 = {
|
|
88
|
-
sub: String(payload2.sub ?? ""),
|
|
89
|
-
email: typeof payload2.email === "string" ? payload2.email : void 0,
|
|
90
|
-
role: typeof payload2.role === "string" ? payload2.role : typeof payload2.user_role === "string" ? payload2.user_role : void 0
|
|
91
|
-
};
|
|
92
|
-
if (!identity3.sub) {
|
|
93
|
-
throw new Error("Invalid token: subject is missing.");
|
|
94
|
-
}
|
|
95
|
-
const enforcedAdminEmail3 = process.env.ADMIN_EMAIL;
|
|
96
|
-
if (enforcedAdminEmail3 && identity3.email?.toLowerCase() !== enforcedAdminEmail3.toLowerCase()) {
|
|
97
|
-
throw new Error("Authenticated user is not allowed for admin access.");
|
|
98
|
-
}
|
|
99
|
-
return identity3;
|
|
100
|
-
}
|
|
101
|
-
const identity2 = await verifyHs256ViaSupabase(token);
|
|
102
|
-
const enforcedAdminEmail2 = process.env.ADMIN_EMAIL;
|
|
103
|
-
if (enforcedAdminEmail2 && identity2.email?.toLowerCase() !== enforcedAdminEmail2.toLowerCase()) {
|
|
104
|
-
throw new Error("Authenticated user is not allowed for admin access.");
|
|
105
|
-
}
|
|
106
|
-
return identity2;
|
|
107
|
-
}
|
|
108
|
-
const result = await jwtVerify(token, getJwks(), {
|
|
109
|
-
algorithms: ["RS256", "ES256"]
|
|
110
|
-
});
|
|
111
|
-
const payload = result.payload;
|
|
112
|
-
const identity = {
|
|
113
|
-
sub: String(payload.sub ?? ""),
|
|
114
|
-
email: typeof payload.email === "string" ? payload.email : void 0,
|
|
115
|
-
role: typeof payload.role === "string" ? payload.role : typeof payload.user_role === "string" ? payload.user_role : void 0
|
|
116
|
-
};
|
|
117
|
-
if (!identity.sub) {
|
|
118
|
-
throw new Error("Invalid token: subject is missing.");
|
|
119
|
-
}
|
|
120
|
-
const enforcedAdminEmail = process.env.ADMIN_EMAIL;
|
|
121
|
-
if (enforcedAdminEmail && identity.email?.toLowerCase() !== enforcedAdminEmail.toLowerCase()) {
|
|
122
|
-
throw new Error("Authenticated user is not allowed for admin access.");
|
|
123
|
-
}
|
|
124
|
-
return identity;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
16
|
// src/api-aws/http.ts
|
|
128
17
|
function jsonResponse(statusCode, body) {
|
|
129
18
|
return {
|
|
@@ -168,23 +57,6 @@ function normalizePath(path) {
|
|
|
168
57
|
return path.replace(/\/+$/, "") || "/";
|
|
169
58
|
}
|
|
170
59
|
|
|
171
|
-
// src/api-aws/normalize-editable-path.ts
|
|
172
|
-
var EDITABLE_ROOTS = ["pages.", "layout.", "seo.", "themeTokens."];
|
|
173
|
-
var MAX_PATH_LENGTH = 320;
|
|
174
|
-
function normalizeEditablePath(value) {
|
|
175
|
-
if (typeof value !== "string") {
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
const trimmed = value.trim();
|
|
179
|
-
if (!trimmed || trimmed.length > MAX_PATH_LENGTH) {
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
if (!EDITABLE_ROOTS.some((prefix) => trimmed.startsWith(prefix))) {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
return trimmed;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
60
|
// src/api-aws/service-factory.ts
|
|
189
61
|
import {
|
|
190
62
|
createDefaultCmsDocument
|
|
@@ -314,6 +186,17 @@ function buildAvailableModels(config) {
|
|
|
314
186
|
}
|
|
315
187
|
return Array.from(options.values());
|
|
316
188
|
}
|
|
189
|
+
function buildModelCapabilities(input) {
|
|
190
|
+
const hasReadableModel = input.availableModels.length > 0;
|
|
191
|
+
const hasImagePipeline = input.config.geminiEnabled && input.hasPublicAssetBaseUrl;
|
|
192
|
+
return {
|
|
193
|
+
contentEdit: hasReadableModel,
|
|
194
|
+
themeTokenEdit: hasReadableModel,
|
|
195
|
+
imageGenerate: hasImagePipeline,
|
|
196
|
+
imageEdit: hasImagePipeline,
|
|
197
|
+
visionAssist: hasReadableModel
|
|
198
|
+
};
|
|
199
|
+
}
|
|
317
200
|
function resolveDefaultModelId(config, availableModels) {
|
|
318
201
|
const requestedDefault = config.defaultModelId.trim();
|
|
319
202
|
if (availableModels.some((model) => model.id === requestedDefault)) {
|
|
@@ -472,11 +355,17 @@ async function handler(event) {
|
|
|
472
355
|
const config = service.getModelConfig();
|
|
473
356
|
const availableModels = buildAvailableModels(config);
|
|
474
357
|
const defaultModelId = resolveDefaultModelId(config, availableModels);
|
|
358
|
+
const capabilities = buildModelCapabilities({
|
|
359
|
+
config,
|
|
360
|
+
availableModels,
|
|
361
|
+
hasPublicAssetBaseUrl: Boolean(service.getPublicAssetBaseUrl())
|
|
362
|
+
});
|
|
475
363
|
return jsonResponse(200, {
|
|
476
364
|
providers: {
|
|
477
365
|
openai: config.openaiEnabled,
|
|
478
366
|
gemini: config.geminiEnabled
|
|
479
367
|
},
|
|
368
|
+
capabilities,
|
|
480
369
|
defaultModelId,
|
|
481
370
|
showModelPicker: availableModels.length > 1,
|
|
482
371
|
availableModels
|
|
@@ -564,7 +453,12 @@ async function handler(event) {
|
|
|
564
453
|
event: "draft-updated",
|
|
565
454
|
data: {
|
|
566
455
|
contentVersion: result.updatedDraft.meta.contentVersion,
|
|
567
|
-
updatedAt: result.updatedDraft.meta.updatedAt
|
|
456
|
+
updatedAt: result.updatedDraft.meta.updatedAt,
|
|
457
|
+
summary: result.mutationSummary ?? {
|
|
458
|
+
contentOperations: 0,
|
|
459
|
+
themeTokenChanges: 0,
|
|
460
|
+
imageOperations: 0
|
|
461
|
+
}
|
|
568
462
|
}
|
|
569
463
|
});
|
|
570
464
|
}
|
|
@@ -641,7 +535,12 @@ var streamHandler = awslambda.streamifyResponse(
|
|
|
641
535
|
if (result.mutationsApplied) {
|
|
642
536
|
write("draft-updated", {
|
|
643
537
|
contentVersion: result.updatedDraft.meta.contentVersion,
|
|
644
|
-
updatedAt: result.updatedDraft.meta.updatedAt
|
|
538
|
+
updatedAt: result.updatedDraft.meta.updatedAt,
|
|
539
|
+
summary: result.mutationSummary ?? {
|
|
540
|
+
contentOperations: 0,
|
|
541
|
+
themeTokenChanges: 0,
|
|
542
|
+
imageOperations: 0
|
|
543
|
+
}
|
|
645
544
|
});
|
|
646
545
|
}
|
|
647
546
|
write("done", { ok: true });
|