@agent-native/core 0.201.1-nightly-20261005213104 → 0.201.1
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/a2a/handlers.js +96 -44
- package/dist/a2a/organization-identity.d.ts +9 -0
- package/dist/a2a/organization-identity.js +34 -0
- package/dist/a2a/server.d.ts +13 -7
- package/dist/a2a/server.js +187 -88
- package/dist/a2a/task-store.d.ts +7 -2
- package/dist/a2a/task-store.js +23 -8
- package/dist/a2a-claims.js +12 -2
- package/dist/app-config/mcp.d.ts +4 -0
- package/dist/app-config/mcp.js +7 -0
- package/dist/app-config/schema.d.ts +3 -0
- package/dist/app-config/schema.js +2 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/route-chunk-recovery.js +75 -11
- package/dist/client/route-warmup.d.ts +2 -0
- package/dist/client/route-warmup.js +3 -0
- package/dist/client/vite-dev-recovery-script.js +85 -17
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.js +3 -1
- package/dist/feature-flags/a2a-action-route.js +3 -4
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/mcp/build-server.d.ts +4 -0
- package/dist/mcp/build-server.js +133 -39
- package/dist/mcp/server.js +21 -8
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +9 -9
- package/dist/onboarding/app-profile.js +2 -1
- package/dist/onboarding/workspace-services.js +3 -0
- package/dist/org/context.d.ts +13 -0
- package/dist/org/context.js +60 -0
- package/dist/org/index.d.ts +1 -1
- package/dist/org/membership.d.ts +6 -0
- package/dist/org/membership.js +23 -5
- package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
- package/dist/provider-api/actions/provider-api.d.ts +6 -6
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +11 -11
- package/dist/server/action-routes.js +12 -5
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/builder-browser.d.ts +4 -2
- package/dist/server/builder-browser.js +147 -9
- package/dist/server/core-routes-plugin.js +13 -6
- package/dist/server/entry-server.js +43 -2
- package/dist/server/sentry.js +9 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.js +3 -7
- package/dist/shared/cache-control.d.ts +4 -1
- package/dist/shared/cache-control.js +11 -6
- package/dist/shared/route-chunk-recovery-bootstrap.d.ts +7 -0
- package/dist/shared/route-chunk-recovery-bootstrap.js +38 -0
- package/dist/triggers/actions/manage-automation.d.ts +5 -5
- package/package.json +6 -4
|
@@ -311,10 +311,9 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
311
311
|
notes?: string | undefined;
|
|
312
312
|
scope?: "org" | "user" | undefined;
|
|
313
313
|
}, {
|
|
314
|
-
|
|
314
|
+
id?: undefined;
|
|
315
315
|
deleted?: undefined;
|
|
316
316
|
message?: undefined;
|
|
317
|
-
id?: undefined;
|
|
318
317
|
providers: {
|
|
319
318
|
id: string;
|
|
320
319
|
label: string;
|
|
@@ -325,44 +324,45 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
325
324
|
updatedAt: number;
|
|
326
325
|
}[];
|
|
327
326
|
count: number;
|
|
327
|
+
provider?: undefined;
|
|
328
328
|
found?: undefined;
|
|
329
329
|
registered?: undefined;
|
|
330
330
|
label?: undefined;
|
|
331
331
|
} | {
|
|
332
|
+
id?: undefined;
|
|
332
333
|
count?: undefined;
|
|
333
334
|
deleted?: undefined;
|
|
334
335
|
message?: undefined;
|
|
335
|
-
id?: undefined;
|
|
336
336
|
providers?: undefined;
|
|
337
337
|
found: boolean;
|
|
338
338
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
339
339
|
registered?: undefined;
|
|
340
340
|
label?: undefined;
|
|
341
341
|
} | {
|
|
342
|
-
provider?: undefined;
|
|
343
342
|
count?: undefined;
|
|
344
343
|
deleted?: undefined;
|
|
345
344
|
message?: undefined;
|
|
346
345
|
providers?: undefined;
|
|
346
|
+
provider?: undefined;
|
|
347
347
|
found: boolean;
|
|
348
348
|
id: string;
|
|
349
349
|
registered?: undefined;
|
|
350
350
|
label?: undefined;
|
|
351
351
|
} | {
|
|
352
|
-
provider?: undefined;
|
|
353
352
|
count?: undefined;
|
|
354
353
|
message?: undefined;
|
|
355
354
|
providers?: undefined;
|
|
355
|
+
provider?: undefined;
|
|
356
356
|
found?: undefined;
|
|
357
357
|
deleted: boolean;
|
|
358
358
|
id: string;
|
|
359
359
|
registered?: undefined;
|
|
360
360
|
label?: undefined;
|
|
361
361
|
} | {
|
|
362
|
-
provider?: undefined;
|
|
363
362
|
count?: undefined;
|
|
364
363
|
deleted?: undefined;
|
|
365
364
|
providers?: undefined;
|
|
365
|
+
provider?: undefined;
|
|
366
366
|
found?: undefined;
|
|
367
367
|
registered: boolean;
|
|
368
368
|
id: string;
|
|
@@ -39,8 +39,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
39
39
|
error: string;
|
|
40
40
|
}>;
|
|
41
41
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
42
|
-
ok?: undefined;
|
|
43
42
|
error: string;
|
|
43
|
+
ok?: undefined;
|
|
44
44
|
} | {
|
|
45
45
|
error?: undefined;
|
|
46
46
|
ok: boolean;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -58,47 +58,47 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
|
|
|
58
58
|
error: string;
|
|
59
59
|
errorCode?: undefined;
|
|
60
60
|
retryable?: undefined;
|
|
61
|
-
ok?: undefined;
|
|
62
61
|
status?: undefined;
|
|
62
|
+
ok?: undefined;
|
|
63
63
|
} | {
|
|
64
64
|
error: string;
|
|
65
65
|
errorCode: string;
|
|
66
66
|
retryable?: undefined;
|
|
67
|
-
ok?: undefined;
|
|
68
67
|
status?: undefined;
|
|
68
|
+
ok?: undefined;
|
|
69
69
|
} | {
|
|
70
70
|
error: string;
|
|
71
71
|
errorCode: string;
|
|
72
72
|
retryable: boolean;
|
|
73
|
-
ok?: undefined;
|
|
74
73
|
status?: undefined;
|
|
74
|
+
ok?: undefined;
|
|
75
75
|
} | {
|
|
76
|
-
error?: undefined;
|
|
77
76
|
errorCode?: undefined;
|
|
78
77
|
retryable?: undefined;
|
|
79
78
|
ok: boolean;
|
|
80
79
|
status: string;
|
|
80
|
+
error?: undefined;
|
|
81
81
|
} | {
|
|
82
|
-
ok?: undefined;
|
|
83
82
|
error: string;
|
|
84
83
|
removed?: undefined;
|
|
84
|
+
ok?: undefined;
|
|
85
85
|
} | {
|
|
86
|
-
error?: undefined;
|
|
87
86
|
ok: boolean;
|
|
88
87
|
removed: boolean;
|
|
88
|
+
error?: undefined;
|
|
89
89
|
}>>;
|
|
90
90
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
91
|
-
ok?: undefined;
|
|
92
91
|
error: string;
|
|
93
92
|
note?: undefined;
|
|
93
|
+
ok?: undefined;
|
|
94
94
|
} | {
|
|
95
|
-
error?: undefined;
|
|
96
95
|
ok: boolean;
|
|
97
96
|
note?: undefined;
|
|
98
|
-
} | {
|
|
99
97
|
error?: undefined;
|
|
98
|
+
} | {
|
|
100
99
|
ok: boolean;
|
|
101
100
|
note: string;
|
|
101
|
+
error?: undefined;
|
|
102
102
|
} | {
|
|
103
103
|
note?: undefined;
|
|
104
104
|
ok: boolean;
|
|
@@ -126,11 +126,11 @@ export declare function createAdHocSecretHandler(): import("h3").EventHandlerWit
|
|
|
126
126
|
} | {
|
|
127
127
|
error: string;
|
|
128
128
|
} | {
|
|
129
|
-
error?: undefined;
|
|
130
129
|
ok: boolean;
|
|
131
130
|
key: string;
|
|
132
|
-
} | {
|
|
133
131
|
error?: undefined;
|
|
132
|
+
} | {
|
|
134
133
|
ok: boolean;
|
|
135
134
|
removed: boolean;
|
|
135
|
+
error?: undefined;
|
|
136
136
|
}>>;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, readBody as readH3Body, } from "h3";
|
|
2
2
|
import "../authorization/check-action.js";
|
|
3
3
|
import { verifyA2ATokenWithClaims } from "../a2a-claims.js";
|
|
4
|
+
import { isA2AIdentityVerificationUnavailableError } from "../a2a/server.js";
|
|
4
5
|
import { actionCallEmitsChange, actionChangeResource, } from "../action-call-classification.js";
|
|
5
6
|
import { ActionContractError, isActionContractError, isActionExposedToExternalAgents, isAgentActionStopError, validateActionArgs, } from "../action.js";
|
|
6
7
|
import { LLM_CREDENTIAL_KEYS, LLM_MISSING_CREDENTIALS_ERROR_CODE, LLM_MISSING_CREDENTIALS_MESSAGE, } from "../agent/engine/credential-errors.js";
|
|
7
8
|
import { isTransientDatabaseError } from "../db/client.js";
|
|
8
9
|
import { declaresFeatureFlagDelegation } from "../feature-flags/a2a-action-route.js";
|
|
9
10
|
import { isFeatureFlagAdminEmail } from "../feature-flags/permissions.js";
|
|
10
|
-
import { isFederationMembershipValidatedForEvent,
|
|
11
|
+
import { isFederationMembershipValidatedForEvent, resolveOrgIdForEmail, } from "../org/context.js";
|
|
11
12
|
import { LLM_PROVIDER_MISSING_ERROR_CODE, LLM_PROVIDER_MISSING_STATUS, } from "../shared/action-error-codes.js";
|
|
12
13
|
import { agentNativeMcpInstructions, agentNativeToolTitle, } from "../shared/agent-mcp-metadata.js";
|
|
13
14
|
import { EMBED_TARGET_HEADER, EMBED_TARGET_QUERY_PARAM, EMBED_TOKEN_QUERY_PARAM, } from "../shared/embed-auth.js";
|
|
@@ -66,8 +67,8 @@ async function resolveFeatureFlagA2ACaller(event, actionName) {
|
|
|
66
67
|
const claims = await verifyA2ATokenWithClaims(token, event);
|
|
67
68
|
if (!claims || !claims.scope.includes(required))
|
|
68
69
|
throw new Error("Invalid feature flag delegation");
|
|
69
|
-
const
|
|
70
|
-
if (!
|
|
70
|
+
const orgId = claims.orgId?.trim() || null;
|
|
71
|
+
if (!orgId && !isFeatureFlagAdminEmail(claims.email))
|
|
71
72
|
throw new Error("Invalid feature flag delegation");
|
|
72
73
|
if (actionName === "set-feature-flag" &&
|
|
73
74
|
(await consumeOneTimeJti(claims.jti))) {
|
|
@@ -75,7 +76,7 @@ async function resolveFeatureFlagA2ACaller(event, actionName) {
|
|
|
75
76
|
}
|
|
76
77
|
return {
|
|
77
78
|
owner: claims.email,
|
|
78
|
-
orgId
|
|
79
|
+
orgId,
|
|
79
80
|
anonymous: false,
|
|
80
81
|
delegationJti: claims.jti,
|
|
81
82
|
delegationIssuer: claims.issuer,
|
|
@@ -386,7 +387,13 @@ function mountActionRoutesInternal(nitroApp, actions, options) {
|
|
|
386
387
|
if (!caller)
|
|
387
388
|
caller = await resolveFeatureFlagA2ACaller(event, name);
|
|
388
389
|
}
|
|
389
|
-
catch {
|
|
390
|
+
catch (error) {
|
|
391
|
+
if (isA2AIdentityVerificationUnavailableError(error)) {
|
|
392
|
+
throw createError({
|
|
393
|
+
statusCode: 503,
|
|
394
|
+
statusMessage: "Identity verification temporarily unavailable",
|
|
395
|
+
});
|
|
396
|
+
}
|
|
390
397
|
throw createError({
|
|
391
398
|
statusCode: 401,
|
|
392
399
|
statusMessage: "Unauthorized",
|
|
@@ -16,9 +16,9 @@ export declare function createAgentEngineDisconnectHandler(): import("h3").Event
|
|
|
16
16
|
error: any;
|
|
17
17
|
scope?: undefined;
|
|
18
18
|
} | {
|
|
19
|
-
error?: undefined;
|
|
20
19
|
ok: boolean;
|
|
21
20
|
scope: "org" | "user";
|
|
21
|
+
error?: undefined;
|
|
22
22
|
}>>;
|
|
23
23
|
export interface DefaultModelSelectionRequest {
|
|
24
24
|
engine: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
2
2
|
error: string;
|
|
3
|
-
ok?: undefined;
|
|
4
3
|
models?: undefined;
|
|
4
|
+
ok?: undefined;
|
|
5
5
|
} | {
|
|
6
|
-
error?: undefined;
|
|
7
6
|
ok: boolean;
|
|
8
7
|
models: string[];
|
|
8
|
+
error?: undefined;
|
|
9
9
|
}>>;
|
|
@@ -43,8 +43,8 @@ export declare class BuilderAccountProvisioningError extends Error {
|
|
|
43
43
|
export declare function isBuilderAccountAlreadyExistsError(error: unknown): boolean;
|
|
44
44
|
export declare function createBuilderConnectState(): string;
|
|
45
45
|
export declare function isSignedBuilderConnectState(value: string | null | undefined): boolean;
|
|
46
|
-
export declare function isBuilderConnectCallbackUrlAllowed(candidate: string, event: H3Event): boolean;
|
|
47
|
-
export declare function resolveBuilderConnectCallbackUrl(event: H3Event, state?: string): string | null;
|
|
46
|
+
export declare function isBuilderConnectCallbackUrlAllowed(candidate: string, event: H3Event, callbackOriginOverride?: string): boolean;
|
|
47
|
+
export declare function resolveBuilderConnectCallbackUrl(event: H3Event, state?: string, callbackOriginOverride?: string): string | null;
|
|
48
48
|
export declare function isSafeBuilderRelayTargetOrigin(value: string): boolean;
|
|
49
49
|
export declare function isTrustedBuilderRelayTargetOrigin(value: string): boolean;
|
|
50
50
|
export declare function resolveBuilderPreviewRelayTargetOrigin(previewOrigin: string): string;
|
|
@@ -94,6 +94,7 @@ export declare const BUILDER_AGENT_NATIVE_CONNECT_SOURCE_PARAM = "agentNativeCon
|
|
|
94
94
|
export declare const BUILDER_AGENT_NATIVE_APP_PARAM = "agentNativeApp";
|
|
95
95
|
export declare const BUILDER_AGENT_NATIVE_TEMPLATE_PARAM = "agentNativeTemplate";
|
|
96
96
|
export declare const BUILDER_CONNECT_MODE_PARAM = "_an_mode";
|
|
97
|
+
export declare const BUILDER_PREVIEW_ORIGIN_HEADER = "x-agent-native-preview-origin";
|
|
97
98
|
export declare const BUILDER_AGENT_NATIVE_PROVISION_MODE = "agent-native";
|
|
98
99
|
export declare const BUILDER_PROVISIONING_TOKEN_PARAM = "_an_provision";
|
|
99
100
|
export declare const BUILDER_CONNECT_ATTEMPT_PARAM = "_an_connect_attempt";
|
|
@@ -207,6 +208,7 @@ export declare function buildBuilderCliAuthUrl(callbackOrigin: string, state?: s
|
|
|
207
208
|
}): string;
|
|
208
209
|
export declare function getBuilderBrowserConnectUrl(origin: string): string;
|
|
209
210
|
export declare function getBuilderBrowserConnectUrlForOwner(origin: string, ownerEmail: string | null | undefined): string;
|
|
211
|
+
export declare function getBuilderConnectCallbackOriginFromUrl(callbackUrl: string): string | null;
|
|
210
212
|
export declare function getBuilderBrowserOriginForEvent(event: H3Event): string;
|
|
211
213
|
export declare function getBuilderCliAuthCallbackOriginForEvent(event: H3Event): string;
|
|
212
214
|
export declare function getBuilderBrowserStatus(origin: string): BuilderBrowserStatus;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, createHmac, randomBytes, timingSafeEqual, } from "node:crypto";
|
|
2
|
-
import { getHeader, getRequestIP, setResponseHeader, setResponseStatus, } from "h3";
|
|
2
|
+
import { getHeader, getQuery, getRequestIP, setResponseHeader, setResponseStatus, } from "h3";
|
|
3
3
|
import { ActionContractError } from "../action.js";
|
|
4
4
|
import { getSetting } from "../settings/store.js";
|
|
5
5
|
import { applyBuilderUtmTrackingParams } from "../shared/builder-link-tracking.js";
|
|
@@ -112,8 +112,8 @@ export function isSignedBuilderConnectState(value) {
|
|
|
112
112
|
return safeEqualText(expected, signature);
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
|
-
export function isBuilderConnectCallbackUrlAllowed(candidate, event) {
|
|
116
|
-
const callbackOrigin = getBuilderConnectCallbackOrigin(event);
|
|
115
|
+
export function isBuilderConnectCallbackUrlAllowed(candidate, event, callbackOriginOverride) {
|
|
116
|
+
const callbackOrigin = getBuilderConnectCallbackOrigin(event, callbackOriginOverride);
|
|
117
117
|
if (!callbackOrigin ||
|
|
118
118
|
!isAllowedOAuthRedirectUri(candidate, event, callbackOrigin))
|
|
119
119
|
return false;
|
|
@@ -137,16 +137,18 @@ export function isBuilderConnectCallbackUrlAllowed(candidate, event) {
|
|
|
137
137
|
}
|
|
138
138
|
return url.protocol === "https:";
|
|
139
139
|
}
|
|
140
|
-
export function resolveBuilderConnectCallbackUrl(event, state) {
|
|
140
|
+
export function resolveBuilderConnectCallbackUrl(event, state, callbackOriginOverride) {
|
|
141
141
|
const stateSuffix = state ? `?state=${encodeURIComponent(state)}` : "";
|
|
142
|
-
const callbackOrigin = getBuilderConnectCallbackOrigin(event);
|
|
142
|
+
const callbackOrigin = getBuilderConnectCallbackOrigin(event, callbackOriginOverride);
|
|
143
143
|
if (!callbackOrigin)
|
|
144
144
|
return null;
|
|
145
145
|
const withBase = `${callbackOrigin}${getAppBasePath()}${BUILDER_CALLBACK_PATH}${stateSuffix}`;
|
|
146
|
-
if (isBuilderConnectCallbackUrlAllowed(withBase, event))
|
|
146
|
+
if (isBuilderConnectCallbackUrlAllowed(withBase, event, callbackOriginOverride)) {
|
|
147
147
|
return withBase;
|
|
148
|
+
}
|
|
148
149
|
const root = `${callbackOrigin}${BUILDER_CALLBACK_PATH}${stateSuffix}`;
|
|
149
|
-
if (root !== withBase &&
|
|
150
|
+
if (root !== withBase &&
|
|
151
|
+
isBuilderConnectCallbackUrlAllowed(root, event, callbackOriginOverride)) {
|
|
150
152
|
return root;
|
|
151
153
|
}
|
|
152
154
|
return null;
|
|
@@ -429,6 +431,9 @@ export const BUILDER_AGENT_NATIVE_CONNECT_SOURCE_PARAM = "agentNativeConnectSour
|
|
|
429
431
|
export const BUILDER_AGENT_NATIVE_APP_PARAM = "agentNativeApp";
|
|
430
432
|
export const BUILDER_AGENT_NATIVE_TEMPLATE_PARAM = "agentNativeTemplate";
|
|
431
433
|
export const BUILDER_CONNECT_MODE_PARAM = "_an_mode";
|
|
434
|
+
export const BUILDER_PREVIEW_ORIGIN_HEADER = "x-agent-native-preview-origin";
|
|
435
|
+
const BUILDER_PREVIEW_ORIGIN_PARAM = "_an_preview_origin";
|
|
436
|
+
const BUILDER_PREVIEW_ORIGIN_SIGNATURE_PARAM = "_an_preview_origin_signature";
|
|
432
437
|
export const BUILDER_AGENT_NATIVE_PROVISION_MODE = "agent-native";
|
|
433
438
|
export const BUILDER_PROVISIONING_TOKEN_PARAM = "_an_provision";
|
|
434
439
|
export const BUILDER_CONNECT_ATTEMPT_PARAM = "_an_connect_attempt";
|
|
@@ -958,7 +963,15 @@ function isConfiguredBuilderRequestHost(event, host) {
|
|
|
958
963
|
(process.env.NODE_ENV === "production" ? "https" : "http");
|
|
959
964
|
return isConfiguredAppOrigin(`${proto}://${host}`);
|
|
960
965
|
}
|
|
961
|
-
function getBuilderConnectCallbackOrigin(event) {
|
|
966
|
+
function getBuilderConnectCallbackOrigin(event, originOverride) {
|
|
967
|
+
if (originOverride) {
|
|
968
|
+
return isAllowedBuilderConnectOrigin(originOverride)
|
|
969
|
+
? originOverride
|
|
970
|
+
: null;
|
|
971
|
+
}
|
|
972
|
+
const signedPreviewOrigin = getSignedBuilderPreviewOriginFromEvent(event);
|
|
973
|
+
if (signedPreviewOrigin)
|
|
974
|
+
return signedPreviewOrigin;
|
|
962
975
|
const requestHost = firstHeaderValue(readEventHeader(event, "host"));
|
|
963
976
|
const headerHost = getBuilderRequestHost(event);
|
|
964
977
|
if (isRejectedDirectBuilderCloudHost(requestHost, headerHost)) {
|
|
@@ -978,6 +991,123 @@ function getBuilderConnectCallbackOrigin(event) {
|
|
|
978
991
|
}
|
|
979
992
|
return configuredOrigin;
|
|
980
993
|
}
|
|
994
|
+
function isAllowedBuilderConnectOrigin(origin) {
|
|
995
|
+
let url;
|
|
996
|
+
try {
|
|
997
|
+
url = new URL(origin);
|
|
998
|
+
}
|
|
999
|
+
catch {
|
|
1000
|
+
// coercion-ok: a malformed callback origin is explicitly rejected.
|
|
1001
|
+
return false;
|
|
1002
|
+
}
|
|
1003
|
+
if (url.origin !== origin ||
|
|
1004
|
+
url.username ||
|
|
1005
|
+
url.password ||
|
|
1006
|
+
url.pathname !== "/" ||
|
|
1007
|
+
url.search ||
|
|
1008
|
+
url.hash) {
|
|
1009
|
+
return false;
|
|
1010
|
+
}
|
|
1011
|
+
if (isTrustedBuilderRequestHost(url.host)) {
|
|
1012
|
+
return (url.protocol === "https:" ||
|
|
1013
|
+
(url.protocol === "http:" && process.env.NODE_ENV !== "production"));
|
|
1014
|
+
}
|
|
1015
|
+
return isConfiguredAppOrigin(origin);
|
|
1016
|
+
}
|
|
1017
|
+
function normalizeBuilderPreviewOrigin(value) {
|
|
1018
|
+
try {
|
|
1019
|
+
const url = new URL(value);
|
|
1020
|
+
if (url.origin !== value ||
|
|
1021
|
+
url.username ||
|
|
1022
|
+
url.password ||
|
|
1023
|
+
url.pathname !== "/" ||
|
|
1024
|
+
url.search ||
|
|
1025
|
+
url.hash ||
|
|
1026
|
+
(url.protocol !== "https:" &&
|
|
1027
|
+
!(url.protocol === "http:" && process.env.NODE_ENV !== "production"))) {
|
|
1028
|
+
return null;
|
|
1029
|
+
}
|
|
1030
|
+
return url.origin;
|
|
1031
|
+
}
|
|
1032
|
+
catch {
|
|
1033
|
+
// coercion-ok: a malformed preview origin is not an allowed origin.
|
|
1034
|
+
return null;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
function getSameOriginBuilderPreviewOrigin(event) {
|
|
1038
|
+
const rawOrigin = firstHeaderValue(readEventHeader(event, BUILDER_PREVIEW_ORIGIN_HEADER));
|
|
1039
|
+
if (!rawOrigin || readEventHeader(event, "sec-fetch-site") === "cross-site") {
|
|
1040
|
+
return null;
|
|
1041
|
+
}
|
|
1042
|
+
const origin = normalizeBuilderPreviewOrigin(rawOrigin);
|
|
1043
|
+
if (!origin || !isTrustedBuilderRequestHost(new URL(origin).host)) {
|
|
1044
|
+
return null;
|
|
1045
|
+
}
|
|
1046
|
+
const requestHost = firstHeaderValue(readEventHeader(event, "host"));
|
|
1047
|
+
if (!requestHost ||
|
|
1048
|
+
(!isLoopbackBuilderRequestHost(requestHost) &&
|
|
1049
|
+
requestHost.toLowerCase() !== new URL(origin).host.toLowerCase())) {
|
|
1050
|
+
return null;
|
|
1051
|
+
}
|
|
1052
|
+
const fetchSite = readEventHeader(event, "sec-fetch-site");
|
|
1053
|
+
const requestOrigin = firstHeaderValue(readEventHeader(event, "origin"));
|
|
1054
|
+
if (fetchSite === "same-origin" || requestOrigin === origin)
|
|
1055
|
+
return origin;
|
|
1056
|
+
const referer = firstHeaderValue(readEventHeader(event, "referer"));
|
|
1057
|
+
if (!referer)
|
|
1058
|
+
return null;
|
|
1059
|
+
try {
|
|
1060
|
+
return new URL(referer).origin === origin ? origin : null;
|
|
1061
|
+
}
|
|
1062
|
+
catch {
|
|
1063
|
+
// coercion-ok: an unreadable Referer cannot authorize a preview origin.
|
|
1064
|
+
return null;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function signBuilderPreviewOrigin(origin) {
|
|
1068
|
+
return createHmac("sha256", builderConnectStateSigningKeys()[0])
|
|
1069
|
+
.update(`builder-connect-preview-origin\0${origin}`)
|
|
1070
|
+
.digest("base64url");
|
|
1071
|
+
}
|
|
1072
|
+
function getSignedBuilderPreviewOriginFromEvent(event) {
|
|
1073
|
+
const query = getQuery(event);
|
|
1074
|
+
const rawOrigin = query[BUILDER_PREVIEW_ORIGIN_PARAM];
|
|
1075
|
+
const signature = query[BUILDER_PREVIEW_ORIGIN_SIGNATURE_PARAM];
|
|
1076
|
+
if (typeof rawOrigin !== "string" || typeof signature !== "string") {
|
|
1077
|
+
return null;
|
|
1078
|
+
}
|
|
1079
|
+
const origin = normalizeBuilderPreviewOrigin(rawOrigin);
|
|
1080
|
+
if (!origin || !isTrustedBuilderRequestHost(new URL(origin).host)) {
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
const requestHost = firstHeaderValue(readEventHeader(event, "host"));
|
|
1084
|
+
if (!requestHost ||
|
|
1085
|
+
(!isLoopbackBuilderRequestHost(requestHost) &&
|
|
1086
|
+
requestHost.toLowerCase() !== new URL(origin).host.toLowerCase())) {
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
return builderConnectStateSigningKeys().some((key) => safeEqualText(createHmac("sha256", key)
|
|
1090
|
+
.update(`builder-connect-preview-origin\0${origin}`)
|
|
1091
|
+
.digest("base64url"), signature))
|
|
1092
|
+
? origin
|
|
1093
|
+
: null;
|
|
1094
|
+
}
|
|
1095
|
+
function addSignedBuilderPreviewOrigin(url, origin) {
|
|
1096
|
+
const parsed = new URL(url);
|
|
1097
|
+
parsed.searchParams.set(BUILDER_PREVIEW_ORIGIN_PARAM, origin);
|
|
1098
|
+
parsed.searchParams.set(BUILDER_PREVIEW_ORIGIN_SIGNATURE_PARAM, signBuilderPreviewOrigin(origin));
|
|
1099
|
+
return parsed.toString();
|
|
1100
|
+
}
|
|
1101
|
+
export function getBuilderConnectCallbackOriginFromUrl(callbackUrl) {
|
|
1102
|
+
try {
|
|
1103
|
+
const origin = new URL(callbackUrl).origin;
|
|
1104
|
+
return isAllowedBuilderConnectOrigin(origin) ? origin : null;
|
|
1105
|
+
}
|
|
1106
|
+
catch {
|
|
1107
|
+
// coercion-ok: a malformed stored callback URL must fail verification.
|
|
1108
|
+
return null;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
981
1111
|
function isRejectedDirectBuilderCloudHost(requestHost, resolvedHost) {
|
|
982
1112
|
return isBuilderCloudRequestHost(requestHost) && requestHost !== resolvedHost;
|
|
983
1113
|
}
|
|
@@ -986,6 +1116,9 @@ function getConfiguredBuilderFallbackOrigin(event) {
|
|
|
986
1116
|
return isConfiguredAppOrigin(origin) ? origin : null;
|
|
987
1117
|
}
|
|
988
1118
|
export function getBuilderBrowserOriginForEvent(event) {
|
|
1119
|
+
const signedPreviewOrigin = getSignedBuilderPreviewOriginFromEvent(event);
|
|
1120
|
+
if (signedPreviewOrigin)
|
|
1121
|
+
return signedPreviewOrigin;
|
|
989
1122
|
const requestHost = firstHeaderValue(readEventHeader(event, "host"));
|
|
990
1123
|
const headerHost = getBuilderRequestHost(event);
|
|
991
1124
|
if (isRejectedDirectBuilderCloudHost(requestHost, headerHost)) {
|
|
@@ -1057,7 +1190,12 @@ function parseOptionalEnvBoolean(value) {
|
|
|
1057
1190
|
return /^(1|true)$/i.test(value);
|
|
1058
1191
|
}
|
|
1059
1192
|
export function getBuilderBrowserStatusForEvent(event) {
|
|
1060
|
-
|
|
1193
|
+
const previewOrigin = getSameOriginBuilderPreviewOrigin(event);
|
|
1194
|
+
const status = getBuilderBrowserStatus(previewOrigin ?? getBuilderBrowserOriginForEvent(event));
|
|
1195
|
+
if (previewOrigin && status.connectUrl) {
|
|
1196
|
+
status.connectUrl = addSignedBuilderPreviewOrigin(status.connectUrl, previewOrigin);
|
|
1197
|
+
}
|
|
1198
|
+
return status;
|
|
1061
1199
|
}
|
|
1062
1200
|
export const BUILDER_ENV_KEYS = [
|
|
1063
1201
|
"BUILDER_PRIVATE_KEY",
|
|
@@ -59,7 +59,7 @@ import { getSession } from "./auth.js";
|
|
|
59
59
|
import { createAutomationFailureUnsubscribeHandler } from "./automation-failure-notifications.js";
|
|
60
60
|
import { getBetterAuthInternalAdapter, getBetterAuthSync, } from "./better-auth-instance.js";
|
|
61
61
|
import { resolveBuilderRequestAuthorization } from "./builder-api-auth.js";
|
|
62
|
-
import { BUILDER_CONNECT_PARAM, BUILDER_CONNECT_MODE_PARAM, BUILDER_AGENT_NATIVE_PROVISION_MODE, BUILDER_CONNECT_ATTEMPT_PARAM, BUILDER_CONNECT_STATE_COOKIE, BUILDER_ENV_KEYS, BUILDER_OPENER_PARAM, BUILDER_RELAY_FLOW_HEADER, BUILDER_RELAY_SIGNATURE_HEADER, BUILDER_RELAY_STATE_PARAM, BUILDER_RELAY_TIMESTAMP_HEADER, appendBuilderConnectToken, appendBuilderConnectStateCookie, builderConnectTrackingProperties, BUILDER_UPSTREAM_FAILURE_STATUS, createBuilderConnectState, createBuilderBrowserCallbackErrorPage, createBuilderBrowserCallbackPage, createBuilderRelayRequest, getBuilderConnectTrackingParams, getBuilderBrowserOriginForEvent, getBuilderBrowserStatusForEvent, isBuilderAccountAlreadyExistsError, isBuilderAccountProvisioningEnabled, isBuilderConnectCallbackUrlAllowed, isSignedBuilderConnectState, normalizeBuilderAgentContext, parseBuilderConnectStateCookie, provisionBuilderAccount, resolveBuilderBranchProjectId, resolveBuilderConnectCallbackUrl, resolveBuilderConnectCallbackState, resolveBuilderPreviewRelayParentOrigin, removeBuilderConnectStateCookie, runBuilderAgent, sendBuilderPopupErrorPage, verifyBuilderRelayRequest, verifyBuilderPreviewRelayStateForCallback, verifyBuilderConnectTokenAndGetOwner, signBuilderProvisioningToken, verifyBuilderProvisioningToken, withBuilderConnectTrackingParams, } from "./builder-browser.js";
|
|
62
|
+
import { BUILDER_CONNECT_PARAM, BUILDER_CONNECT_MODE_PARAM, BUILDER_AGENT_NATIVE_PROVISION_MODE, BUILDER_CONNECT_ATTEMPT_PARAM, BUILDER_CONNECT_STATE_COOKIE, BUILDER_ENV_KEYS, BUILDER_OPENER_PARAM, BUILDER_RELAY_FLOW_HEADER, BUILDER_RELAY_SIGNATURE_HEADER, BUILDER_RELAY_STATE_PARAM, BUILDER_RELAY_TIMESTAMP_HEADER, appendBuilderConnectToken, appendBuilderConnectStateCookie, builderConnectTrackingProperties, BUILDER_UPSTREAM_FAILURE_STATUS, createBuilderConnectState, createBuilderBrowserCallbackErrorPage, createBuilderBrowserCallbackPage, createBuilderRelayRequest, getBuilderConnectCallbackOriginFromUrl, getBuilderConnectTrackingParams, getBuilderBrowserOriginForEvent, getBuilderBrowserStatusForEvent, isBuilderAccountAlreadyExistsError, isBuilderAccountProvisioningEnabled, isBuilderConnectCallbackUrlAllowed, isSignedBuilderConnectState, normalizeBuilderAgentContext, parseBuilderConnectStateCookie, provisionBuilderAccount, resolveBuilderBranchProjectId, resolveBuilderConnectCallbackUrl, resolveBuilderConnectCallbackState, resolveBuilderPreviewRelayParentOrigin, removeBuilderConnectStateCookie, runBuilderAgent, sendBuilderPopupErrorPage, verifyBuilderRelayRequest, verifyBuilderPreviewRelayStateForCallback, verifyBuilderConnectTokenAndGetOwner, signBuilderProvisioningToken, verifyBuilderProvisioningToken, withBuilderConnectTrackingParams, } from "./builder-browser.js";
|
|
63
63
|
import { BUILDER_ASSETS_WRITE_SCOPE, BUILDER_OAUTH_SCOPE, builderOAuthScopeFor, canRoleConnectPersonalBuilder, deleteBuilderOAuthSession, exchangeBuilderOAuthAuthorization, getBuilderOAuthGrants, getBuilderOAuthStoredScope, hasStoredBuilderOAuthGrant, isBuilderOrgManagerRole, isPersonalBuilderGrantAllowed, saveBuilderOAuthCredentials, startBuilderOAuthAuthorization, } from "./builder-oauth.js";
|
|
64
64
|
import { captureError, registerErrorCaptureProvider } from "./capture-error.js";
|
|
65
65
|
import { createChatGPTSubscriptionOAuthCallbackHandler, createChatGPTSubscriptionOAuthStartHandler, } from "./chatgpt-subscription-oauth.js";
|
|
@@ -3472,7 +3472,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
3472
3472
|
? await selectLiveBuilderConnectStates(cookieStates)
|
|
3473
3473
|
: cookieStates;
|
|
3474
3474
|
const { state, resetStateCookie } = resolveBuilderConnectCallbackState(queryState, liveStates ? liveStates.join(",") : rawStateCookie);
|
|
3475
|
-
|
|
3475
|
+
let parentOrigin = getBuilderBrowserOriginForEvent(event);
|
|
3476
|
+
let callbackOriginOverride;
|
|
3476
3477
|
let callbackAttemptId = requestConnectAttemptId;
|
|
3477
3478
|
// A finished attempt — succeeded or failed — must not leave its
|
|
3478
3479
|
// state in the cookie, or the next restart resolves against two
|
|
@@ -3492,8 +3493,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
3492
3493
|
}
|
|
3493
3494
|
setCookie(event, BUILDER_CONNECT_STATE_COOKIE, remaining, {
|
|
3494
3495
|
httpOnly: true,
|
|
3495
|
-
secure: (resolveBuilderConnectCallbackUrl(event, finishedState) ??
|
|
3496
|
-
parentOrigin).startsWith("https://"),
|
|
3496
|
+
secure: (resolveBuilderConnectCallbackUrl(event, finishedState, callbackOriginOverride) ?? parentOrigin).startsWith("https://"),
|
|
3497
3497
|
sameSite: "lax",
|
|
3498
3498
|
path: "/",
|
|
3499
3499
|
maxAge: Math.ceil(BUILDER_CONNECT_PENDING_TTL_MS / 1_000),
|
|
@@ -3553,7 +3553,14 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
3553
3553
|
const redirectUri = typeof pending.redirectUri === "string"
|
|
3554
3554
|
? pending.redirectUri
|
|
3555
3555
|
: null;
|
|
3556
|
-
const
|
|
3556
|
+
const storedCallbackOrigin = redirectUri
|
|
3557
|
+
? getBuilderConnectCallbackOriginFromUrl(redirectUri)
|
|
3558
|
+
: null;
|
|
3559
|
+
if (storedCallbackOrigin) {
|
|
3560
|
+
callbackOriginOverride = storedCallbackOrigin;
|
|
3561
|
+
parentOrigin = storedCallbackOrigin;
|
|
3562
|
+
}
|
|
3563
|
+
const expectedRedirectUri = resolveBuilderConnectCallbackUrl(event, state, callbackOriginOverride);
|
|
3557
3564
|
if (!ownerEmail ||
|
|
3558
3565
|
!isBuilderConnectCallbackOwner(ownerEmail, session?.email) ||
|
|
3559
3566
|
Date.now() >= expiresAt ||
|
|
@@ -3561,7 +3568,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
3561
3568
|
!redirectUri ||
|
|
3562
3569
|
!expectedRedirectUri ||
|
|
3563
3570
|
redirectUri !== expectedRedirectUri ||
|
|
3564
|
-
!isBuilderConnectCallbackUrlAllowed(redirectUri, event)) {
|
|
3571
|
+
!isBuilderConnectCallbackUrlAllowed(redirectUri, event, callbackOriginOverride)) {
|
|
3565
3572
|
if (Date.now() >= expiresAt) {
|
|
3566
3573
|
await deleteSetting(`builder-connect-pending:${state}`).catch(() => false); // coercion-ok: expired pending cleanup is best-effort; callback already failed verification
|
|
3567
3574
|
}
|
|
@@ -2,8 +2,49 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import ReactDOMServer from "react-dom/server.browser";
|
|
3
3
|
const { renderToReadableStream } = ReactDOMServer;
|
|
4
4
|
import { isbot } from "isbot";
|
|
5
|
+
import { ROUTE_CHUNK_RECOVERY_BOOTSTRAP_SCRIPT } from "../shared/route-chunk-recovery-bootstrap.js";
|
|
5
6
|
import { wrapWithAnalytics } from "./analytics.js";
|
|
6
7
|
export const streamTimeout = 5_000;
|
|
8
|
+
const HEAD_OPEN_PATTERN = /<head\b[^>]*>/i;
|
|
9
|
+
const CHUNK_RECOVERY_BOOTSTRAP_TAG = `<script data-agent-native-chunk-recovery-bootstrap>${ROUTE_CHUNK_RECOVERY_BOOTSTRAP_SCRIPT}</script>`;
|
|
10
|
+
function installEarlyChunkRecoveryBootstrap(body) {
|
|
11
|
+
const decoder = new TextDecoder();
|
|
12
|
+
const encoder = new TextEncoder();
|
|
13
|
+
let pending = "";
|
|
14
|
+
let injected = false;
|
|
15
|
+
return body.pipeThrough(new TransformStream({
|
|
16
|
+
transform(chunk, controller) {
|
|
17
|
+
pending += decoder.decode(chunk, { stream: true });
|
|
18
|
+
if (!injected) {
|
|
19
|
+
const headOpenMatch = HEAD_OPEN_PATTERN.exec(pending);
|
|
20
|
+
if (!headOpenMatch || headOpenMatch.index === undefined)
|
|
21
|
+
return;
|
|
22
|
+
const headEnd = headOpenMatch.index + headOpenMatch[0].length;
|
|
23
|
+
controller.enqueue(encoder.encode(pending.slice(0, headEnd) + CHUNK_RECOVERY_BOOTSTRAP_TAG));
|
|
24
|
+
pending = pending.slice(headEnd);
|
|
25
|
+
injected = true;
|
|
26
|
+
}
|
|
27
|
+
if (pending) {
|
|
28
|
+
controller.enqueue(encoder.encode(pending));
|
|
29
|
+
pending = "";
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
flush(controller) {
|
|
33
|
+
pending += decoder.decode();
|
|
34
|
+
if (!injected) {
|
|
35
|
+
const headOpenMatch = HEAD_OPEN_PATTERN.exec(pending);
|
|
36
|
+
if (headOpenMatch && headOpenMatch.index !== undefined) {
|
|
37
|
+
const headEnd = headOpenMatch.index + headOpenMatch[0].length;
|
|
38
|
+
controller.enqueue(encoder.encode(pending.slice(0, headEnd) + CHUNK_RECOVERY_BOOTSTRAP_TAG));
|
|
39
|
+
pending = pending.slice(headEnd);
|
|
40
|
+
injected = true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (pending)
|
|
44
|
+
controller.enqueue(encoder.encode(pending));
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
7
48
|
export function createDocumentRequestHandler(ServerRouter) {
|
|
8
49
|
return async function handleDocumentRequest(request, responseStatusCode, responseHeaders, routerContext, _loadContext) {
|
|
9
50
|
if (request.method.toUpperCase() === "HEAD") {
|
|
@@ -33,8 +74,8 @@ export function createDocumentRequestHandler(ServerRouter) {
|
|
|
33
74
|
if (waitForAll) {
|
|
34
75
|
await body.allReady;
|
|
35
76
|
}
|
|
36
|
-
responseHeaders.set("Content-Type", "text/html");
|
|
37
|
-
return new Response(wrapWithAnalytics(body), {
|
|
77
|
+
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
|
|
78
|
+
return new Response(wrapWithAnalytics(installEarlyChunkRecoveryBootstrap(body)), {
|
|
38
79
|
headers: responseHeaders,
|
|
39
80
|
status: responseStatusCode,
|
|
40
81
|
});
|
package/dist/server/sentry.js
CHANGED
|
@@ -258,8 +258,10 @@ export function setSentryRequestContext(ctx) {
|
|
|
258
258
|
export function captureAuthError(error, context) {
|
|
259
259
|
if (getRequestContext()?.isSyntheticTraffic)
|
|
260
260
|
return undefined;
|
|
261
|
-
if (!_initSucceeded || !Sentry)
|
|
261
|
+
if (!_initSucceeded || !Sentry) {
|
|
262
|
+
logSignupErrorWhenSentryUnavailable(context.route);
|
|
262
263
|
return undefined;
|
|
264
|
+
}
|
|
263
265
|
const sentry = Sentry;
|
|
264
266
|
try {
|
|
265
267
|
return sentry.withScope((scope) => {
|
|
@@ -274,9 +276,15 @@ export function captureAuthError(error, context) {
|
|
|
274
276
|
});
|
|
275
277
|
}
|
|
276
278
|
catch {
|
|
279
|
+
logSignupErrorWhenSentryUnavailable(context.route);
|
|
277
280
|
return undefined;
|
|
278
281
|
}
|
|
279
282
|
}
|
|
283
|
+
function logSignupErrorWhenSentryUnavailable(route) {
|
|
284
|
+
if (route !== "signup")
|
|
285
|
+
return;
|
|
286
|
+
console.error("[agent-native][auth] signup error (Sentry unavailable)");
|
|
287
|
+
}
|
|
280
288
|
export function captureRouteError(error, context = {}) {
|
|
281
289
|
if (getRequestContext()?.isSyntheticTraffic)
|
|
282
290
|
return undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
|
|
1
|
+
export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, resolveSsrNetlifyQueryVary, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
|
|
2
2
|
export declare function createH3SSRHandler(getBuild: () => unknown): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<Response>>;
|
|
@@ -13,7 +13,7 @@ import { getFrameworkRoutePrefix } from "./framework-route-prefix.js";
|
|
|
13
13
|
import { getPostHogClientConfigScript } from "./posthog-config.js";
|
|
14
14
|
import { runWithRequestContext } from "./request-context.js";
|
|
15
15
|
import { getRealtimeClientConfigScript, getSentryClientConfigScript, } from "./sentry-config.js";
|
|
16
|
-
export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
|
|
16
|
+
export { DEFAULT_SSR_CACHE_HEADERS, DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, DISABLED_SSR_CACHE_HEADERS, isSsrCacheEnabled, resolveSsrCacheHeaders, resolveSsrCacheKeyHeaders, resolveSsrNetlifyQueryVary, SSR_CACHE_ENV_VAR, } from "../shared/cache-control.js";
|
|
17
17
|
function getAppBasePath() {
|
|
18
18
|
return getAppBasePathFromViteEnv();
|
|
19
19
|
}
|
|
@@ -215,12 +215,8 @@ function applyDefaultSsrCacheHeader(headers, status, pathname) {
|
|
|
215
215
|
for (const [name, value] of Object.entries(resolveSsrCacheHeaders())) {
|
|
216
216
|
headers.set(name, value);
|
|
217
217
|
}
|
|
218
|
-
const cacheKeyHeaders = resolveSsrCacheKeyHeaders();
|
|
219
|
-
const netlifyVary =
|
|
220
|
-
? cacheKeyHeaders["netlify-vary"]
|
|
221
|
-
? "query"
|
|
222
|
-
: undefined
|
|
223
|
-
: cacheKeyHeaders["netlify-vary"];
|
|
218
|
+
const cacheKeyHeaders = resolveSsrCacheKeyHeaders(undefined, { varyByQuery });
|
|
219
|
+
const netlifyVary = cacheKeyHeaders["netlify-vary"];
|
|
224
220
|
if (netlifyVary)
|
|
225
221
|
headers.set("netlify-vary", netlifyVary);
|
|
226
222
|
else
|
|
@@ -32,7 +32,10 @@ export type SsrCacheHeaders = Record<"cache-control" | "cdn-cache-control" | "ne
|
|
|
32
32
|
export declare function parseSsrCacheSetting(raw: string | undefined | null): SsrCachePolicy;
|
|
33
33
|
export declare function ssrCacheHeadersForPolicy(policy: SsrCachePolicy): SsrCacheHeaders;
|
|
34
34
|
export declare function resolveSsrCacheHeaders(env?: Record<string, string | undefined>): Readonly<SsrCacheHeaders>;
|
|
35
|
-
export declare function
|
|
35
|
+
export declare function resolveSsrNetlifyQueryVary(varyByQuery?: boolean): string;
|
|
36
|
+
export declare function resolveSsrCacheKeyHeaders(env?: Record<string, string | undefined>, options?: {
|
|
37
|
+
varyByQuery?: boolean;
|
|
38
|
+
}): Readonly<Record<string, string>>;
|
|
36
39
|
export declare function isSsrCacheEnabled(env?: Record<string, string | undefined>): boolean;
|
|
37
40
|
export declare const DEFAULT_SPECULATION_RULES_PATH = "/_agent-native/speculation-rules.json";
|
|
38
41
|
export declare const DEFAULT_SPECULATION_RULES_HEADER = "\"/_agent-native/speculation-rules.json\"";
|