veryfront 0.1.130 → 0.1.131
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/esm/cli/auth/login.d.ts.map +1 -1
- package/esm/cli/auth/login.js +11 -0
- package/esm/cli/auth/provider-store.d.ts +20 -0
- package/esm/cli/auth/provider-store.d.ts.map +1 -0
- package/esm/cli/auth/provider-store.js +62 -0
- package/esm/cli/auth/providers/anthropic.d.ts +2 -0
- package/esm/cli/auth/providers/anthropic.d.ts.map +1 -0
- package/esm/cli/auth/providers/anthropic.js +37 -0
- package/esm/cli/auth/providers/openai.d.ts +2 -0
- package/esm/cli/auth/providers/openai.d.ts.map +1 -0
- package/esm/cli/auth/providers/openai.js +35 -0
- package/esm/cli/auth/utils.d.ts +5 -0
- package/esm/cli/auth/utils.d.ts.map +1 -1
- package/esm/cli/auth/utils.js +9 -0
- package/esm/cli/router.d.ts.map +1 -1
- package/esm/cli/router.js +22 -1
- package/esm/deno.js +1 -1
- package/esm/src/channels/control-plane.js +6 -6
- package/esm/src/discovery/handlers/agent-handler.d.ts.map +1 -1
- package/esm/src/discovery/handlers/agent-handler.js +10 -1
- package/esm/src/rendering/rsc/client-boot.ts +18 -1
- package/esm/src/server/handlers/preview/markdown-html-generator.d.ts +2 -0
- package/esm/src/server/handlers/preview/markdown-html-generator.d.ts.map +1 -1
- package/esm/src/server/handlers/preview/markdown-html-generator.js +10 -7
- package/esm/src/server/handlers/preview/markdown-preview.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/preview/markdown-preview.handler.js +6 -3
- package/esm/src/server/handlers/request/api/project-discovery.d.ts.map +1 -1
- package/esm/src/server/handlers/request/api/project-discovery.js +16 -5
- package/esm/src/server/handlers/request/api/security-headers.d.ts +1 -0
- package/esm/src/server/handlers/request/api/security-headers.d.ts.map +1 -1
- package/esm/src/server/handlers/request/api/security-headers.js +4 -1
- package/esm/src/server/handlers/request/openapi-docs.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/openapi-docs.handler.js +10 -6
- package/esm/src/server/handlers/request/rsc/index.d.ts.map +1 -1
- package/esm/src/server/handlers/request/rsc/index.js +5 -2
- package/esm/src/server/handlers/request/ssr/ssr-response-builder.d.ts.map +1 -1
- package/esm/src/server/handlers/request/ssr/ssr-response-builder.js +12 -2
- package/esm/src/server/handlers/response/not-found.d.ts.map +1 -1
- package/esm/src/server/handlers/response/not-found.js +14 -15
- package/esm/src/server/services/rsc/endpoints/endpoint-router.d.ts +1 -1
- package/esm/src/server/services/rsc/endpoints/endpoint-router.d.ts.map +1 -1
- package/esm/src/server/services/rsc/endpoints/endpoint-router.js +3 -3
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.d.ts.map +1 -1
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
- package/esm/src/server/services/rsc/endpoints/types.d.ts +1 -0
- package/esm/src/server/services/rsc/endpoints/types.d.ts.map +1 -1
- package/esm/src/server/services/rsc/orchestrators/handler.d.ts +1 -1
- package/esm/src/server/services/rsc/orchestrators/handler.d.ts.map +1 -1
- package/esm/src/server/services/rsc/orchestrators/handler.js +2 -2
- package/esm/src/server/services/rsc/orchestrators/page-handler.d.ts +1 -1
- package/esm/src/server/services/rsc/orchestrators/page-handler.d.ts.map +1 -1
- package/esm/src/server/services/rsc/orchestrators/page-handler.js +7 -5
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/cli/auth/login.ts +12 -0
- package/src/cli/auth/provider-store.ts +82 -0
- package/src/cli/auth/providers/anthropic.ts +46 -0
- package/src/cli/auth/providers/openai.ts +45 -0
- package/src/cli/auth/utils.ts +10 -0
- package/src/cli/router.ts +24 -1
- package/src/deno.js +1 -1
- package/src/src/channels/control-plane.ts +6 -6
- package/src/src/discovery/handlers/agent-handler.ts +10 -1
- package/src/src/server/handlers/preview/markdown-html-generator.ts +12 -6
- package/src/src/server/handlers/preview/markdown-preview.handler.ts +6 -3
- package/src/src/server/handlers/request/api/project-discovery.ts +18 -5
- package/src/src/server/handlers/request/api/security-headers.ts +10 -1
- package/src/src/server/handlers/request/openapi-docs.handler.ts +10 -6
- package/src/src/server/handlers/request/rsc/index.ts +5 -2
- package/src/src/server/handlers/request/ssr/ssr-response-builder.ts +16 -2
- package/src/src/server/handlers/response/not-found.ts +14 -15
- package/src/src/server/services/rsc/endpoints/endpoint-router.ts +3 -3
- package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
- package/src/src/server/services/rsc/endpoints/types.ts +1 -0
- package/src/src/server/services/rsc/orchestrators/handler.ts +2 -2
- package/src/src/server/services/rsc/orchestrators/page-handler.ts +8 -5
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/login.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,WAAW,EAAoB,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQjG,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AASD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAgB3E;AA8ID,wBAAsB,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA8BzE;AAED,wBAAsB,mBAAmB,CACvC,GAAG,GAAE,iBAA0C,GAC9C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqB1B;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAI5C;AAED,wBAAsB,MAAM,CAC1B,GAAG,GAAE,iBAA0C,GAC9C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/login.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,WAAW,EAAoB,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQjG,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AASD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAgB3E;AA8ID,wBAAsB,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA8BzE;AAED,wBAAsB,mBAAmB,CACvC,GAAG,GAAE,iBAA0C,GAC9C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqB1B;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAI5C;AAED,wBAAsB,MAAM,CAC1B,GAAG,GAAE,iBAA0C,GAC9C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAmD1B;AAED,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC"}
|
package/esm/cli/auth/login.js
CHANGED
|
@@ -238,6 +238,17 @@ export async function whoami(env = getEnvironmentConfig()) {
|
|
|
238
238
|
console.log();
|
|
239
239
|
console.log(" " + warning("✗") + " Not logged in");
|
|
240
240
|
console.log(" " + dim("Run 'veryfront login' to authenticate"));
|
|
241
|
+
// Show provider tokens
|
|
242
|
+
try {
|
|
243
|
+
const { listProviderTokens } = await import("./provider-store.js");
|
|
244
|
+
const providers = await listProviderTokens();
|
|
245
|
+
for (const p of providers) {
|
|
246
|
+
console.log(" " + success("✓") + ` ${p} API key configured`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// Provider store not available
|
|
251
|
+
}
|
|
241
252
|
return null;
|
|
242
253
|
}
|
|
243
254
|
export { deleteToken, hasToken, readToken, saveToken };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-namespaced token storage for AI provider API keys.
|
|
3
|
+
*
|
|
4
|
+
* Stores API keys as plaintext with 0600 permissions in
|
|
5
|
+
* ~/.config/veryfront/tokens/<provider>. Same security model
|
|
6
|
+
* as the existing platform token in ~/.config/veryfront/token.
|
|
7
|
+
*
|
|
8
|
+
* @module cli/auth/provider-store
|
|
9
|
+
*/
|
|
10
|
+
export type ProviderName = "anthropic" | "openai";
|
|
11
|
+
export interface ProviderCredential {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
validatedAt: string;
|
|
14
|
+
provider: ProviderName;
|
|
15
|
+
}
|
|
16
|
+
export declare function saveProviderToken(provider: ProviderName, credential: ProviderCredential): Promise<void>;
|
|
17
|
+
export declare function readProviderToken(provider: ProviderName): Promise<ProviderCredential | null>;
|
|
18
|
+
export declare function deleteProviderToken(provider: ProviderName): Promise<void>;
|
|
19
|
+
export declare function listProviderTokens(): Promise<ProviderName[]>;
|
|
20
|
+
//# sourceMappingURL=provider-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-store.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/provider-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAUD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAQpC;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBlE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-namespaced token storage for AI provider API keys.
|
|
3
|
+
*
|
|
4
|
+
* Stores API keys as plaintext with 0600 permissions in
|
|
5
|
+
* ~/.config/veryfront/tokens/<provider>. Same security model
|
|
6
|
+
* as the existing platform token in ~/.config/veryfront/token.
|
|
7
|
+
*
|
|
8
|
+
* @module cli/auth/provider-store
|
|
9
|
+
*/
|
|
10
|
+
import { getEnvironmentConfig } from "../../src/config/index.js";
|
|
11
|
+
import { join } from "../../src/platform/compat/path/index.js";
|
|
12
|
+
import { createFileSystem } from "../../src/platform/index.js";
|
|
13
|
+
function getTokenDir() {
|
|
14
|
+
const env = getEnvironmentConfig();
|
|
15
|
+
const configDir = env.xdgConfigHome
|
|
16
|
+
? join(env.xdgConfigHome, "veryfront")
|
|
17
|
+
: join(env.homeDir, ".config", "veryfront");
|
|
18
|
+
return join(configDir, "tokens");
|
|
19
|
+
}
|
|
20
|
+
export async function saveProviderToken(provider, credential) {
|
|
21
|
+
const fs = createFileSystem();
|
|
22
|
+
const dir = getTokenDir();
|
|
23
|
+
await fs.mkdir(dir, { recursive: true });
|
|
24
|
+
const path = join(dir, provider);
|
|
25
|
+
await fs.writeTextFile(path, JSON.stringify(credential));
|
|
26
|
+
await fs.chmod(path, 0o600);
|
|
27
|
+
}
|
|
28
|
+
export async function readProviderToken(provider) {
|
|
29
|
+
const fs = createFileSystem();
|
|
30
|
+
try {
|
|
31
|
+
const raw = await fs.readTextFile(join(getTokenDir(), provider));
|
|
32
|
+
return JSON.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function deleteProviderToken(provider) {
|
|
39
|
+
const fs = createFileSystem();
|
|
40
|
+
try {
|
|
41
|
+
await fs.remove(join(getTokenDir(), provider));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Token doesn't exist — fine
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function listProviderTokens() {
|
|
48
|
+
const fs = createFileSystem();
|
|
49
|
+
const providers = [];
|
|
50
|
+
try {
|
|
51
|
+
for await (const entry of fs.readDir(getTokenDir())) {
|
|
52
|
+
if (entry.isFile &&
|
|
53
|
+
(entry.name === "anthropic" || entry.name === "openai")) {
|
|
54
|
+
providers.push(entry.name);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Directory doesn't exist
|
|
60
|
+
}
|
|
61
|
+
return providers;
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../../src/cli/auth/providers/anthropic.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAwCvD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
|
+
import { logError, logSuccess, promptPassword } from "../../utils/index.js";
|
|
3
|
+
import { saveProviderToken } from "../provider-store.js";
|
|
4
|
+
import { dim } from "../../ui/colors.js";
|
|
5
|
+
export async function loginAnthropic() {
|
|
6
|
+
console.log(`\n Enter your Anthropic API key.`);
|
|
7
|
+
console.log(` ${dim("Get one at: https://console.anthropic.com/settings/keys")}\n`);
|
|
8
|
+
const apiKey = promptPassword(" API key: ");
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
logError("No API key provided.");
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const resp = await dntShim.fetch("https://api.anthropic.com/v1/models", {
|
|
15
|
+
headers: {
|
|
16
|
+
"x-api-key": apiKey,
|
|
17
|
+
"anthropic-version": "2023-06-01",
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
if (!resp.ok) {
|
|
21
|
+
logError(`Invalid API key (HTTP ${resp.status}). Check your key at console.anthropic.com`);
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
logError(`Failed to validate key: ${e instanceof Error ? e.message : String(e)}`);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const credential = {
|
|
30
|
+
apiKey,
|
|
31
|
+
validatedAt: new Date().toISOString(),
|
|
32
|
+
provider: "anthropic",
|
|
33
|
+
};
|
|
34
|
+
await saveProviderToken("anthropic", credential);
|
|
35
|
+
logSuccess("Anthropic API key configured");
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../../src/cli/auth/providers/openai.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCpE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
|
+
import { logError, logSuccess, promptPassword } from "../../utils/index.js";
|
|
3
|
+
import { saveProviderToken } from "../provider-store.js";
|
|
4
|
+
import { dim } from "../../ui/colors.js";
|
|
5
|
+
export async function loginOpenAI(baseUrl) {
|
|
6
|
+
console.log(`\n Enter your OpenAI API key.`);
|
|
7
|
+
console.log(` ${dim("Get one at: https://platform.openai.com/api-keys")}\n`);
|
|
8
|
+
const apiKey = promptPassword(" API key: ");
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
logError("No API key provided.");
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const endpoint = baseUrl ?? "https://api.openai.com";
|
|
14
|
+
try {
|
|
15
|
+
const resp = await dntShim.fetch(`${endpoint}/v1/models`, {
|
|
16
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
17
|
+
});
|
|
18
|
+
if (!resp.ok) {
|
|
19
|
+
logError(`Invalid API key (HTTP ${resp.status}). Check your key at platform.openai.com`);
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
logError(`Failed to validate key: ${e instanceof Error ? e.message : String(e)}`);
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const credential = {
|
|
28
|
+
apiKey,
|
|
29
|
+
validatedAt: new Date().toISOString(),
|
|
30
|
+
provider: "openai",
|
|
31
|
+
};
|
|
32
|
+
await saveProviderToken("openai", credential);
|
|
33
|
+
logSuccess("OpenAI API key configured");
|
|
34
|
+
return true;
|
|
35
|
+
}
|
package/esm/cli/auth/utils.d.ts
CHANGED
|
@@ -5,8 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { AuthMethod } from "./login.js";
|
|
7
7
|
import type { ParsedArgs } from "../shared/types.js";
|
|
8
|
+
import type { ProviderName } from "./provider-store.js";
|
|
8
9
|
/**
|
|
9
10
|
* Parse login method from CLI arguments
|
|
10
11
|
*/
|
|
11
12
|
export declare function parseLoginMethod(args: ParsedArgs): AuthMethod | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Parse --provider flag from CLI arguments
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseProvider(args: ParsedArgs): ProviderName | undefined;
|
|
12
17
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/cli/auth/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,GACf,UAAU,GAAG,SAAS,CAMxB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,CAIxE"}
|
package/esm/cli/auth/utils.js
CHANGED
|
@@ -17,3 +17,12 @@ export function parseLoginMethod(args) {
|
|
|
17
17
|
return "token";
|
|
18
18
|
return undefined;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse --provider flag from CLI arguments
|
|
22
|
+
*/
|
|
23
|
+
export function parseProvider(args) {
|
|
24
|
+
const provider = args.provider;
|
|
25
|
+
if (provider === "anthropic" || provider === "openai")
|
|
26
|
+
return provider;
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
package/esm/cli/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/cli/router.ts"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/cli/router.ts"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA0FpD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0FlE"}
|
package/esm/cli/router.js
CHANGED
|
@@ -76,9 +76,30 @@ const commands = {
|
|
|
76
76
|
"deploy": handleDeployCommand,
|
|
77
77
|
"up": handleUpCommand,
|
|
78
78
|
"login": async (args) => {
|
|
79
|
+
const { parseProvider } = await import("./auth/utils.js");
|
|
80
|
+
const provider = parseProvider(args);
|
|
81
|
+
if (provider === "anthropic") {
|
|
82
|
+
const { loginAnthropic } = await import("./auth/providers/anthropic.js");
|
|
83
|
+
await loginAnthropic();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (provider === "openai") {
|
|
87
|
+
const { loginOpenAI } = await import("./auth/providers/openai.js");
|
|
88
|
+
await loginOpenAI(args["base-url"]);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
79
91
|
await login(parseLoginMethod(args));
|
|
80
92
|
},
|
|
81
|
-
"logout": async () => {
|
|
93
|
+
"logout": async (args) => {
|
|
94
|
+
const { parseProvider } = await import("./auth/utils.js");
|
|
95
|
+
const provider = parseProvider(args);
|
|
96
|
+
if (provider) {
|
|
97
|
+
const { deleteProviderToken } = await import("./auth/provider-store.js");
|
|
98
|
+
await deleteProviderToken(provider);
|
|
99
|
+
const { logSuccess } = await import("./utils/index.js");
|
|
100
|
+
logSuccess(`${provider} API key removed`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
82
103
|
await logout();
|
|
83
104
|
},
|
|
84
105
|
"whoami": async () => {
|
package/esm/deno.js
CHANGED
|
@@ -148,13 +148,13 @@ function resolveAgentSkills(agent) {
|
|
|
148
148
|
}))
|
|
149
149
|
.sort((left, right) => left.name.localeCompare(right.name));
|
|
150
150
|
}
|
|
151
|
-
function getRuntimeAgentMetadata(agent) {
|
|
151
|
+
function getRuntimeAgentMetadata(id, agent) {
|
|
152
152
|
const rawConfig = agent.config;
|
|
153
153
|
return RuntimeAgentSchema.parse({
|
|
154
|
-
id
|
|
154
|
+
id,
|
|
155
155
|
name: typeof rawConfig.name === "string" && rawConfig.name.trim().length > 0
|
|
156
156
|
? rawConfig.name
|
|
157
|
-
:
|
|
157
|
+
: id,
|
|
158
158
|
description: typeof rawConfig.description === "string" ? rawConfig.description : null,
|
|
159
159
|
model: agent.config.model ?? null,
|
|
160
160
|
version: typeof rawConfig.version === "string" ? rawConfig.version : null,
|
|
@@ -164,9 +164,9 @@ function getRuntimeAgentMetadata(agent) {
|
|
|
164
164
|
export async function listRuntimeAgents(ctx, deps) {
|
|
165
165
|
await deps.ensureProjectDiscovery(ctx);
|
|
166
166
|
const agents = deps.getAllAgentIds()
|
|
167
|
-
.map((id) => deps.getAgent(id))
|
|
168
|
-
.filter((
|
|
169
|
-
.map(getRuntimeAgentMetadata)
|
|
167
|
+
.map((id) => ({ id, agent: deps.getAgent(id) }))
|
|
168
|
+
.filter((entry) => Boolean(entry.agent))
|
|
169
|
+
.map(({ id, agent }) => getRuntimeAgentMetadata(id, agent))
|
|
170
170
|
.sort((left, right) => left.name.localeCompare(right.name));
|
|
171
171
|
return RuntimeAgentListResponseSchema.parse({ agents });
|
|
172
172
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/discovery/handlers/agent-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/discovery/handlers/agent-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,eAAO,MAAM,YAAY,EAAE,gBAAgB,CAAC,KAAK,CAmBhD,CAAC"}
|
|
@@ -2,12 +2,21 @@
|
|
|
2
2
|
* Agent Discovery Handler
|
|
3
3
|
*/
|
|
4
4
|
import { registerAgent } from "../../agent/index.js";
|
|
5
|
+
import { agentRegistry } from "../../agent/composition/index.js";
|
|
5
6
|
import { filenameToId, trackAgentPath } from "../discovery-utils.js";
|
|
6
7
|
export const agentHandler = {
|
|
7
8
|
typeName: "agent",
|
|
8
9
|
validate: (item) => item !== null && typeof item === "object" && typeof item.generate === "function",
|
|
9
|
-
getId: (agent, file) =>
|
|
10
|
+
getId: (agent, file) => {
|
|
11
|
+
const configuredId = agent.config.id;
|
|
12
|
+
return typeof configuredId === "string" && configuredId.trim().length > 0
|
|
13
|
+
? configuredId
|
|
14
|
+
: filenameToId(file);
|
|
15
|
+
},
|
|
10
16
|
register: (id, agent, file) => {
|
|
17
|
+
if (agent.id !== id) {
|
|
18
|
+
agentRegistry.delete(agent.id);
|
|
19
|
+
}
|
|
11
20
|
registerAgent(id, agent);
|
|
12
21
|
trackAgentPath(id, file);
|
|
13
22
|
return agent;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { ClientModuleStrategy } from "./client-module-strategy.ts";
|
|
7
7
|
import {
|
|
8
8
|
buildClientModuleUrl,
|
|
9
|
+
type ClientRuntimeHydrationData,
|
|
9
10
|
getHydrationReactImportSpecifiers,
|
|
10
11
|
readHydrationData,
|
|
11
12
|
resolveClientModuleStrategy,
|
|
@@ -58,6 +59,18 @@ export function selectHydrationRoot<T extends HydrationRootCandidate>(
|
|
|
58
59
|
fallback;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
interface RSCBootDocument {
|
|
63
|
+
getElementById(id: string): Element | null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function shouldAttemptRSCTransport(
|
|
67
|
+
doc: RSCBootDocument,
|
|
68
|
+
hydrationData: ClientRuntimeHydrationData | null,
|
|
69
|
+
): boolean {
|
|
70
|
+
if (hydrationData?.pagePath) return false;
|
|
71
|
+
return !!doc.getElementById(RSC_ROOT_ID);
|
|
72
|
+
}
|
|
73
|
+
|
|
61
74
|
async function tryStream(q: string): Promise<boolean> {
|
|
62
75
|
try {
|
|
63
76
|
const res = await fetch(RSC_PATH_PREFIX + "stream" + q);
|
|
@@ -151,8 +164,12 @@ export async function boot(): Promise<void> {
|
|
|
151
164
|
console.debug?.("[RSC] Found page component in hydration data:", pagePath);
|
|
152
165
|
if (await hydratePageComponent(pagePath, clientModuleStrategy)) {
|
|
153
166
|
console.debug?.("[RSC] Client component hydrated successfully");
|
|
154
|
-
return;
|
|
155
167
|
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!shouldAttemptRSCTransport(document, hydrationData)) {
|
|
172
|
+
return;
|
|
156
173
|
}
|
|
157
174
|
|
|
158
175
|
if (await tryStream(q)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-html-generator.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-html-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown-html-generator.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-html-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAMrD,oDAAoD;AACpD,UAAU,mBAAmB;IAC3B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,gDAAgD;IAChD,GAAG,EAAE,GAAG,CAAC;IACT,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAyDD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA2FzE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { escapeHtml } from "../../../utils/html-escape.js";
|
|
2
|
+
import { buildNonceAttribute } from "../../../html/html-escape.js";
|
|
2
3
|
/**
|
|
3
4
|
* Detect the preferred color theme from request parameters and client hints.
|
|
4
5
|
*
|
|
@@ -23,10 +24,11 @@ function detectTheme(req, url) {
|
|
|
23
24
|
* Generate the studio bridge `<script>` tag.
|
|
24
25
|
* Injected only when embedded in Studio (`studio_embed=true`).
|
|
25
26
|
*/
|
|
26
|
-
function buildStudioScript(url, projectId, filePath) {
|
|
27
|
+
function buildStudioScript(url, projectId, filePath, nonce) {
|
|
27
28
|
const studioEmbed = url.searchParams.get("studio_embed") === "true";
|
|
28
29
|
if (!studioEmbed)
|
|
29
30
|
return "";
|
|
31
|
+
const nonceAttr = buildNonceAttribute(nonce);
|
|
30
32
|
const rawQueryProjectId = url.searchParams.get("vf_project_id")?.trim() || "";
|
|
31
33
|
// Validate query param before using it in bridge config.
|
|
32
34
|
const queryProjectId = /^[a-zA-Z0-9_-]+$/.test(rawQueryProjectId) ? rawQueryProjectId : "";
|
|
@@ -40,8 +42,8 @@ function buildStudioScript(url, projectId, filePath) {
|
|
|
40
42
|
};
|
|
41
43
|
// Escape </script> sequences to prevent XSS breakout from inline JSON
|
|
42
44
|
const safeJson = JSON.stringify(bridgeConfig).replace(/</g, "\\u003c");
|
|
43
|
-
return `<script>window.__VF_BRIDGE_CONFIG__=${safeJson};</script>
|
|
44
|
-
<script type="module" src="/_veryfront/studio-bridge.js"></script>`;
|
|
45
|
+
return `<script${nonceAttr}>window.__VF_BRIDGE_CONFIG__=${safeJson};</script>
|
|
46
|
+
<script type="module" src="/_veryfront/studio-bridge.js"${nonceAttr}></script>`;
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
47
49
|
* Generate a complete HTML document for markdown preview rendering.
|
|
@@ -51,10 +53,11 @@ function buildStudioScript(url, projectId, filePath) {
|
|
|
51
53
|
* studio bridge integration.
|
|
52
54
|
*/
|
|
53
55
|
export function generateMarkdownHtml(options) {
|
|
54
|
-
const { rawHtml, title, description, request, url, projectId, filePath } = options;
|
|
56
|
+
const { rawHtml, title, description, request, url, projectId, filePath, nonce } = options;
|
|
55
57
|
const theme = detectTheme(request, url);
|
|
56
|
-
const studioScript = buildStudioScript(url, projectId, filePath);
|
|
58
|
+
const studioScript = buildStudioScript(url, projectId, filePath, nonce);
|
|
57
59
|
const themeAttrs = theme ? ` data-theme="${theme}" style="color-scheme: ${theme};"` : "";
|
|
60
|
+
const nonceAttr = buildNonceAttribute(nonce);
|
|
58
61
|
return `<!DOCTYPE html>
|
|
59
62
|
<html lang="en"${themeAttrs}>
|
|
60
63
|
<head>
|
|
@@ -75,7 +78,7 @@ export function generateMarkdownHtml(options) {
|
|
|
75
78
|
|
|
76
79
|
${studioScript}
|
|
77
80
|
|
|
78
|
-
<script type="module">
|
|
81
|
+
<script type="module"${nonceAttr}>
|
|
79
82
|
import mermaid from 'https://esm.sh/mermaid@11.4.1?pin=v135';
|
|
80
83
|
|
|
81
84
|
function getMermaidTheme() {
|
|
@@ -135,7 +138,7 @@ export function generateMarkdownHtml(options) {
|
|
|
135
138
|
</script>
|
|
136
139
|
|
|
137
140
|
<!-- Preview HMR -->
|
|
138
|
-
<script src="/_veryfront/preview-hmr.js"></script>
|
|
141
|
+
<script src="/_veryfront/preview-hmr.js"${nonceAttr}></script>
|
|
139
142
|
</body>
|
|
140
143
|
</html>`;
|
|
141
144
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-preview.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-preview.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBnG,qBAAa,sBAAuB,SAAQ,WAAW;IACrD,QAAQ,EAAE,eAAe,CAKvB;IAEI,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;YAmEjE,cAAc;
|
|
1
|
+
{"version":3,"file":"markdown-preview.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/preview/markdown-preview.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBnG,qBAAa,sBAAuB,SAAQ,WAAW;IACrD,QAAQ,EAAE,eAAe,CAKvB;IAEI,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;YAmEjE,cAAc;CAoF7B"}
|
|
@@ -103,6 +103,7 @@ export class MarkdownPreviewHandler extends BaseHandler {
|
|
|
103
103
|
return this.continue();
|
|
104
104
|
}
|
|
105
105
|
const bundle = await compileMarkdownRuntime("development", ctx.projectDir, body, frontmatter, filePath, "server");
|
|
106
|
+
const responseBuilder = this.createResponseBuilder(ctx);
|
|
106
107
|
const html = generateMarkdownHtml({
|
|
107
108
|
rawHtml: bundle.rawHtml || "",
|
|
108
109
|
title: frontmatter.title != null ? String(frontmatter.title) : filePath,
|
|
@@ -111,15 +112,17 @@ export class MarkdownPreviewHandler extends BaseHandler {
|
|
|
111
112
|
url,
|
|
112
113
|
projectId: ctx.projectSlug || ctx.projectId || "markdown-preview",
|
|
113
114
|
filePath,
|
|
115
|
+
nonce: responseBuilder.nonce,
|
|
114
116
|
});
|
|
115
|
-
|
|
117
|
+
responseBuilder
|
|
116
118
|
.withCache("no-cache")
|
|
117
|
-
.
|
|
119
|
+
.withSecurity(ctx.securityConfig ?? undefined, req);
|
|
120
|
+
const response = responseBuilder.withContentType("text/html; charset=utf-8", html, HTTP_OK);
|
|
118
121
|
logger.debug("Serving markdown preview", {
|
|
119
122
|
filePath,
|
|
120
123
|
htmlLength: html.length,
|
|
121
124
|
});
|
|
122
|
-
return this.respond(
|
|
125
|
+
return this.respond(response);
|
|
123
126
|
}
|
|
124
127
|
catch (error) {
|
|
125
128
|
logger.error("Error rendering markdown", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/project-discovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/project-discovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AA+DrD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D/E"}
|
|
@@ -12,6 +12,21 @@ const logger = serverLogger.component("api-wrapper");
|
|
|
12
12
|
* allows retry on failure (the key is deleted if discovery rejects).
|
|
13
13
|
*/
|
|
14
14
|
const discoveredProjects = new Map();
|
|
15
|
+
function buildDiscoveryConfig(ctx) {
|
|
16
|
+
const ai = ctx.config?.ai;
|
|
17
|
+
const skillDiscoveryEnabled = ai?.skills?.discovery?.enabled ?? true;
|
|
18
|
+
return {
|
|
19
|
+
baseDir: ctx.projectDir,
|
|
20
|
+
toolDirs: ai?.tools?.discovery?.paths ?? ["tools"],
|
|
21
|
+
agentDirs: ai?.agents?.discovery?.paths ?? ["agents"],
|
|
22
|
+
skillDirs: skillDiscoveryEnabled ? (ai?.skills?.discovery?.paths ?? ["skills"]) : [],
|
|
23
|
+
resourceDirs: ["resources"],
|
|
24
|
+
promptDirs: ["prompts"],
|
|
25
|
+
workflowDirs: ["workflows"],
|
|
26
|
+
fsAdapter: ctx.adapter.fs,
|
|
27
|
+
verbose: false,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
15
30
|
/** Build a discovery cache key that incorporates the release/version. */
|
|
16
31
|
function discoveryKey(ctx) {
|
|
17
32
|
const cacheContext = tryGetCacheKeyContext();
|
|
@@ -59,11 +74,7 @@ export async function ensureProjectDiscovery(ctx) {
|
|
|
59
74
|
clearTranspileCache();
|
|
60
75
|
agentRegistry.clear();
|
|
61
76
|
toolRegistry.clear();
|
|
62
|
-
const result = await discoverAll(
|
|
63
|
-
baseDir: ctx.projectDir,
|
|
64
|
-
fsAdapter: ctx.adapter.fs,
|
|
65
|
-
verbose: false,
|
|
66
|
-
});
|
|
77
|
+
const result = await discoverAll(buildDiscoveryConfig(ctx));
|
|
67
78
|
const logData = {
|
|
68
79
|
projectSlug: ctx.projectSlug,
|
|
69
80
|
releaseId: ctx.releaseId,
|
|
@@ -3,4 +3,5 @@ import type { HandlerContext } from "../../types.js";
|
|
|
3
3
|
export declare function buildCSP(ctx: HandlerContext): string;
|
|
4
4
|
export declare function getSecurityHeader(headerName: string, defaultValue: string, ctx: HandlerContext): string;
|
|
5
5
|
export declare function applySecurityHeaders(headers: dntShim.Headers, ctx: HandlerContext, req?: dntShim.Request): void;
|
|
6
|
+
export declare function applySecurityHeadersWithNonce(headers: dntShim.Headers, ctx: HandlerContext, nonce: string, req?: dntShim.Request): void;
|
|
6
7
|
//# sourceMappingURL=security-headers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAarD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAQpD;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,cAAc,GAClB,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/api/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAarD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAQpD;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,cAAc,GAClB,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,IAAI,CAE/G;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,GACpB,IAAI,CAaN"}
|
|
@@ -10,7 +10,10 @@ export function getSecurityHeader(headerName, defaultValue, ctx) {
|
|
|
10
10
|
return coreGetSecurityHeader(headerName, defaultValue, ctx.securityConfig, ctx.adapter);
|
|
11
11
|
}
|
|
12
12
|
export function applySecurityHeaders(headers, ctx, req) {
|
|
13
|
-
|
|
13
|
+
applySecurityHeadersWithNonce(headers, ctx, generateNonce(), req);
|
|
14
|
+
}
|
|
15
|
+
export function applySecurityHeadersWithNonce(headers, ctx, nonce, req) {
|
|
16
|
+
coreApplySecurityHeaders(headers, isDev(ctx), nonce, ctx.cspUserHeader ?? null, ctx.securityConfig, ctx.adapter, ctx.parsedDomain?.allowIframeEmbed ?? false);
|
|
14
17
|
if (req) {
|
|
15
18
|
applyCsrfCookie(req, headers, ctx.securityConfig?.csrf);
|
|
16
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi-docs.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/openapi-docs.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAWnG,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,EAAE,eAAe,CAKvB;cAEiB,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO;IAMnF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"openapi-docs.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/openapi-docs.handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAWnG,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,QAAQ,EAAE,eAAe,CAKvB;cAEiB,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO;IAMnF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAezE,OAAO,CAAC,gBAAgB;CAwCzB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseHandler } from "../response/base.js";
|
|
2
2
|
import { HTTP_OK, PRIORITY_HIGH_DEV } from "../../../utils/constants/index.js";
|
|
3
|
-
import { escapeHtml } from "../../../html/html-escape.js";
|
|
3
|
+
import { buildNonceAttribute, escapeHtml } from "../../../html/html-escape.js";
|
|
4
4
|
/** Default paths */
|
|
5
5
|
const DEFAULT_DOCS_PATH = "/_docs";
|
|
6
6
|
const DEFAULT_JSON_PATH = "/_openapi.json";
|
|
@@ -21,17 +21,20 @@ export class OpenAPIDocsHandler extends BaseHandler {
|
|
|
21
21
|
handle(req, ctx) {
|
|
22
22
|
if (!this.shouldHandle(req, ctx))
|
|
23
23
|
return Promise.resolve(this.continue());
|
|
24
|
-
const html = this.generateDocsPage(ctx);
|
|
25
24
|
const isDev = !!ctx.isLocalProject;
|
|
26
|
-
const
|
|
25
|
+
const builder = this.createResponseBuilder(ctx);
|
|
26
|
+
const html = this.generateDocsPage(ctx, builder.nonce);
|
|
27
|
+
const response = builder
|
|
27
28
|
.withCache(isDev ? "no-cache" : { maxAge: DOCS_CACHE_MAX_AGE_SECONDS, public: true })
|
|
29
|
+
.withSecurity(ctx.securityConfig ?? undefined, req)
|
|
28
30
|
.withContentType("text/html; charset=utf-8", html, HTTP_OK);
|
|
29
31
|
return Promise.resolve(this.respond(response));
|
|
30
32
|
}
|
|
31
|
-
generateDocsPage(ctx) {
|
|
33
|
+
generateDocsPage(ctx, nonce) {
|
|
32
34
|
const specUrl = ctx.config?.openapi?.paths?.json ?? DEFAULT_JSON_PATH;
|
|
33
35
|
const title = escapeHtml(ctx.config?.openapi?.title ?? "API Documentation");
|
|
34
36
|
const description = escapeHtml(ctx.config?.openapi?.description ?? "");
|
|
37
|
+
const nonceAttr = buildNonceAttribute(nonce);
|
|
35
38
|
const configuration = JSON.stringify({
|
|
36
39
|
theme: "purple",
|
|
37
40
|
layout: "modern",
|
|
@@ -47,7 +50,7 @@ export class OpenAPIDocsHandler extends BaseHandler {
|
|
|
47
50
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
48
51
|
<title>${title}</title>
|
|
49
52
|
${description ? `<meta name="description" content="${description}"/>` : ""}
|
|
50
|
-
<style>
|
|
53
|
+
<style${nonceAttr}>
|
|
51
54
|
body {
|
|
52
55
|
margin: 0;
|
|
53
56
|
padding: 0;
|
|
@@ -59,8 +62,9 @@ export class OpenAPIDocsHandler extends BaseHandler {
|
|
|
59
62
|
id="api-reference"
|
|
60
63
|
data-url="${specUrl}"
|
|
61
64
|
data-configuration='${configuration}'
|
|
65
|
+
${nonce ? `nonce="${escapeHtml(nonce)}"` : ""}
|
|
62
66
|
></script>
|
|
63
|
-
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
67
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"${nonceAttr}></script>
|
|
64
68
|
</body>
|
|
65
69
|
</html>`;
|
|
66
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/rsc/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,aAAa,EACd,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/rsc/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,aAAa,EACd,MAAM,gBAAgB,CAAC;AASxB,qBAAa,UAAW,SAAQ,WAAW;IACzC,QAAQ,EAAE,eAAe,CAIvB;IAEF,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAqD1E"}
|