@patternfly/patternfly-doc-core 1.10.0 → 1.11.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/astro.config.mjs +3 -4
- package/cli/cli.ts +60 -19
- package/dist/.assetsignore +2 -0
- package/dist/_astro/ClientRouter.astro_astro_type_script_index_0_lang.CtSceO8m.js +1 -0
- package/dist/_astro/client.DN8ES6L5.js +1 -0
- package/dist/_routes.json +20 -0
- package/dist/_worker.js/_@astrojs-ssr-adapter.mjs +2 -0
- package/dist/_worker.js/_astro-internal_middleware.mjs +21 -0
- package/dist/_worker.js/_noop-actions.mjs +4 -0
- package/dist/{server/chunks/AutoLinkHeader_C2GD0g-K.mjs → _worker.js/chunks/AutoLinkHeader_xh_mBOfs.mjs} +13 -14
- package/dist/{server/chunks/Button_BKhHR-ak.mjs → _worker.js/chunks/Button_ByndGYyw.mjs} +83 -13
- package/dist/{server/chunks/CSSTable_B8tlH3gz.mjs → _worker.js/chunks/CSSTable_DAbso55e.mjs} +3 -3
- package/dist/_worker.js/chunks/PropsTables_BZngJp47.mjs +6628 -0
- package/dist/_worker.js/chunks/_@astrojs-ssr-adapter_C9Nk07-M.mjs +1082 -0
- package/dist/_worker.js/chunks/angle-down-icon_yt3z9cvI.mjs +3686 -0
- package/dist/_worker.js/chunks/astro/server_BpfPtTmt.mjs +7278 -0
- package/dist/_worker.js/chunks/astro-designed-error-pages_4xWqsa9_.mjs +928 -0
- package/dist/_worker.js/chunks/cloudflare-kv-binding_DMly_2Gl.mjs +107 -0
- package/dist/_worker.js/chunks/index_Dc2aKkl4.mjs +57 -0
- package/dist/{server/chunks/_@astrojs-ssr-adapter_CbICuCdt.mjs → _worker.js/chunks/index_DlGha6WC.mjs} +1295 -1817
- package/dist/_worker.js/chunks/noop-middleware_Ct44Kk5Y.mjs +10 -0
- package/dist/_worker.js/chunks/parse_EttCPxrw.mjs +271 -0
- package/dist/{server/chunks/path_Cvt6sEOY.mjs → _worker.js/chunks/path_C-ZOwaTP.mjs} +2 -1
- package/dist/{server/entry.mjs → _worker.js/index.js} +12 -19
- package/dist/_worker.js/manifest_DcBPbZXQ.mjs +100 -0
- package/dist/_worker.js/pages/_image.astro.mjs +24 -0
- package/dist/_worker.js/pages/_section_/_page_/_---tab_.astro.mjs +1 -0
- package/dist/_worker.js/pages/index.astro.mjs +1 -0
- package/dist/{server → _worker.js}/pages/props.astro.mjs +3 -2
- package/dist/_worker.js/renderers.mjs +484 -0
- package/dist/cli/cli.js +46 -12
- package/dist/{client/components/accordion/react → components/accordion}/index.html +14 -64
- package/dist/{client/components/accordion → components/accordion/react}/index.html +14 -64
- package/dist/components/all-components/index.html +47 -0
- package/dist/design-foundations/typography/index.html +198 -0
- package/dist/{client/design-foundations → design-foundations}/usage-and-behavior/index.html +4 -54
- package/dist/get-started/contribute/index.html +94 -0
- package/dist/index.html +43 -0
- package/package.json +12 -8
- package/public/.assetsignore +2 -0
- package/src/pages/props.ts +2 -2
- package/wrangler.jsonc +14 -0
- package/dist/client/_astro/ClientRouter.astro_astro_type_script_index_0_lang.Cainpjm5.js +0 -1
- package/dist/client/_astro/client.zs76E0tG.js +0 -1
- package/dist/client/components/all-components/index.html +0 -97
- package/dist/client/design-foundations/typography/index.html +0 -248
- package/dist/client/get-started/contribute/index.html +0 -144
- package/dist/client/index.html +0 -43
- package/dist/server/_@astrojs-ssr-adapter.mjs +0 -1
- package/dist/server/_noop-middleware.mjs +0 -3
- package/dist/server/chunks/PropsTables_PVzRHJNB.mjs +0 -1750
- package/dist/server/chunks/_astro_assets_DaYumpRZ.mjs +0 -1507
- package/dist/server/chunks/angle-down-icon_BO1Ed-9Z.mjs +0 -3288
- package/dist/server/chunks/astro/server_Cl9jPh4p.mjs +0 -2859
- package/dist/server/chunks/astro-designed-error-pages_BFveJFnQ.mjs +0 -282
- package/dist/server/chunks/consts_BmVDRGlB.mjs +0 -32
- package/dist/server/chunks/sharp_CbOL3WDk.mjs +0 -88
- package/dist/server/manifest_DsbMfV1U.mjs +0 -102
- package/dist/server/pages/_image.astro.mjs +0 -132
- package/dist/server/renderers.mjs +0 -308
- /package/dist/{client/PF-HorizontalLogo-Color.svg → PF-HorizontalLogo-Color.svg} +0 -0
- /package/dist/{client/PF-HorizontalLogo-Reverse.svg → PF-HorizontalLogo-Reverse.svg} +0 -0
- /package/dist/{client/_astro → _astro}/Button.BQCwQ5pE.js +0 -0
- /package/dist/{client/_astro → _astro}/CSSTable.DC79W1Ct.js +0 -0
- /package/dist/{client/_astro → _astro}/Content.B4M2qzJY.js +0 -0
- /package/dist/{client/_astro → _astro}/DropdownList.cxp03sS4.js +0 -0
- /package/dist/{client/_astro → _astro}/LiveExample.CxJsMvEq.css +0 -0
- /package/dist/{client/_astro → _astro}/LiveExample.DjPiO80i.js +0 -0
- /package/dist/{client/_astro → _astro}/Navigation.kbLxctIo.js +0 -0
- /package/dist/{client/_astro → _astro}/PageContext.miTsIqVo.js +0 -0
- /package/dist/{client/_astro → _astro}/PageSidebarBody.B0AJe8Hg.js +0 -0
- /package/dist/{client/_astro → _astro}/PageToggle.CMZ3C1v1.js +0 -0
- /package/dist/{client/_astro → _astro}/RedHatDisplayVF-Italic.CRpusWc8.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/RedHatDisplayVF.CYDHf1NI.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/RedHatMonoVF-Italic.DGQo2ogW.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/RedHatMonoVF.C4fMH6Vz.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/RedHatTextVF-Italic.Dkj_WqbA.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/RedHatTextVF.wYvZ7prR.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/SearchInput.DhHo7yPx.js +0 -0
- /package/dist/{client/_astro → _astro}/SectionGallery.3ABpQwE4.js +0 -0
- /package/dist/{client/_astro → _astro}/Toolbar.CroDQcyv.js +0 -0
- /package/dist/{client/_astro → _astro}/ToolbarContent.UH3ZRlHp.js +0 -0
- /package/dist/{client/_astro → _astro}/_page_.Chv_bGyU.css +0 -0
- /package/dist/{client/_astro → _astro}/_page_.CtheD08_.css +0 -0
- /package/dist/{client/_astro → _astro}/_page_.D1z73Byz.css +0 -0
- /package/dist/{client/_astro → _astro}/_page_.DxJDkZPc.css +0 -0
- /package/dist/{client/_astro → _astro}/angle-left-icon.teo8GC0v.js +0 -0
- /package/dist/{client/_astro → _astro}/bars-icon.Dk6ua1rr.js +0 -0
- /package/dist/{client/_astro → _astro}/divider.tlrBPkzg.js +0 -0
- /package/dist/{client/_astro → _astro}/fa-solid-900.DguXoeIz.woff2 +0 -0
- /package/dist/{client/_astro → _astro}/github-icon.ByC5XEPt.js +0 -0
- /package/dist/{client/_astro → _astro}/index.BQFV5hT1.js +0 -0
- /package/dist/{client/_astro → _astro}/index.CAChmxYj.js +0 -0
- /package/dist/{client/_astro → _astro}/index.DYVB4vTo.js +0 -0
- /package/dist/{client/_astro → _astro}/index.eCxJ45ll.js +0 -0
- /package/dist/{client/_astro → _astro}/link-icon.BNHnRn73.js +0 -0
- /package/dist/{client/_astro → _astro}/page.BTC3Kf3x.js +0 -0
- /package/dist/{client/_astro → _astro}/pf-v6-pficon.Dy6oiu9u.woff2 +0 -0
- /package/dist/{server/chunks/Accordion_BJka4Qvb.mjs → _worker.js/chunks/Accordion_BNafbla6.mjs} +0 -0
- /package/dist/{server/chunks/Accordion_BQIphkaZ.mjs → _worker.js/chunks/Accordion_CZsuyu9E.mjs} +0 -0
- /package/dist/{server/chunks/AllComponents_CRhgTsiT.mjs → _worker.js/chunks/AllComponents_BrL9IHSc.mjs} +0 -0
- /package/dist/{server/chunks/AllComponents_CjOtwUH6.mjs → _worker.js/chunks/AllComponents_CI7S6uwA.mjs} +0 -0
- /package/dist/{server/chunks/_astro_data-layer-content_D4Ib_RjR.mjs → _worker.js/chunks/_astro_assets_vBCb4v6U.mjs} +0 -0
- /package/dist/{server/chunks/content-assets_DleWbedO.mjs → _worker.js/chunks/_astro_data-layer-content_CgXoS6Mm.mjs} +0 -0
- /package/dist/{server/chunks/content-modules_fX1c2JRG.mjs → _worker.js/chunks/content-assets_XqCgPAV2.mjs} +0 -0
- /package/dist/{server/pages/_section_/_---page_.astro.mjs → _worker.js/chunks/content-modules_CKq2j9RQ.mjs} +0 -0
- /package/dist/{server/pages/_section_/_page_/_---tab_.astro.mjs → _worker.js/chunks/sharp_CNjr3bU4.mjs} +0 -0
- /package/dist/{server/pages/index.astro.mjs → _worker.js/pages/_section_/_---page_.astro.mjs} +0 -0
- /package/dist/{client/avatarImg.svg → avatarImg.svg} +0 -0
- /package/dist/{client/avatarImgDark.svg → avatarImgDark.svg} +0 -0
- /package/dist/{client/content → content}/typography/line-height.png +0 -0
- /package/dist/{client/favicon.svg → favicon.svg} +0 -0
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import '
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
globalThis.process ??= {}; globalThis.process.env ??= {};
|
|
2
|
+
import { g as getActionQueryString, a as deserializeActionResult, b as distExports, D as DEFAULT_404_ROUTE, A as ActionError, s as serializeActionResult, c as ACTION_RPC_ROUTE_PATTERN, f as ACTION_QUERY_PARAMS, h as stringify$2 } from './astro-designed-error-pages_4xWqsa9_.mjs';
|
|
3
|
+
import { J as decryptString, K as createSlotValueFromString, M as isAstroComponentFactory, r as renderComponent, b as renderTemplate, x as REROUTE_DIRECTIVE_HEADER, A as AstroError, N as i18nNoLocaleFoundInPath, O as ResponseSentError, P as originPathnameSymbol, Q as RewriteWithBodyUsed, S as MiddlewareNoDataOrNextCalled, T as MiddlewareNotAResponse, V as GetStaticPathsRequired, W as InvalidGetStaticPathsReturn, X as InvalidGetStaticPathsEntry, Y as GetStaticPathsExpectedParams, Z as GetStaticPathsInvalidRouteParam, _ as PageNumberParamNotFound, D as DEFAULT_404_COMPONENT, $ as NoMatchingStaticPathFound, a0 as PrerenderDynamicEndpointPathCollide, a1 as ReservedSlotName, a2 as renderSlotToString, q as renderJSX, a3 as chunkToString, a4 as isRenderInstruction, a5 as SessionStorageSaveError, a6 as SessionStorageInitError, w as ROUTE_TYPE_HEADER, a7 as ForbiddenRewrite, a8 as ASTRO_VERSION, a9 as CspNotEnabled, aa as green, ab as LocalsReassigned, ac as PrerenderClientAddressNotAvailable, G as clientAddressSymbol, ad as ClientAddressNotAvailable, ae as StaticClientAddressNotAvailable, af as AstroResponseHeadersReassigned, I as responseSentSymbol$1, ag as renderPage, ah as REWRITE_DIRECTIVE_HEADER_KEY, ai as REWRITE_DIRECTIVE_HEADER_VALUE, aj as renderEndpoint } from './astro/server_BpfPtTmt.mjs';
|
|
4
|
+
import { b as appendForwardSlash, j as joinPaths, a as removeTrailingForwardSlash, p as prependForwardSlash, t as trimSlashes } from './path_C-ZOwaTP.mjs';
|
|
5
|
+
import { u as unflatten$1 } from './parse_EttCPxrw.mjs';
|
|
6
|
+
|
|
7
|
+
const ACTION_API_CONTEXT_SYMBOL = Symbol.for("astro.actionAPIContext");
|
|
8
|
+
const formContentTypes = ["application/x-www-form-urlencoded", "multipart/form-data"];
|
|
9
|
+
function hasContentType(contentType, expected) {
|
|
10
|
+
const type = contentType.split(";")[0].toLowerCase();
|
|
11
|
+
return expected.some((t) => type === t);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function hasActionPayload(locals) {
|
|
15
|
+
return "_actionPayload" in locals;
|
|
16
|
+
}
|
|
17
|
+
function createGetActionResult(locals) {
|
|
18
|
+
return (actionFn) => {
|
|
19
|
+
if (!hasActionPayload(locals) || actionFn.toString() !== getActionQueryString(locals._actionPayload.actionName)) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
return deserializeActionResult(locals._actionPayload.actionResult);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createCallAction(context) {
|
|
26
|
+
return (baseAction, input) => {
|
|
27
|
+
Reflect.set(context, ACTION_API_CONTEXT_SYMBOL, true);
|
|
28
|
+
const action = baseAction.bind(context);
|
|
29
|
+
return action(input);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
22
32
|
|
|
23
33
|
function shouldAppendForwardSlash(trailingSlash, buildFormat) {
|
|
24
34
|
switch (trailingSlash) {
|
|
@@ -211,125 +221,6 @@ function isRouteExternalRedirect(route) {
|
|
|
211
221
|
return !!(route.type === "redirect" && route.redirect && redirectIsExternal(route.redirect));
|
|
212
222
|
}
|
|
213
223
|
|
|
214
|
-
function createI18nMiddleware(i18n, base, trailingSlash, format) {
|
|
215
|
-
if (!i18n) return (_, next) => next();
|
|
216
|
-
const payload = {
|
|
217
|
-
...i18n,
|
|
218
|
-
trailingSlash,
|
|
219
|
-
base,
|
|
220
|
-
format};
|
|
221
|
-
const _redirectToDefaultLocale = redirectToDefaultLocale(payload);
|
|
222
|
-
const _noFoundForNonLocaleRoute = notFound(payload);
|
|
223
|
-
const _requestHasLocale = requestHasLocale(payload.locales);
|
|
224
|
-
const _redirectToFallback = redirectToFallback(payload);
|
|
225
|
-
const prefixAlways = (context, response) => {
|
|
226
|
-
const url = context.url;
|
|
227
|
-
if (url.pathname === base + "/" || url.pathname === base) {
|
|
228
|
-
return _redirectToDefaultLocale(context);
|
|
229
|
-
} else if (!_requestHasLocale(context)) {
|
|
230
|
-
return _noFoundForNonLocaleRoute(context, response);
|
|
231
|
-
}
|
|
232
|
-
return void 0;
|
|
233
|
-
};
|
|
234
|
-
const prefixOtherLocales = (context, response) => {
|
|
235
|
-
let pathnameContainsDefaultLocale = false;
|
|
236
|
-
const url = context.url;
|
|
237
|
-
for (const segment of url.pathname.split("/")) {
|
|
238
|
-
if (normalizeTheLocale(segment) === normalizeTheLocale(i18n.defaultLocale)) {
|
|
239
|
-
pathnameContainsDefaultLocale = true;
|
|
240
|
-
break;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
if (pathnameContainsDefaultLocale) {
|
|
244
|
-
const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, "");
|
|
245
|
-
response.headers.set("Location", newLocation);
|
|
246
|
-
return _noFoundForNonLocaleRoute(context);
|
|
247
|
-
}
|
|
248
|
-
return void 0;
|
|
249
|
-
};
|
|
250
|
-
return async (context, next) => {
|
|
251
|
-
const response = await next();
|
|
252
|
-
const type = response.headers.get(ROUTE_TYPE_HEADER);
|
|
253
|
-
const isReroute = response.headers.get(REROUTE_DIRECTIVE_HEADER);
|
|
254
|
-
if (isReroute === "no" && typeof i18n.fallback === "undefined") {
|
|
255
|
-
return response;
|
|
256
|
-
}
|
|
257
|
-
if (type !== "page" && type !== "fallback") {
|
|
258
|
-
return response;
|
|
259
|
-
}
|
|
260
|
-
if (requestIs404Or500(context.request, base)) {
|
|
261
|
-
return response;
|
|
262
|
-
}
|
|
263
|
-
if (isRequestServerIsland(context.request, base)) {
|
|
264
|
-
return response;
|
|
265
|
-
}
|
|
266
|
-
const { currentLocale } = context;
|
|
267
|
-
switch (i18n.strategy) {
|
|
268
|
-
// NOTE: theoretically, we should never hit this code path
|
|
269
|
-
case "manual": {
|
|
270
|
-
return response;
|
|
271
|
-
}
|
|
272
|
-
case "domains-prefix-other-locales": {
|
|
273
|
-
if (localeHasntDomain(i18n, currentLocale)) {
|
|
274
|
-
const result = prefixOtherLocales(context, response);
|
|
275
|
-
if (result) {
|
|
276
|
-
return result;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
break;
|
|
280
|
-
}
|
|
281
|
-
case "pathname-prefix-other-locales": {
|
|
282
|
-
const result = prefixOtherLocales(context, response);
|
|
283
|
-
if (result) {
|
|
284
|
-
return result;
|
|
285
|
-
}
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
case "domains-prefix-always-no-redirect": {
|
|
289
|
-
if (localeHasntDomain(i18n, currentLocale)) {
|
|
290
|
-
const result = _noFoundForNonLocaleRoute(context, response);
|
|
291
|
-
if (result) {
|
|
292
|
-
return result;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
break;
|
|
296
|
-
}
|
|
297
|
-
case "pathname-prefix-always-no-redirect": {
|
|
298
|
-
const result = _noFoundForNonLocaleRoute(context, response);
|
|
299
|
-
if (result) {
|
|
300
|
-
return result;
|
|
301
|
-
}
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
case "pathname-prefix-always": {
|
|
305
|
-
const result = prefixAlways(context, response);
|
|
306
|
-
if (result) {
|
|
307
|
-
return result;
|
|
308
|
-
}
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
case "domains-prefix-always": {
|
|
312
|
-
if (localeHasntDomain(i18n, currentLocale)) {
|
|
313
|
-
const result = prefixAlways(context, response);
|
|
314
|
-
if (result) {
|
|
315
|
-
return result;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
break;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return _redirectToFallback(context, response);
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
function localeHasntDomain(i18n, currentLocale) {
|
|
325
|
-
for (const domainLocale of Object.values(i18n.domainLookupTable)) {
|
|
326
|
-
if (domainLocale === currentLocale) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
return true;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
224
|
function requestHasLocale(locales) {
|
|
334
225
|
return function(context) {
|
|
335
226
|
return pathHasLocale(context.url.pathname, locales);
|
|
@@ -369,14 +260,16 @@ function getPathByLocale(locale, locales) {
|
|
|
369
260
|
function normalizeTheLocale(locale) {
|
|
370
261
|
return locale.replaceAll("_", "-").toLowerCase();
|
|
371
262
|
}
|
|
372
|
-
function
|
|
373
|
-
|
|
263
|
+
function getAllCodes(locales) {
|
|
264
|
+
const result = [];
|
|
265
|
+
for (const loopLocale of locales) {
|
|
374
266
|
if (typeof loopLocale === "string") {
|
|
375
|
-
|
|
267
|
+
result.push(loopLocale);
|
|
376
268
|
} else {
|
|
377
|
-
|
|
269
|
+
result.push(...loopLocale.codes);
|
|
378
270
|
}
|
|
379
|
-
}
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
380
273
|
}
|
|
381
274
|
function redirectToDefaultLocale({
|
|
382
275
|
trailingSlash,
|
|
@@ -386,7 +279,7 @@ function redirectToDefaultLocale({
|
|
|
386
279
|
}) {
|
|
387
280
|
return function(context, statusCode) {
|
|
388
281
|
if (shouldAppendForwardSlash(trailingSlash, format)) {
|
|
389
|
-
return context.redirect(`${appendForwardSlash
|
|
282
|
+
return context.redirect(`${appendForwardSlash(joinPaths(base, defaultLocale))}`, statusCode);
|
|
390
283
|
} else {
|
|
391
284
|
return context.redirect(`${joinPaths(base, defaultLocale)}`, statusCode);
|
|
392
285
|
}
|
|
@@ -466,9 +359,146 @@ function redirectToFallback({
|
|
|
466
359
|
};
|
|
467
360
|
}
|
|
468
361
|
|
|
362
|
+
function parseLocale(header) {
|
|
363
|
+
if (header === "*") {
|
|
364
|
+
return [{ locale: header, qualityValue: void 0 }];
|
|
365
|
+
}
|
|
366
|
+
const result = [];
|
|
367
|
+
const localeValues = header.split(",").map((str) => str.trim());
|
|
368
|
+
for (const localeValue of localeValues) {
|
|
369
|
+
const split = localeValue.split(";").map((str) => str.trim());
|
|
370
|
+
const localeName = split[0];
|
|
371
|
+
const qualityValue = split[1];
|
|
372
|
+
if (!split) {
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (qualityValue && qualityValue.startsWith("q=")) {
|
|
376
|
+
const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length));
|
|
377
|
+
if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) {
|
|
378
|
+
result.push({
|
|
379
|
+
locale: localeName,
|
|
380
|
+
qualityValue: void 0
|
|
381
|
+
});
|
|
382
|
+
} else {
|
|
383
|
+
result.push({
|
|
384
|
+
locale: localeName,
|
|
385
|
+
qualityValue: qualityValueAsFloat
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
result.push({
|
|
390
|
+
locale: localeName,
|
|
391
|
+
qualityValue: void 0
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return result;
|
|
396
|
+
}
|
|
397
|
+
function sortAndFilterLocales(browserLocaleList, locales) {
|
|
398
|
+
const normalizedLocales = getAllCodes(locales).map(normalizeTheLocale);
|
|
399
|
+
return browserLocaleList.filter((browserLocale) => {
|
|
400
|
+
if (browserLocale.locale !== "*") {
|
|
401
|
+
return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale));
|
|
402
|
+
}
|
|
403
|
+
return true;
|
|
404
|
+
}).sort((a, b) => {
|
|
405
|
+
if (a.qualityValue && b.qualityValue) {
|
|
406
|
+
return Math.sign(b.qualityValue - a.qualityValue);
|
|
407
|
+
}
|
|
408
|
+
return 0;
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
function computePreferredLocale(request, locales) {
|
|
412
|
+
const acceptHeader = request.headers.get("Accept-Language");
|
|
413
|
+
let result = void 0;
|
|
414
|
+
if (acceptHeader) {
|
|
415
|
+
const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales);
|
|
416
|
+
const firstResult = browserLocaleList.at(0);
|
|
417
|
+
if (firstResult && firstResult.locale !== "*") {
|
|
418
|
+
for (const currentLocale of locales) {
|
|
419
|
+
if (typeof currentLocale === "string") {
|
|
420
|
+
if (normalizeTheLocale(currentLocale) === normalizeTheLocale(firstResult.locale)) {
|
|
421
|
+
result = currentLocale;
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
} else {
|
|
425
|
+
for (const currentCode of currentLocale.codes) {
|
|
426
|
+
if (normalizeTheLocale(currentCode) === normalizeTheLocale(firstResult.locale)) {
|
|
427
|
+
result = currentCode;
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return result;
|
|
436
|
+
}
|
|
437
|
+
function computePreferredLocaleList(request, locales) {
|
|
438
|
+
const acceptHeader = request.headers.get("Accept-Language");
|
|
439
|
+
let result = [];
|
|
440
|
+
if (acceptHeader) {
|
|
441
|
+
const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales);
|
|
442
|
+
if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") {
|
|
443
|
+
return getAllCodes(locales);
|
|
444
|
+
} else if (browserLocaleList.length > 0) {
|
|
445
|
+
for (const browserLocale of browserLocaleList) {
|
|
446
|
+
for (const loopLocale of locales) {
|
|
447
|
+
if (typeof loopLocale === "string") {
|
|
448
|
+
if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) {
|
|
449
|
+
result.push(loopLocale);
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
for (const code of loopLocale.codes) {
|
|
453
|
+
if (code === browserLocale.locale) {
|
|
454
|
+
result.push(code);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return result;
|
|
463
|
+
}
|
|
464
|
+
function computeCurrentLocale(pathname, locales, defaultLocale) {
|
|
465
|
+
for (const segment of pathname.split("/")) {
|
|
466
|
+
for (const locale of locales) {
|
|
467
|
+
if (typeof locale === "string") {
|
|
468
|
+
if (!segment.includes(locale)) continue;
|
|
469
|
+
if (normalizeTheLocale(locale) === normalizeTheLocale(segment)) {
|
|
470
|
+
return locale;
|
|
471
|
+
}
|
|
472
|
+
} else {
|
|
473
|
+
if (locale.path === segment) {
|
|
474
|
+
return locale.codes.at(0);
|
|
475
|
+
} else {
|
|
476
|
+
for (const code of locale.codes) {
|
|
477
|
+
if (normalizeTheLocale(code) === normalizeTheLocale(segment)) {
|
|
478
|
+
return code;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
for (const locale of locales) {
|
|
486
|
+
if (typeof locale === "string") {
|
|
487
|
+
if (locale === defaultLocale) {
|
|
488
|
+
return locale;
|
|
489
|
+
}
|
|
490
|
+
} else {
|
|
491
|
+
if (locale.path === defaultLocale) {
|
|
492
|
+
return locale.codes.at(0);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
469
498
|
const DELETED_EXPIRATION = /* @__PURE__ */ new Date(0);
|
|
470
499
|
const DELETED_VALUE = "deleted";
|
|
471
500
|
const responseSentSymbol = Symbol.for("astro.responseSent");
|
|
501
|
+
const identity = (value) => value;
|
|
472
502
|
class AstroCookie {
|
|
473
503
|
constructor(value) {
|
|
474
504
|
this.value = value;
|
|
@@ -519,7 +549,7 @@ class AstroCookies {
|
|
|
519
549
|
};
|
|
520
550
|
this.#ensureOutgoingMap().set(key, [
|
|
521
551
|
DELETED_VALUE,
|
|
522
|
-
serialize(key, DELETED_VALUE, serializeOptions),
|
|
552
|
+
distExports.serialize(key, DELETED_VALUE, serializeOptions),
|
|
523
553
|
false
|
|
524
554
|
]);
|
|
525
555
|
}
|
|
@@ -539,25 +569,29 @@ class AstroCookies {
|
|
|
539
569
|
return void 0;
|
|
540
570
|
}
|
|
541
571
|
}
|
|
542
|
-
const
|
|
572
|
+
const decode = options?.decode ?? decodeURIComponent;
|
|
573
|
+
const values = this.#ensureParsed();
|
|
543
574
|
if (key in values) {
|
|
544
575
|
const value = values[key];
|
|
545
|
-
|
|
576
|
+
if (value) {
|
|
577
|
+
return new AstroCookie(decode(value));
|
|
578
|
+
}
|
|
546
579
|
}
|
|
547
580
|
}
|
|
548
581
|
/**
|
|
549
582
|
* Astro.cookies.has(key) returns a boolean indicating whether this cookie is either
|
|
550
583
|
* part of the initial request or set via Astro.cookies.set(key)
|
|
551
584
|
* @param key The cookie to check for.
|
|
585
|
+
* @param _options This parameter is no longer used.
|
|
552
586
|
* @returns
|
|
553
587
|
*/
|
|
554
|
-
has(key,
|
|
588
|
+
has(key, _options) {
|
|
555
589
|
if (this.#outgoing?.has(key)) {
|
|
556
590
|
let [, , isSetValue] = this.#outgoing.get(key);
|
|
557
591
|
return isSetValue;
|
|
558
592
|
}
|
|
559
|
-
const values = this.#ensureParsed(
|
|
560
|
-
return
|
|
593
|
+
const values = this.#ensureParsed();
|
|
594
|
+
return values[key] !== void 0;
|
|
561
595
|
}
|
|
562
596
|
/**
|
|
563
597
|
* Astro.cookies.set(key, value) is used to set a cookie's value. If provided
|
|
@@ -593,7 +627,7 @@ class AstroCookies {
|
|
|
593
627
|
}
|
|
594
628
|
this.#ensureOutgoingMap().set(key, [
|
|
595
629
|
serializedValue,
|
|
596
|
-
serialize(key, serializedValue, serializeOptions),
|
|
630
|
+
distExports.serialize(key, serializedValue, serializeOptions),
|
|
597
631
|
true
|
|
598
632
|
]);
|
|
599
633
|
if (this.#request[responseSentSymbol]) {
|
|
@@ -634,9 +668,9 @@ class AstroCookies {
|
|
|
634
668
|
cookies.#consumed = true;
|
|
635
669
|
return cookies.headers();
|
|
636
670
|
}
|
|
637
|
-
#ensureParsed(
|
|
671
|
+
#ensureParsed() {
|
|
638
672
|
if (!this.#requestValues) {
|
|
639
|
-
this.#parse(
|
|
673
|
+
this.#parse();
|
|
640
674
|
}
|
|
641
675
|
if (!this.#requestValues) {
|
|
642
676
|
this.#requestValues = {};
|
|
@@ -649,12 +683,12 @@ class AstroCookies {
|
|
|
649
683
|
}
|
|
650
684
|
return this.#outgoing;
|
|
651
685
|
}
|
|
652
|
-
#parse(
|
|
686
|
+
#parse() {
|
|
653
687
|
const raw = this.#request.headers.get("cookie");
|
|
654
688
|
if (!raw) {
|
|
655
689
|
return;
|
|
656
690
|
}
|
|
657
|
-
this.#requestValues = parse(raw,
|
|
691
|
+
this.#requestValues = distExports.parse(raw, { decode: identity });
|
|
658
692
|
}
|
|
659
693
|
}
|
|
660
694
|
|
|
@@ -681,298 +715,238 @@ function* getSetCookiesFromResponse(response) {
|
|
|
681
715
|
return [];
|
|
682
716
|
}
|
|
683
717
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
newLine
|
|
705
|
-
};
|
|
706
|
-
if (!isLogLevelEnabled(logLevel, level)) {
|
|
707
|
-
return;
|
|
718
|
+
function createRequest({
|
|
719
|
+
url,
|
|
720
|
+
headers,
|
|
721
|
+
method = "GET",
|
|
722
|
+
body = void 0,
|
|
723
|
+
logger,
|
|
724
|
+
isPrerendered = false,
|
|
725
|
+
routePattern,
|
|
726
|
+
init
|
|
727
|
+
}) {
|
|
728
|
+
const headersObj = isPrerendered ? void 0 : headers instanceof Headers ? headers : new Headers(
|
|
729
|
+
// Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request.
|
|
730
|
+
// Examples include `:method`, `:scheme`, `:authority`, and `:path`.
|
|
731
|
+
// They are always prefixed with a colon to distinguish them from other headers, and it is an error to add the to a Headers object manually.
|
|
732
|
+
// See https://httpwg.org/specs/rfc7540.html#HttpRequest
|
|
733
|
+
Object.entries(headers).filter(([name]) => !name.startsWith(":"))
|
|
734
|
+
);
|
|
735
|
+
if (typeof url === "string") url = new URL(url);
|
|
736
|
+
if (isPrerendered) {
|
|
737
|
+
url.search = "";
|
|
708
738
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
739
|
+
const request = new Request(url, {
|
|
740
|
+
method,
|
|
741
|
+
headers: headersObj,
|
|
742
|
+
// body is made available only if the request is for a page that will be on-demand rendered
|
|
743
|
+
body: isPrerendered ? null : body,
|
|
744
|
+
...init
|
|
745
|
+
});
|
|
746
|
+
if (isPrerendered) {
|
|
747
|
+
let _headers = request.headers;
|
|
748
|
+
const { value, writable, ...headersDesc } = Object.getOwnPropertyDescriptor(request, "headers") || {};
|
|
749
|
+
Object.defineProperty(request, "headers", {
|
|
750
|
+
...headersDesc,
|
|
751
|
+
get() {
|
|
752
|
+
logger.warn(
|
|
753
|
+
null,
|
|
754
|
+
`\`Astro.request.headers\` was used when rendering the route \`${routePattern}'\`. \`Astro.request.headers\` is not available on prerendered pages. If you need access to request headers, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default.`
|
|
755
|
+
);
|
|
756
|
+
return _headers;
|
|
757
|
+
},
|
|
758
|
+
set(newHeaders) {
|
|
759
|
+
_headers = newHeaders;
|
|
760
|
+
}
|
|
761
|
+
});
|
|
726
762
|
}
|
|
763
|
+
return request;
|
|
727
764
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
}
|
|
746
|
-
if (prefix.length === 1) {
|
|
747
|
-
return dim(prefix[0]);
|
|
748
|
-
}
|
|
749
|
-
return dim(prefix[0]) + " " + blue(prefix.splice(1).join(" "));
|
|
750
|
-
}
|
|
751
|
-
class Logger {
|
|
752
|
-
options;
|
|
753
|
-
constructor(options) {
|
|
754
|
-
this.options = options;
|
|
755
|
-
}
|
|
756
|
-
info(label, message, newLine = true) {
|
|
757
|
-
info(this.options, label, message, newLine);
|
|
758
|
-
}
|
|
759
|
-
warn(label, message, newLine = true) {
|
|
760
|
-
warn(this.options, label, message, newLine);
|
|
761
|
-
}
|
|
762
|
-
error(label, message, newLine = true) {
|
|
763
|
-
error(this.options, label, message, newLine);
|
|
764
|
-
}
|
|
765
|
-
debug(label, ...messages) {
|
|
766
|
-
debug(label, ...messages);
|
|
767
|
-
}
|
|
768
|
-
level() {
|
|
769
|
-
return this.options.level;
|
|
770
|
-
}
|
|
771
|
-
forkIntegrationLogger(label) {
|
|
772
|
-
return new AstroIntegrationLogger(this.options, label);
|
|
765
|
+
|
|
766
|
+
function findRouteToRewrite({
|
|
767
|
+
payload,
|
|
768
|
+
routes,
|
|
769
|
+
request,
|
|
770
|
+
trailingSlash,
|
|
771
|
+
buildFormat,
|
|
772
|
+
base,
|
|
773
|
+
outDir
|
|
774
|
+
}) {
|
|
775
|
+
let newUrl = void 0;
|
|
776
|
+
if (payload instanceof URL) {
|
|
777
|
+
newUrl = payload;
|
|
778
|
+
} else if (payload instanceof Request) {
|
|
779
|
+
newUrl = new URL(payload.url);
|
|
780
|
+
} else {
|
|
781
|
+
newUrl = new URL(payload, new URL(request.url).origin);
|
|
773
782
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
783
|
+
let pathname = newUrl.pathname;
|
|
784
|
+
const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat);
|
|
785
|
+
if (base !== "/") {
|
|
786
|
+
const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base);
|
|
787
|
+
if (isBasePathRequest) {
|
|
788
|
+
pathname = shouldAppendSlash ? "/" : "";
|
|
789
|
+
} else if (newUrl.pathname.startsWith(base)) {
|
|
790
|
+
pathname = shouldAppendSlash ? appendForwardSlash(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname);
|
|
791
|
+
pathname = pathname.slice(base.length);
|
|
792
|
+
}
|
|
781
793
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
*/
|
|
785
|
-
fork(label) {
|
|
786
|
-
return new AstroIntegrationLogger(this.options, label);
|
|
794
|
+
if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) {
|
|
795
|
+
pathname = prependForwardSlash(pathname);
|
|
787
796
|
}
|
|
788
|
-
|
|
789
|
-
|
|
797
|
+
if (pathname === "/" && base !== "/" && !shouldAppendSlash) {
|
|
798
|
+
pathname = "";
|
|
790
799
|
}
|
|
791
|
-
|
|
792
|
-
|
|
800
|
+
if (buildFormat === "file") {
|
|
801
|
+
pathname = pathname.replace(/\.html$/, "");
|
|
793
802
|
}
|
|
794
|
-
|
|
795
|
-
|
|
803
|
+
if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) {
|
|
804
|
+
newUrl.pathname = removeTrailingForwardSlash(base);
|
|
805
|
+
} else {
|
|
806
|
+
newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean));
|
|
796
807
|
}
|
|
797
|
-
|
|
798
|
-
|
|
808
|
+
const decodedPathname = decodeURI(pathname);
|
|
809
|
+
let foundRoute;
|
|
810
|
+
for (const route of routes) {
|
|
811
|
+
if (route.pattern.test(decodedPathname)) {
|
|
812
|
+
if (route.params && route.params.length !== 0 && route.distURL && route.distURL.length !== 0) {
|
|
813
|
+
if (!route.distURL.find(
|
|
814
|
+
(url) => url.href.replace(outDir.toString(), "").replace(/(?:\/index\.html|\.html)$/, "") == trimSlashes(decodedPathname)
|
|
815
|
+
)) {
|
|
816
|
+
continue;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
foundRoute = route;
|
|
820
|
+
break;
|
|
821
|
+
}
|
|
799
822
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
if (
|
|
809
|
-
|
|
823
|
+
if (foundRoute) {
|
|
824
|
+
return {
|
|
825
|
+
routeData: foundRoute,
|
|
826
|
+
newUrl,
|
|
827
|
+
pathname: decodedPathname
|
|
828
|
+
};
|
|
829
|
+
} else {
|
|
830
|
+
const custom404 = routes.find((route) => route.route === "/404");
|
|
831
|
+
if (custom404) {
|
|
832
|
+
return { routeData: custom404, newUrl, pathname };
|
|
810
833
|
} else {
|
|
811
|
-
|
|
834
|
+
return { routeData: DEFAULT_404_ROUTE, newUrl, pathname };
|
|
812
835
|
}
|
|
813
|
-
return true;
|
|
814
836
|
}
|
|
815
|
-
};
|
|
816
|
-
|
|
817
|
-
const ACTION_API_CONTEXT_SYMBOL = Symbol.for("astro.actionAPIContext");
|
|
818
|
-
|
|
819
|
-
function hasActionPayload(locals) {
|
|
820
|
-
return "_actionPayload" in locals;
|
|
821
837
|
}
|
|
822
|
-
function
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
838
|
+
function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) {
|
|
839
|
+
if (oldRequest.bodyUsed) {
|
|
840
|
+
throw new AstroError(RewriteWithBodyUsed);
|
|
841
|
+
}
|
|
842
|
+
return createRequest({
|
|
843
|
+
url: newUrl,
|
|
844
|
+
method: oldRequest.method,
|
|
845
|
+
body: oldRequest.body,
|
|
846
|
+
isPrerendered,
|
|
847
|
+
logger,
|
|
848
|
+
headers: isPrerendered ? {} : oldRequest.headers,
|
|
849
|
+
routePattern,
|
|
850
|
+
init: {
|
|
851
|
+
referrer: oldRequest.referrer,
|
|
852
|
+
referrerPolicy: oldRequest.referrerPolicy,
|
|
853
|
+
mode: oldRequest.mode,
|
|
854
|
+
credentials: oldRequest.credentials,
|
|
855
|
+
cache: oldRequest.cache,
|
|
856
|
+
redirect: oldRequest.redirect,
|
|
857
|
+
integrity: oldRequest.integrity,
|
|
858
|
+
signal: oldRequest.signal,
|
|
859
|
+
keepalive: oldRequest.keepalive,
|
|
860
|
+
// https://fetch.spec.whatwg.org/#dom-request-duplex
|
|
861
|
+
// @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
|
|
862
|
+
duplex: "half"
|
|
826
863
|
}
|
|
827
|
-
|
|
828
|
-
};
|
|
864
|
+
});
|
|
829
865
|
}
|
|
830
|
-
function
|
|
831
|
-
|
|
832
|
-
Reflect.set(context, ACTION_API_CONTEXT_SYMBOL, true);
|
|
833
|
-
const action = baseAction.bind(context);
|
|
834
|
-
return action(input);
|
|
835
|
-
};
|
|
866
|
+
function setOriginPathname(request, pathname) {
|
|
867
|
+
Reflect.set(request, originPathnameSymbol, encodeURIComponent(pathname));
|
|
836
868
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
if (
|
|
840
|
-
return
|
|
841
|
-
}
|
|
842
|
-
const result = [];
|
|
843
|
-
const localeValues = header.split(",").map((str) => str.trim());
|
|
844
|
-
for (const localeValue of localeValues) {
|
|
845
|
-
const split = localeValue.split(";").map((str) => str.trim());
|
|
846
|
-
const localeName = split[0];
|
|
847
|
-
const qualityValue = split[1];
|
|
848
|
-
if (!split) {
|
|
849
|
-
continue;
|
|
850
|
-
}
|
|
851
|
-
if (qualityValue && qualityValue.startsWith("q=")) {
|
|
852
|
-
const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length));
|
|
853
|
-
if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) {
|
|
854
|
-
result.push({
|
|
855
|
-
locale: localeName,
|
|
856
|
-
qualityValue: void 0
|
|
857
|
-
});
|
|
858
|
-
} else {
|
|
859
|
-
result.push({
|
|
860
|
-
locale: localeName,
|
|
861
|
-
qualityValue: qualityValueAsFloat
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
} else {
|
|
865
|
-
result.push({
|
|
866
|
-
locale: localeName,
|
|
867
|
-
qualityValue: void 0
|
|
868
|
-
});
|
|
869
|
-
}
|
|
869
|
+
function getOriginPathname(request) {
|
|
870
|
+
const origin = Reflect.get(request, originPathnameSymbol);
|
|
871
|
+
if (origin) {
|
|
872
|
+
return decodeURIComponent(origin);
|
|
870
873
|
}
|
|
871
|
-
return
|
|
872
|
-
}
|
|
873
|
-
function sortAndFilterLocales(browserLocaleList, locales) {
|
|
874
|
-
const normalizedLocales = toCodes(locales).map(normalizeTheLocale);
|
|
875
|
-
return browserLocaleList.filter((browserLocale) => {
|
|
876
|
-
if (browserLocale.locale !== "*") {
|
|
877
|
-
return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale));
|
|
878
|
-
}
|
|
879
|
-
return true;
|
|
880
|
-
}).sort((a, b) => {
|
|
881
|
-
if (a.qualityValue && b.qualityValue) {
|
|
882
|
-
return Math.sign(b.qualityValue - a.qualityValue);
|
|
883
|
-
}
|
|
884
|
-
return 0;
|
|
885
|
-
});
|
|
874
|
+
return new URL(request.url).pathname;
|
|
886
875
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
876
|
+
|
|
877
|
+
function getActionContext(context) {
|
|
878
|
+
const callerInfo = getCallerInfo(context);
|
|
879
|
+
const actionResultAlreadySet = Boolean(context.locals._actionPayload);
|
|
880
|
+
let action = void 0;
|
|
881
|
+
if (callerInfo && context.request.method === "POST" && !actionResultAlreadySet) {
|
|
882
|
+
action = {
|
|
883
|
+
calledFrom: callerInfo.from,
|
|
884
|
+
name: callerInfo.name,
|
|
885
|
+
handler: async () => {
|
|
886
|
+
const pipeline = Reflect.get(context, apiContextRoutesSymbol);
|
|
887
|
+
const callerInfoName = shouldAppendForwardSlash(
|
|
888
|
+
pipeline.manifest.trailingSlash,
|
|
889
|
+
pipeline.manifest.buildFormat
|
|
890
|
+
) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name;
|
|
891
|
+
const baseAction = await pipeline.getAction(callerInfoName);
|
|
892
|
+
let input;
|
|
893
|
+
try {
|
|
894
|
+
input = await parseRequestBody(context.request);
|
|
895
|
+
} catch (e) {
|
|
896
|
+
if (e instanceof TypeError) {
|
|
897
|
+
return { data: void 0, error: new ActionError({ code: "UNSUPPORTED_MEDIA_TYPE" }) };
|
|
904
898
|
}
|
|
899
|
+
throw e;
|
|
905
900
|
}
|
|
901
|
+
const omitKeys = ["props", "getActionResult", "callAction", "redirect"];
|
|
902
|
+
const actionAPIContext = Object.create(
|
|
903
|
+
Object.getPrototypeOf(context),
|
|
904
|
+
Object.fromEntries(
|
|
905
|
+
Object.entries(Object.getOwnPropertyDescriptors(context)).filter(
|
|
906
|
+
([key]) => !omitKeys.includes(key)
|
|
907
|
+
)
|
|
908
|
+
)
|
|
909
|
+
);
|
|
910
|
+
Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true);
|
|
911
|
+
const handler = baseAction.bind(actionAPIContext);
|
|
912
|
+
return handler(input);
|
|
906
913
|
}
|
|
907
|
-
}
|
|
914
|
+
};
|
|
908
915
|
}
|
|
909
|
-
|
|
916
|
+
function setActionResult(actionName, actionResult) {
|
|
917
|
+
context.locals._actionPayload = {
|
|
918
|
+
actionResult,
|
|
919
|
+
actionName
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
return {
|
|
923
|
+
action,
|
|
924
|
+
setActionResult,
|
|
925
|
+
serializeActionResult,
|
|
926
|
+
deserializeActionResult
|
|
927
|
+
};
|
|
910
928
|
}
|
|
911
|
-
function
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
if (acceptHeader) {
|
|
915
|
-
const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales);
|
|
916
|
-
if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") {
|
|
917
|
-
return locales.map((locale) => {
|
|
918
|
-
if (typeof locale === "string") {
|
|
919
|
-
return locale;
|
|
920
|
-
} else {
|
|
921
|
-
return locale.codes.at(0);
|
|
922
|
-
}
|
|
923
|
-
});
|
|
924
|
-
} else if (browserLocaleList.length > 0) {
|
|
925
|
-
for (const browserLocale of browserLocaleList) {
|
|
926
|
-
for (const loopLocale of locales) {
|
|
927
|
-
if (typeof loopLocale === "string") {
|
|
928
|
-
if (normalizeTheLocale(loopLocale) === normalizeTheLocale(browserLocale.locale)) {
|
|
929
|
-
result.push(loopLocale);
|
|
930
|
-
}
|
|
931
|
-
} else {
|
|
932
|
-
for (const code of loopLocale.codes) {
|
|
933
|
-
if (code === browserLocale.locale) {
|
|
934
|
-
result.push(loopLocale.path);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
}
|
|
929
|
+
function getCallerInfo(ctx) {
|
|
930
|
+
if (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) {
|
|
931
|
+
return { from: "rpc", name: ctx.url.pathname.replace(/^.*\/_actions\//, "") };
|
|
941
932
|
}
|
|
942
|
-
|
|
933
|
+
const queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName);
|
|
934
|
+
if (queryParam) {
|
|
935
|
+
return { from: "form", name: queryParam };
|
|
936
|
+
}
|
|
937
|
+
return void 0;
|
|
943
938
|
}
|
|
944
|
-
function
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
return locale;
|
|
951
|
-
}
|
|
952
|
-
} else {
|
|
953
|
-
if (locale.path === segment) {
|
|
954
|
-
return locale.codes.at(0);
|
|
955
|
-
} else {
|
|
956
|
-
for (const code of locale.codes) {
|
|
957
|
-
if (normalizeTheLocale(code) === normalizeTheLocale(segment)) {
|
|
958
|
-
return code;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
939
|
+
async function parseRequestBody(request) {
|
|
940
|
+
const contentType = request.headers.get("content-type");
|
|
941
|
+
const contentLength = request.headers.get("Content-Length");
|
|
942
|
+
if (!contentType) return void 0;
|
|
943
|
+
if (hasContentType(contentType, formContentTypes)) {
|
|
944
|
+
return await request.clone().formData();
|
|
964
945
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
if (locale === defaultLocale) {
|
|
968
|
-
return locale;
|
|
969
|
-
}
|
|
970
|
-
} else {
|
|
971
|
-
if (locale.path === defaultLocale) {
|
|
972
|
-
return locale.codes.at(0);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
946
|
+
if (hasContentType(contentType, ["application/json"])) {
|
|
947
|
+
return contentLength === "0" ? void 0 : await request.clone().json();
|
|
975
948
|
}
|
|
949
|
+
throw new TypeError("Unsupported content type");
|
|
976
950
|
}
|
|
977
951
|
|
|
978
952
|
async function callMiddleware(onRequest, apiContext, responseFunction) {
|
|
@@ -1008,190 +982,6 @@ async function callMiddleware(onRequest, apiContext, responseFunction) {
|
|
|
1008
982
|
});
|
|
1009
983
|
}
|
|
1010
984
|
|
|
1011
|
-
function createRequest({
|
|
1012
|
-
url,
|
|
1013
|
-
headers,
|
|
1014
|
-
method = "GET",
|
|
1015
|
-
body = void 0,
|
|
1016
|
-
logger,
|
|
1017
|
-
isPrerendered = false,
|
|
1018
|
-
routePattern,
|
|
1019
|
-
init
|
|
1020
|
-
}) {
|
|
1021
|
-
const headersObj = isPrerendered ? void 0 : headers instanceof Headers ? headers : new Headers(
|
|
1022
|
-
// Filter out HTTP/2 pseudo-headers. These are internally-generated headers added to all HTTP/2 requests with trusted metadata about the request.
|
|
1023
|
-
// Examples include `:method`, `:scheme`, `:authority`, and `:path`.
|
|
1024
|
-
// They are always prefixed with a colon to distinguish them from other headers, and it is an error to add the to a Headers object manually.
|
|
1025
|
-
// See https://httpwg.org/specs/rfc7540.html#HttpRequest
|
|
1026
|
-
Object.entries(headers).filter(([name]) => !name.startsWith(":"))
|
|
1027
|
-
);
|
|
1028
|
-
if (typeof url === "string") url = new URL(url);
|
|
1029
|
-
if (isPrerendered) {
|
|
1030
|
-
url.search = "";
|
|
1031
|
-
}
|
|
1032
|
-
const request = new Request(url, {
|
|
1033
|
-
method,
|
|
1034
|
-
headers: headersObj,
|
|
1035
|
-
// body is made available only if the request is for a page that will be on-demand rendered
|
|
1036
|
-
body: isPrerendered ? null : body,
|
|
1037
|
-
...init
|
|
1038
|
-
});
|
|
1039
|
-
if (isPrerendered) {
|
|
1040
|
-
let _headers = request.headers;
|
|
1041
|
-
const { value, writable, ...headersDesc } = Object.getOwnPropertyDescriptor(request, "headers") || {};
|
|
1042
|
-
Object.defineProperty(request, "headers", {
|
|
1043
|
-
...headersDesc,
|
|
1044
|
-
get() {
|
|
1045
|
-
logger.warn(
|
|
1046
|
-
null,
|
|
1047
|
-
`\`Astro.request.headers\` was used when rendering the route \`${routePattern}'\`. \`Astro.request.headers\` is not available on prerendered pages. If you need access to request headers, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default.`
|
|
1048
|
-
);
|
|
1049
|
-
return _headers;
|
|
1050
|
-
},
|
|
1051
|
-
set(newHeaders) {
|
|
1052
|
-
_headers = newHeaders;
|
|
1053
|
-
}
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
return request;
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
function findRouteToRewrite({
|
|
1060
|
-
payload,
|
|
1061
|
-
routes,
|
|
1062
|
-
request,
|
|
1063
|
-
trailingSlash,
|
|
1064
|
-
buildFormat,
|
|
1065
|
-
base
|
|
1066
|
-
}) {
|
|
1067
|
-
let newUrl = void 0;
|
|
1068
|
-
if (payload instanceof URL) {
|
|
1069
|
-
newUrl = payload;
|
|
1070
|
-
} else if (payload instanceof Request) {
|
|
1071
|
-
newUrl = new URL(payload.url);
|
|
1072
|
-
} else {
|
|
1073
|
-
newUrl = new URL(payload, new URL(request.url).origin);
|
|
1074
|
-
}
|
|
1075
|
-
let pathname = newUrl.pathname;
|
|
1076
|
-
const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat);
|
|
1077
|
-
if (base !== "/" && newUrl.pathname.startsWith(base)) {
|
|
1078
|
-
pathname = shouldAppendSlash ? appendForwardSlash$1(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname);
|
|
1079
|
-
pathname = pathname.slice(base.length);
|
|
1080
|
-
}
|
|
1081
|
-
if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) {
|
|
1082
|
-
pathname = prependForwardSlash$1(pathname);
|
|
1083
|
-
}
|
|
1084
|
-
if (pathname === "/" && base !== "/" && !shouldAppendSlash) {
|
|
1085
|
-
pathname = "";
|
|
1086
|
-
}
|
|
1087
|
-
newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean));
|
|
1088
|
-
const decodedPathname = decodeURI(pathname);
|
|
1089
|
-
let foundRoute;
|
|
1090
|
-
for (const route of routes) {
|
|
1091
|
-
if (route.pattern.test(decodedPathname)) {
|
|
1092
|
-
foundRoute = route;
|
|
1093
|
-
break;
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
if (foundRoute) {
|
|
1097
|
-
return {
|
|
1098
|
-
routeData: foundRoute,
|
|
1099
|
-
newUrl,
|
|
1100
|
-
pathname: decodedPathname
|
|
1101
|
-
};
|
|
1102
|
-
} else {
|
|
1103
|
-
const custom404 = routes.find((route) => route.route === "/404");
|
|
1104
|
-
if (custom404) {
|
|
1105
|
-
return { routeData: custom404, newUrl, pathname };
|
|
1106
|
-
} else {
|
|
1107
|
-
return { routeData: DEFAULT_404_ROUTE, newUrl, pathname };
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) {
|
|
1112
|
-
if (oldRequest.bodyUsed) {
|
|
1113
|
-
throw new AstroError(RewriteWithBodyUsed);
|
|
1114
|
-
}
|
|
1115
|
-
return createRequest({
|
|
1116
|
-
url: newUrl,
|
|
1117
|
-
method: oldRequest.method,
|
|
1118
|
-
body: oldRequest.body,
|
|
1119
|
-
isPrerendered,
|
|
1120
|
-
logger,
|
|
1121
|
-
headers: isPrerendered ? {} : oldRequest.headers,
|
|
1122
|
-
routePattern,
|
|
1123
|
-
init: {
|
|
1124
|
-
referrer: oldRequest.referrer,
|
|
1125
|
-
referrerPolicy: oldRequest.referrerPolicy,
|
|
1126
|
-
mode: oldRequest.mode,
|
|
1127
|
-
credentials: oldRequest.credentials,
|
|
1128
|
-
cache: oldRequest.cache,
|
|
1129
|
-
redirect: oldRequest.redirect,
|
|
1130
|
-
integrity: oldRequest.integrity,
|
|
1131
|
-
signal: oldRequest.signal,
|
|
1132
|
-
keepalive: oldRequest.keepalive,
|
|
1133
|
-
// https://fetch.spec.whatwg.org/#dom-request-duplex
|
|
1134
|
-
// @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
|
|
1135
|
-
duplex: "half"
|
|
1136
|
-
}
|
|
1137
|
-
});
|
|
1138
|
-
}
|
|
1139
|
-
function setOriginPathname(request, pathname) {
|
|
1140
|
-
Reflect.set(request, originPathnameSymbol, encodeURIComponent(pathname));
|
|
1141
|
-
}
|
|
1142
|
-
function getOriginPathname(request) {
|
|
1143
|
-
const origin = Reflect.get(request, originPathnameSymbol);
|
|
1144
|
-
if (origin) {
|
|
1145
|
-
return decodeURIComponent(origin);
|
|
1146
|
-
}
|
|
1147
|
-
return new URL(request.url).pathname;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
const FORM_CONTENT_TYPES = [
|
|
1151
|
-
"application/x-www-form-urlencoded",
|
|
1152
|
-
"multipart/form-data",
|
|
1153
|
-
"text/plain"
|
|
1154
|
-
];
|
|
1155
|
-
const SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
|
|
1156
|
-
function createOriginCheckMiddleware() {
|
|
1157
|
-
return defineMiddleware((context, next) => {
|
|
1158
|
-
const { request, url, isPrerendered } = context;
|
|
1159
|
-
if (isPrerendered) {
|
|
1160
|
-
return next();
|
|
1161
|
-
}
|
|
1162
|
-
if (SAFE_METHODS.includes(request.method)) {
|
|
1163
|
-
return next();
|
|
1164
|
-
}
|
|
1165
|
-
const isSameOrigin = request.headers.get("origin") === url.origin;
|
|
1166
|
-
const hasContentType = request.headers.has("content-type");
|
|
1167
|
-
if (hasContentType) {
|
|
1168
|
-
const formLikeHeader = hasFormLikeHeader(request.headers.get("content-type"));
|
|
1169
|
-
if (formLikeHeader && !isSameOrigin) {
|
|
1170
|
-
return new Response(`Cross-site ${request.method} form submissions are forbidden`, {
|
|
1171
|
-
status: 403
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1174
|
-
} else {
|
|
1175
|
-
if (!isSameOrigin) {
|
|
1176
|
-
return new Response(`Cross-site ${request.method} form submissions are forbidden`, {
|
|
1177
|
-
status: 403
|
|
1178
|
-
});
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
return next();
|
|
1182
|
-
});
|
|
1183
|
-
}
|
|
1184
|
-
function hasFormLikeHeader(contentType) {
|
|
1185
|
-
if (contentType) {
|
|
1186
|
-
for (const FORM_CONTENT_TYPE of FORM_CONTENT_TYPES) {
|
|
1187
|
-
if (contentType.toLowerCase().includes(FORM_CONTENT_TYPE)) {
|
|
1188
|
-
return true;
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
return false;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
985
|
const VALID_PARAM_TYPES = ["string", "number", "undefined"];
|
|
1196
986
|
function validateGetStaticPathsParameter([key, value], route) {
|
|
1197
987
|
if (!VALID_PARAM_TYPES.includes(typeof value)) {
|
|
@@ -1418,74 +1208,6 @@ function findPathItemByKey(staticPaths, params, route, logger) {
|
|
|
1418
1208
|
logger.debug("router", `findPathItemByKey() - Unexpected cache miss looking for ${paramsKey}`);
|
|
1419
1209
|
}
|
|
1420
1210
|
|
|
1421
|
-
function createDefaultRoutes(manifest) {
|
|
1422
|
-
const root = new URL(manifest.hrefRoot);
|
|
1423
|
-
return [
|
|
1424
|
-
{
|
|
1425
|
-
instance: default404Instance,
|
|
1426
|
-
matchesComponent: (filePath) => filePath.href === new URL(DEFAULT_404_COMPONENT, root).href,
|
|
1427
|
-
route: DEFAULT_404_ROUTE.route,
|
|
1428
|
-
component: DEFAULT_404_COMPONENT
|
|
1429
|
-
},
|
|
1430
|
-
{
|
|
1431
|
-
instance: createEndpoint(manifest),
|
|
1432
|
-
matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href,
|
|
1433
|
-
route: SERVER_ISLAND_ROUTE,
|
|
1434
|
-
component: SERVER_ISLAND_COMPONENT
|
|
1435
|
-
}
|
|
1436
|
-
];
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
class Pipeline {
|
|
1440
|
-
constructor(logger, manifest, runtimeMode, renderers, resolve, serverLike, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest)) {
|
|
1441
|
-
this.logger = logger;
|
|
1442
|
-
this.manifest = manifest;
|
|
1443
|
-
this.runtimeMode = runtimeMode;
|
|
1444
|
-
this.renderers = renderers;
|
|
1445
|
-
this.resolve = resolve;
|
|
1446
|
-
this.serverLike = serverLike;
|
|
1447
|
-
this.streaming = streaming;
|
|
1448
|
-
this.adapterName = adapterName;
|
|
1449
|
-
this.clientDirectives = clientDirectives;
|
|
1450
|
-
this.inlinedScripts = inlinedScripts;
|
|
1451
|
-
this.compressHTML = compressHTML;
|
|
1452
|
-
this.i18n = i18n;
|
|
1453
|
-
this.middleware = middleware;
|
|
1454
|
-
this.routeCache = routeCache;
|
|
1455
|
-
this.site = site;
|
|
1456
|
-
this.defaultRoutes = defaultRoutes;
|
|
1457
|
-
this.internalMiddleware = [];
|
|
1458
|
-
if (i18n?.strategy !== "manual") {
|
|
1459
|
-
this.internalMiddleware.push(
|
|
1460
|
-
createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat)
|
|
1461
|
-
);
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
internalMiddleware;
|
|
1465
|
-
resolvedMiddleware = void 0;
|
|
1466
|
-
/**
|
|
1467
|
-
* Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there,
|
|
1468
|
-
* it returns a no-op function
|
|
1469
|
-
*/
|
|
1470
|
-
async getMiddleware() {
|
|
1471
|
-
if (this.resolvedMiddleware) {
|
|
1472
|
-
return this.resolvedMiddleware;
|
|
1473
|
-
} else if (this.middleware) {
|
|
1474
|
-
const middlewareInstance = await this.middleware();
|
|
1475
|
-
const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN;
|
|
1476
|
-
if (this.manifest.checkOrigin) {
|
|
1477
|
-
this.resolvedMiddleware = sequence(createOriginCheckMiddleware(), onRequest);
|
|
1478
|
-
} else {
|
|
1479
|
-
this.resolvedMiddleware = onRequest;
|
|
1480
|
-
}
|
|
1481
|
-
return this.resolvedMiddleware;
|
|
1482
|
-
} else {
|
|
1483
|
-
this.resolvedMiddleware = NOOP_MIDDLEWARE_FN;
|
|
1484
|
-
return this.resolvedMiddleware;
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
1211
|
function routeIsRedirect(route) {
|
|
1490
1212
|
return route?.type === "redirect";
|
|
1491
1213
|
}
|
|
@@ -1493,19 +1215,6 @@ function routeIsFallback(route) {
|
|
|
1493
1215
|
return route?.type === "fallback";
|
|
1494
1216
|
}
|
|
1495
1217
|
|
|
1496
|
-
const RedirectComponentInstance = {
|
|
1497
|
-
default() {
|
|
1498
|
-
return new Response(null, {
|
|
1499
|
-
status: 301
|
|
1500
|
-
});
|
|
1501
|
-
}
|
|
1502
|
-
};
|
|
1503
|
-
const RedirectSinglePageBuiltModule = {
|
|
1504
|
-
page: () => Promise.resolve(RedirectComponentInstance),
|
|
1505
|
-
onRequest: (_, next) => next(),
|
|
1506
|
-
renderers: []
|
|
1507
|
-
};
|
|
1508
|
-
|
|
1509
1218
|
async function getProps(opts) {
|
|
1510
1219
|
const { logger, mod, routeData: route, routeCache, pathname, serverLike, base } = opts;
|
|
1511
1220
|
if (!route || route.pathname) {
|
|
@@ -1634,79 +1343,673 @@ class Slots {
|
|
|
1634
1343
|
}
|
|
1635
1344
|
}
|
|
1636
1345
|
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1346
|
+
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
|
|
1347
|
+
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
|
|
1348
|
+
const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
|
|
1349
|
+
function jsonParseTransform(key, value) {
|
|
1350
|
+
if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
|
|
1351
|
+
warnKeyDropped(key);
|
|
1352
|
+
return;
|
|
1644
1353
|
}
|
|
1645
|
-
return
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
handleContext.request = newRequest;
|
|
1682
|
-
handleContext.url = new URL(newRequest.url);
|
|
1683
|
-
handleContext.cookies = new AstroCookies(newRequest);
|
|
1684
|
-
handleContext.params = getParams(routeData, pathname);
|
|
1685
|
-
}
|
|
1686
|
-
return applyHandle(i + 1, handleContext);
|
|
1687
|
-
} else {
|
|
1688
|
-
return next(payload ?? carriedPayload);
|
|
1689
|
-
}
|
|
1690
|
-
});
|
|
1691
|
-
return result;
|
|
1354
|
+
return value;
|
|
1355
|
+
}
|
|
1356
|
+
function warnKeyDropped(key) {
|
|
1357
|
+
console.warn(`[destr] Dropping "${key}" key to prevent prototype pollution.`);
|
|
1358
|
+
}
|
|
1359
|
+
function destr(value, options = {}) {
|
|
1360
|
+
if (typeof value !== "string") {
|
|
1361
|
+
return value;
|
|
1362
|
+
}
|
|
1363
|
+
if (value[0] === '"' && value[value.length - 1] === '"' && value.indexOf("\\") === -1) {
|
|
1364
|
+
return value.slice(1, -1);
|
|
1365
|
+
}
|
|
1366
|
+
const _value = value.trim();
|
|
1367
|
+
if (_value.length <= 9) {
|
|
1368
|
+
switch (_value.toLowerCase()) {
|
|
1369
|
+
case "true": {
|
|
1370
|
+
return true;
|
|
1371
|
+
}
|
|
1372
|
+
case "false": {
|
|
1373
|
+
return false;
|
|
1374
|
+
}
|
|
1375
|
+
case "undefined": {
|
|
1376
|
+
return void 0;
|
|
1377
|
+
}
|
|
1378
|
+
case "null": {
|
|
1379
|
+
return null;
|
|
1380
|
+
}
|
|
1381
|
+
case "nan": {
|
|
1382
|
+
return Number.NaN;
|
|
1383
|
+
}
|
|
1384
|
+
case "infinity": {
|
|
1385
|
+
return Number.POSITIVE_INFINITY;
|
|
1386
|
+
}
|
|
1387
|
+
case "-infinity": {
|
|
1388
|
+
return Number.NEGATIVE_INFINITY;
|
|
1389
|
+
}
|
|
1692
1390
|
}
|
|
1693
|
-
}
|
|
1391
|
+
}
|
|
1392
|
+
if (!JsonSigRx.test(value)) {
|
|
1393
|
+
if (options.strict) {
|
|
1394
|
+
throw new SyntaxError("[destr] Invalid JSON");
|
|
1395
|
+
}
|
|
1396
|
+
return value;
|
|
1397
|
+
}
|
|
1398
|
+
try {
|
|
1399
|
+
if (suspectProtoRx.test(value) || suspectConstructorRx.test(value)) {
|
|
1400
|
+
if (options.strict) {
|
|
1401
|
+
throw new Error("[destr] Possible prototype pollution");
|
|
1402
|
+
}
|
|
1403
|
+
return JSON.parse(value, jsonParseTransform);
|
|
1404
|
+
}
|
|
1405
|
+
return JSON.parse(value);
|
|
1406
|
+
} catch (error) {
|
|
1407
|
+
if (options.strict) {
|
|
1408
|
+
throw error;
|
|
1409
|
+
}
|
|
1410
|
+
return value;
|
|
1411
|
+
}
|
|
1694
1412
|
}
|
|
1695
1413
|
|
|
1696
|
-
function
|
|
1697
|
-
|
|
1414
|
+
function wrapToPromise(value) {
|
|
1415
|
+
if (!value || typeof value.then !== "function") {
|
|
1416
|
+
return Promise.resolve(value);
|
|
1417
|
+
}
|
|
1418
|
+
return value;
|
|
1698
1419
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1420
|
+
function asyncCall(function_, ...arguments_) {
|
|
1421
|
+
try {
|
|
1422
|
+
return wrapToPromise(function_(...arguments_));
|
|
1423
|
+
} catch (error) {
|
|
1424
|
+
return Promise.reject(error);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
function isPrimitive(value) {
|
|
1428
|
+
const type = typeof value;
|
|
1429
|
+
return value === null || type !== "object" && type !== "function";
|
|
1430
|
+
}
|
|
1431
|
+
function isPureObject(value) {
|
|
1432
|
+
const proto = Object.getPrototypeOf(value);
|
|
1433
|
+
return !proto || proto.isPrototypeOf(Object);
|
|
1434
|
+
}
|
|
1435
|
+
function stringify$1(value) {
|
|
1436
|
+
if (isPrimitive(value)) {
|
|
1437
|
+
return String(value);
|
|
1438
|
+
}
|
|
1439
|
+
if (isPureObject(value) || Array.isArray(value)) {
|
|
1440
|
+
return JSON.stringify(value);
|
|
1441
|
+
}
|
|
1442
|
+
if (typeof value.toJSON === "function") {
|
|
1443
|
+
return stringify$1(value.toJSON());
|
|
1444
|
+
}
|
|
1445
|
+
throw new Error("[unstorage] Cannot stringify value!");
|
|
1446
|
+
}
|
|
1447
|
+
const BASE64_PREFIX = "base64:";
|
|
1448
|
+
function serializeRaw(value) {
|
|
1449
|
+
if (typeof value === "string") {
|
|
1450
|
+
return value;
|
|
1451
|
+
}
|
|
1452
|
+
return BASE64_PREFIX + base64Encode(value);
|
|
1453
|
+
}
|
|
1454
|
+
function deserializeRaw(value) {
|
|
1455
|
+
if (typeof value !== "string") {
|
|
1456
|
+
return value;
|
|
1457
|
+
}
|
|
1458
|
+
if (!value.startsWith(BASE64_PREFIX)) {
|
|
1459
|
+
return value;
|
|
1460
|
+
}
|
|
1461
|
+
return base64Decode(value.slice(BASE64_PREFIX.length));
|
|
1462
|
+
}
|
|
1463
|
+
function base64Decode(input) {
|
|
1464
|
+
if (globalThis.Buffer) {
|
|
1465
|
+
return Buffer.from(input, "base64");
|
|
1466
|
+
}
|
|
1467
|
+
return Uint8Array.from(
|
|
1468
|
+
globalThis.atob(input),
|
|
1469
|
+
(c) => c.codePointAt(0)
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
function base64Encode(input) {
|
|
1473
|
+
if (globalThis.Buffer) {
|
|
1474
|
+
return Buffer.from(input).toString("base64");
|
|
1475
|
+
}
|
|
1476
|
+
return globalThis.btoa(String.fromCodePoint(...input));
|
|
1477
|
+
}
|
|
1478
|
+
function normalizeKey(key) {
|
|
1479
|
+
if (!key) {
|
|
1480
|
+
return "";
|
|
1481
|
+
}
|
|
1482
|
+
return key.split("?")[0]?.replace(/[/\\]/g, ":").replace(/:+/g, ":").replace(/^:|:$/g, "") || "";
|
|
1483
|
+
}
|
|
1484
|
+
function joinKeys(...keys) {
|
|
1485
|
+
return normalizeKey(keys.join(":"));
|
|
1486
|
+
}
|
|
1487
|
+
function normalizeBaseKey(base) {
|
|
1488
|
+
base = normalizeKey(base);
|
|
1489
|
+
return base ? base + ":" : "";
|
|
1490
|
+
}
|
|
1491
|
+
function filterKeyByDepth(key, depth) {
|
|
1492
|
+
if (depth === void 0) {
|
|
1493
|
+
return true;
|
|
1494
|
+
}
|
|
1495
|
+
let substrCount = 0;
|
|
1496
|
+
let index = key.indexOf(":");
|
|
1497
|
+
while (index > -1) {
|
|
1498
|
+
substrCount++;
|
|
1499
|
+
index = key.indexOf(":", index + 1);
|
|
1500
|
+
}
|
|
1501
|
+
return substrCount <= depth;
|
|
1502
|
+
}
|
|
1503
|
+
function filterKeyByBase(key, base) {
|
|
1504
|
+
if (base) {
|
|
1505
|
+
return key.startsWith(base) && key[key.length - 1] !== "$";
|
|
1506
|
+
}
|
|
1507
|
+
return key[key.length - 1] !== "$";
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
function defineDriver(factory) {
|
|
1511
|
+
return factory;
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
const DRIVER_NAME = "memory";
|
|
1515
|
+
const memory = defineDriver(() => {
|
|
1516
|
+
const data = /* @__PURE__ */ new Map();
|
|
1517
|
+
return {
|
|
1518
|
+
name: DRIVER_NAME,
|
|
1519
|
+
getInstance: () => data,
|
|
1520
|
+
hasItem(key) {
|
|
1521
|
+
return data.has(key);
|
|
1522
|
+
},
|
|
1523
|
+
getItem(key) {
|
|
1524
|
+
return data.get(key) ?? null;
|
|
1525
|
+
},
|
|
1526
|
+
getItemRaw(key) {
|
|
1527
|
+
return data.get(key) ?? null;
|
|
1528
|
+
},
|
|
1529
|
+
setItem(key, value) {
|
|
1530
|
+
data.set(key, value);
|
|
1531
|
+
},
|
|
1532
|
+
setItemRaw(key, value) {
|
|
1533
|
+
data.set(key, value);
|
|
1534
|
+
},
|
|
1535
|
+
removeItem(key) {
|
|
1536
|
+
data.delete(key);
|
|
1537
|
+
},
|
|
1538
|
+
getKeys() {
|
|
1539
|
+
return [...data.keys()];
|
|
1540
|
+
},
|
|
1541
|
+
clear() {
|
|
1542
|
+
data.clear();
|
|
1543
|
+
},
|
|
1544
|
+
dispose() {
|
|
1545
|
+
data.clear();
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
});
|
|
1549
|
+
|
|
1550
|
+
function createStorage(options = {}) {
|
|
1551
|
+
const context = {
|
|
1552
|
+
mounts: { "": options.driver || memory() },
|
|
1553
|
+
mountpoints: [""],
|
|
1554
|
+
watching: false,
|
|
1555
|
+
watchListeners: [],
|
|
1556
|
+
unwatch: {}
|
|
1557
|
+
};
|
|
1558
|
+
const getMount = (key) => {
|
|
1559
|
+
for (const base of context.mountpoints) {
|
|
1560
|
+
if (key.startsWith(base)) {
|
|
1561
|
+
return {
|
|
1562
|
+
base,
|
|
1563
|
+
relativeKey: key.slice(base.length),
|
|
1564
|
+
driver: context.mounts[base]
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
return {
|
|
1569
|
+
base: "",
|
|
1570
|
+
relativeKey: key,
|
|
1571
|
+
driver: context.mounts[""]
|
|
1572
|
+
};
|
|
1573
|
+
};
|
|
1574
|
+
const getMounts = (base, includeParent) => {
|
|
1575
|
+
return context.mountpoints.filter(
|
|
1576
|
+
(mountpoint) => mountpoint.startsWith(base) || includeParent && base.startsWith(mountpoint)
|
|
1577
|
+
).map((mountpoint) => ({
|
|
1578
|
+
relativeBase: base.length > mountpoint.length ? base.slice(mountpoint.length) : void 0,
|
|
1579
|
+
mountpoint,
|
|
1580
|
+
driver: context.mounts[mountpoint]
|
|
1581
|
+
}));
|
|
1582
|
+
};
|
|
1583
|
+
const onChange = (event, key) => {
|
|
1584
|
+
if (!context.watching) {
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
key = normalizeKey(key);
|
|
1588
|
+
for (const listener of context.watchListeners) {
|
|
1589
|
+
listener(event, key);
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
const startWatch = async () => {
|
|
1593
|
+
if (context.watching) {
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
context.watching = true;
|
|
1597
|
+
for (const mountpoint in context.mounts) {
|
|
1598
|
+
context.unwatch[mountpoint] = await watch(
|
|
1599
|
+
context.mounts[mountpoint],
|
|
1600
|
+
onChange,
|
|
1601
|
+
mountpoint
|
|
1602
|
+
);
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1605
|
+
const stopWatch = async () => {
|
|
1606
|
+
if (!context.watching) {
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
for (const mountpoint in context.unwatch) {
|
|
1610
|
+
await context.unwatch[mountpoint]();
|
|
1611
|
+
}
|
|
1612
|
+
context.unwatch = {};
|
|
1613
|
+
context.watching = false;
|
|
1614
|
+
};
|
|
1615
|
+
const runBatch = (items, commonOptions, cb) => {
|
|
1616
|
+
const batches = /* @__PURE__ */ new Map();
|
|
1617
|
+
const getBatch = (mount) => {
|
|
1618
|
+
let batch = batches.get(mount.base);
|
|
1619
|
+
if (!batch) {
|
|
1620
|
+
batch = {
|
|
1621
|
+
driver: mount.driver,
|
|
1622
|
+
base: mount.base,
|
|
1623
|
+
items: []
|
|
1624
|
+
};
|
|
1625
|
+
batches.set(mount.base, batch);
|
|
1626
|
+
}
|
|
1627
|
+
return batch;
|
|
1628
|
+
};
|
|
1629
|
+
for (const item of items) {
|
|
1630
|
+
const isStringItem = typeof item === "string";
|
|
1631
|
+
const key = normalizeKey(isStringItem ? item : item.key);
|
|
1632
|
+
const value = isStringItem ? void 0 : item.value;
|
|
1633
|
+
const options2 = isStringItem || !item.options ? commonOptions : { ...commonOptions, ...item.options };
|
|
1634
|
+
const mount = getMount(key);
|
|
1635
|
+
getBatch(mount).items.push({
|
|
1636
|
+
key,
|
|
1637
|
+
value,
|
|
1638
|
+
relativeKey: mount.relativeKey,
|
|
1639
|
+
options: options2
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
return Promise.all([...batches.values()].map((batch) => cb(batch))).then(
|
|
1643
|
+
(r) => r.flat()
|
|
1644
|
+
);
|
|
1645
|
+
};
|
|
1646
|
+
const storage = {
|
|
1647
|
+
// Item
|
|
1648
|
+
hasItem(key, opts = {}) {
|
|
1649
|
+
key = normalizeKey(key);
|
|
1650
|
+
const { relativeKey, driver } = getMount(key);
|
|
1651
|
+
return asyncCall(driver.hasItem, relativeKey, opts);
|
|
1652
|
+
},
|
|
1653
|
+
getItem(key, opts = {}) {
|
|
1654
|
+
key = normalizeKey(key);
|
|
1655
|
+
const { relativeKey, driver } = getMount(key);
|
|
1656
|
+
return asyncCall(driver.getItem, relativeKey, opts).then(
|
|
1657
|
+
(value) => destr(value)
|
|
1658
|
+
);
|
|
1659
|
+
},
|
|
1660
|
+
getItems(items, commonOptions = {}) {
|
|
1661
|
+
return runBatch(items, commonOptions, (batch) => {
|
|
1662
|
+
if (batch.driver.getItems) {
|
|
1663
|
+
return asyncCall(
|
|
1664
|
+
batch.driver.getItems,
|
|
1665
|
+
batch.items.map((item) => ({
|
|
1666
|
+
key: item.relativeKey,
|
|
1667
|
+
options: item.options
|
|
1668
|
+
})),
|
|
1669
|
+
commonOptions
|
|
1670
|
+
).then(
|
|
1671
|
+
(r) => r.map((item) => ({
|
|
1672
|
+
key: joinKeys(batch.base, item.key),
|
|
1673
|
+
value: destr(item.value)
|
|
1674
|
+
}))
|
|
1675
|
+
);
|
|
1676
|
+
}
|
|
1677
|
+
return Promise.all(
|
|
1678
|
+
batch.items.map((item) => {
|
|
1679
|
+
return asyncCall(
|
|
1680
|
+
batch.driver.getItem,
|
|
1681
|
+
item.relativeKey,
|
|
1682
|
+
item.options
|
|
1683
|
+
).then((value) => ({
|
|
1684
|
+
key: item.key,
|
|
1685
|
+
value: destr(value)
|
|
1686
|
+
}));
|
|
1687
|
+
})
|
|
1688
|
+
);
|
|
1689
|
+
});
|
|
1690
|
+
},
|
|
1691
|
+
getItemRaw(key, opts = {}) {
|
|
1692
|
+
key = normalizeKey(key);
|
|
1693
|
+
const { relativeKey, driver } = getMount(key);
|
|
1694
|
+
if (driver.getItemRaw) {
|
|
1695
|
+
return asyncCall(driver.getItemRaw, relativeKey, opts);
|
|
1696
|
+
}
|
|
1697
|
+
return asyncCall(driver.getItem, relativeKey, opts).then(
|
|
1698
|
+
(value) => deserializeRaw(value)
|
|
1699
|
+
);
|
|
1700
|
+
},
|
|
1701
|
+
async setItem(key, value, opts = {}) {
|
|
1702
|
+
if (value === void 0) {
|
|
1703
|
+
return storage.removeItem(key);
|
|
1704
|
+
}
|
|
1705
|
+
key = normalizeKey(key);
|
|
1706
|
+
const { relativeKey, driver } = getMount(key);
|
|
1707
|
+
if (!driver.setItem) {
|
|
1708
|
+
return;
|
|
1709
|
+
}
|
|
1710
|
+
await asyncCall(driver.setItem, relativeKey, stringify$1(value), opts);
|
|
1711
|
+
if (!driver.watch) {
|
|
1712
|
+
onChange("update", key);
|
|
1713
|
+
}
|
|
1714
|
+
},
|
|
1715
|
+
async setItems(items, commonOptions) {
|
|
1716
|
+
await runBatch(items, commonOptions, async (batch) => {
|
|
1717
|
+
if (batch.driver.setItems) {
|
|
1718
|
+
return asyncCall(
|
|
1719
|
+
batch.driver.setItems,
|
|
1720
|
+
batch.items.map((item) => ({
|
|
1721
|
+
key: item.relativeKey,
|
|
1722
|
+
value: stringify$1(item.value),
|
|
1723
|
+
options: item.options
|
|
1724
|
+
})),
|
|
1725
|
+
commonOptions
|
|
1726
|
+
);
|
|
1727
|
+
}
|
|
1728
|
+
if (!batch.driver.setItem) {
|
|
1729
|
+
return;
|
|
1730
|
+
}
|
|
1731
|
+
await Promise.all(
|
|
1732
|
+
batch.items.map((item) => {
|
|
1733
|
+
return asyncCall(
|
|
1734
|
+
batch.driver.setItem,
|
|
1735
|
+
item.relativeKey,
|
|
1736
|
+
stringify$1(item.value),
|
|
1737
|
+
item.options
|
|
1738
|
+
);
|
|
1739
|
+
})
|
|
1740
|
+
);
|
|
1741
|
+
});
|
|
1742
|
+
},
|
|
1743
|
+
async setItemRaw(key, value, opts = {}) {
|
|
1744
|
+
if (value === void 0) {
|
|
1745
|
+
return storage.removeItem(key, opts);
|
|
1746
|
+
}
|
|
1747
|
+
key = normalizeKey(key);
|
|
1748
|
+
const { relativeKey, driver } = getMount(key);
|
|
1749
|
+
if (driver.setItemRaw) {
|
|
1750
|
+
await asyncCall(driver.setItemRaw, relativeKey, value, opts);
|
|
1751
|
+
} else if (driver.setItem) {
|
|
1752
|
+
await asyncCall(driver.setItem, relativeKey, serializeRaw(value), opts);
|
|
1753
|
+
} else {
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
if (!driver.watch) {
|
|
1757
|
+
onChange("update", key);
|
|
1758
|
+
}
|
|
1759
|
+
},
|
|
1760
|
+
async removeItem(key, opts = {}) {
|
|
1761
|
+
if (typeof opts === "boolean") {
|
|
1762
|
+
opts = { removeMeta: opts };
|
|
1763
|
+
}
|
|
1764
|
+
key = normalizeKey(key);
|
|
1765
|
+
const { relativeKey, driver } = getMount(key);
|
|
1766
|
+
if (!driver.removeItem) {
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
await asyncCall(driver.removeItem, relativeKey, opts);
|
|
1770
|
+
if (opts.removeMeta || opts.removeMata) {
|
|
1771
|
+
await asyncCall(driver.removeItem, relativeKey + "$", opts);
|
|
1772
|
+
}
|
|
1773
|
+
if (!driver.watch) {
|
|
1774
|
+
onChange("remove", key);
|
|
1775
|
+
}
|
|
1776
|
+
},
|
|
1777
|
+
// Meta
|
|
1778
|
+
async getMeta(key, opts = {}) {
|
|
1779
|
+
if (typeof opts === "boolean") {
|
|
1780
|
+
opts = { nativeOnly: opts };
|
|
1781
|
+
}
|
|
1782
|
+
key = normalizeKey(key);
|
|
1783
|
+
const { relativeKey, driver } = getMount(key);
|
|
1784
|
+
const meta = /* @__PURE__ */ Object.create(null);
|
|
1785
|
+
if (driver.getMeta) {
|
|
1786
|
+
Object.assign(meta, await asyncCall(driver.getMeta, relativeKey, opts));
|
|
1787
|
+
}
|
|
1788
|
+
if (!opts.nativeOnly) {
|
|
1789
|
+
const value = await asyncCall(
|
|
1790
|
+
driver.getItem,
|
|
1791
|
+
relativeKey + "$",
|
|
1792
|
+
opts
|
|
1793
|
+
).then((value_) => destr(value_));
|
|
1794
|
+
if (value && typeof value === "object") {
|
|
1795
|
+
if (typeof value.atime === "string") {
|
|
1796
|
+
value.atime = new Date(value.atime);
|
|
1797
|
+
}
|
|
1798
|
+
if (typeof value.mtime === "string") {
|
|
1799
|
+
value.mtime = new Date(value.mtime);
|
|
1800
|
+
}
|
|
1801
|
+
Object.assign(meta, value);
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
return meta;
|
|
1805
|
+
},
|
|
1806
|
+
setMeta(key, value, opts = {}) {
|
|
1807
|
+
return this.setItem(key + "$", value, opts);
|
|
1808
|
+
},
|
|
1809
|
+
removeMeta(key, opts = {}) {
|
|
1810
|
+
return this.removeItem(key + "$", opts);
|
|
1811
|
+
},
|
|
1812
|
+
// Keys
|
|
1813
|
+
async getKeys(base, opts = {}) {
|
|
1814
|
+
base = normalizeBaseKey(base);
|
|
1815
|
+
const mounts = getMounts(base, true);
|
|
1816
|
+
let maskedMounts = [];
|
|
1817
|
+
const allKeys = [];
|
|
1818
|
+
let allMountsSupportMaxDepth = true;
|
|
1819
|
+
for (const mount of mounts) {
|
|
1820
|
+
if (!mount.driver.flags?.maxDepth) {
|
|
1821
|
+
allMountsSupportMaxDepth = false;
|
|
1822
|
+
}
|
|
1823
|
+
const rawKeys = await asyncCall(
|
|
1824
|
+
mount.driver.getKeys,
|
|
1825
|
+
mount.relativeBase,
|
|
1826
|
+
opts
|
|
1827
|
+
);
|
|
1828
|
+
for (const key of rawKeys) {
|
|
1829
|
+
const fullKey = mount.mountpoint + normalizeKey(key);
|
|
1830
|
+
if (!maskedMounts.some((p) => fullKey.startsWith(p))) {
|
|
1831
|
+
allKeys.push(fullKey);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
maskedMounts = [
|
|
1835
|
+
mount.mountpoint,
|
|
1836
|
+
...maskedMounts.filter((p) => !p.startsWith(mount.mountpoint))
|
|
1837
|
+
];
|
|
1838
|
+
}
|
|
1839
|
+
const shouldFilterByDepth = opts.maxDepth !== void 0 && !allMountsSupportMaxDepth;
|
|
1840
|
+
return allKeys.filter(
|
|
1841
|
+
(key) => (!shouldFilterByDepth || filterKeyByDepth(key, opts.maxDepth)) && filterKeyByBase(key, base)
|
|
1842
|
+
);
|
|
1843
|
+
},
|
|
1844
|
+
// Utils
|
|
1845
|
+
async clear(base, opts = {}) {
|
|
1846
|
+
base = normalizeBaseKey(base);
|
|
1847
|
+
await Promise.all(
|
|
1848
|
+
getMounts(base, false).map(async (m) => {
|
|
1849
|
+
if (m.driver.clear) {
|
|
1850
|
+
return asyncCall(m.driver.clear, m.relativeBase, opts);
|
|
1851
|
+
}
|
|
1852
|
+
if (m.driver.removeItem) {
|
|
1853
|
+
const keys = await m.driver.getKeys(m.relativeBase || "", opts);
|
|
1854
|
+
return Promise.all(
|
|
1855
|
+
keys.map((key) => m.driver.removeItem(key, opts))
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
})
|
|
1859
|
+
);
|
|
1860
|
+
},
|
|
1861
|
+
async dispose() {
|
|
1862
|
+
await Promise.all(
|
|
1863
|
+
Object.values(context.mounts).map((driver) => dispose(driver))
|
|
1864
|
+
);
|
|
1865
|
+
},
|
|
1866
|
+
async watch(callback) {
|
|
1867
|
+
await startWatch();
|
|
1868
|
+
context.watchListeners.push(callback);
|
|
1869
|
+
return async () => {
|
|
1870
|
+
context.watchListeners = context.watchListeners.filter(
|
|
1871
|
+
(listener) => listener !== callback
|
|
1872
|
+
);
|
|
1873
|
+
if (context.watchListeners.length === 0) {
|
|
1874
|
+
await stopWatch();
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
},
|
|
1878
|
+
async unwatch() {
|
|
1879
|
+
context.watchListeners = [];
|
|
1880
|
+
await stopWatch();
|
|
1881
|
+
},
|
|
1882
|
+
// Mount
|
|
1883
|
+
mount(base, driver) {
|
|
1884
|
+
base = normalizeBaseKey(base);
|
|
1885
|
+
if (base && context.mounts[base]) {
|
|
1886
|
+
throw new Error(`already mounted at ${base}`);
|
|
1887
|
+
}
|
|
1888
|
+
if (base) {
|
|
1889
|
+
context.mountpoints.push(base);
|
|
1890
|
+
context.mountpoints.sort((a, b) => b.length - a.length);
|
|
1891
|
+
}
|
|
1892
|
+
context.mounts[base] = driver;
|
|
1893
|
+
if (context.watching) {
|
|
1894
|
+
Promise.resolve(watch(driver, onChange, base)).then((unwatcher) => {
|
|
1895
|
+
context.unwatch[base] = unwatcher;
|
|
1896
|
+
}).catch(console.error);
|
|
1897
|
+
}
|
|
1898
|
+
return storage;
|
|
1899
|
+
},
|
|
1900
|
+
async unmount(base, _dispose = true) {
|
|
1901
|
+
base = normalizeBaseKey(base);
|
|
1902
|
+
if (!base || !context.mounts[base]) {
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
if (context.watching && base in context.unwatch) {
|
|
1906
|
+
context.unwatch[base]?.();
|
|
1907
|
+
delete context.unwatch[base];
|
|
1908
|
+
}
|
|
1909
|
+
if (_dispose) {
|
|
1910
|
+
await dispose(context.mounts[base]);
|
|
1911
|
+
}
|
|
1912
|
+
context.mountpoints = context.mountpoints.filter((key) => key !== base);
|
|
1913
|
+
delete context.mounts[base];
|
|
1914
|
+
},
|
|
1915
|
+
getMount(key = "") {
|
|
1916
|
+
key = normalizeKey(key) + ":";
|
|
1917
|
+
const m = getMount(key);
|
|
1918
|
+
return {
|
|
1919
|
+
driver: m.driver,
|
|
1920
|
+
base: m.base
|
|
1921
|
+
};
|
|
1922
|
+
},
|
|
1923
|
+
getMounts(base = "", opts = {}) {
|
|
1924
|
+
base = normalizeKey(base);
|
|
1925
|
+
const mounts = getMounts(base, opts.parents);
|
|
1926
|
+
return mounts.map((m) => ({
|
|
1927
|
+
driver: m.driver,
|
|
1928
|
+
base: m.mountpoint
|
|
1929
|
+
}));
|
|
1930
|
+
},
|
|
1931
|
+
// Aliases
|
|
1932
|
+
keys: (base, opts = {}) => storage.getKeys(base, opts),
|
|
1933
|
+
get: (key, opts = {}) => storage.getItem(key, opts),
|
|
1934
|
+
set: (key, value, opts = {}) => storage.setItem(key, value, opts),
|
|
1935
|
+
has: (key, opts = {}) => storage.hasItem(key, opts),
|
|
1936
|
+
del: (key, opts = {}) => storage.removeItem(key, opts),
|
|
1937
|
+
remove: (key, opts = {}) => storage.removeItem(key, opts)
|
|
1938
|
+
};
|
|
1939
|
+
return storage;
|
|
1940
|
+
}
|
|
1941
|
+
function watch(driver, onChange, base) {
|
|
1942
|
+
return driver.watch ? driver.watch((event, key) => onChange(event, base + key)) : () => {
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
async function dispose(driver) {
|
|
1946
|
+
if (typeof driver.dispose === "function") {
|
|
1947
|
+
await asyncCall(driver.dispose);
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
const builtinDrivers = {
|
|
1952
|
+
"azure-app-configuration": "unstorage/drivers/azure-app-configuration",
|
|
1953
|
+
"azureAppConfiguration": "unstorage/drivers/azure-app-configuration",
|
|
1954
|
+
"azure-cosmos": "unstorage/drivers/azure-cosmos",
|
|
1955
|
+
"azureCosmos": "unstorage/drivers/azure-cosmos",
|
|
1956
|
+
"azure-key-vault": "unstorage/drivers/azure-key-vault",
|
|
1957
|
+
"azureKeyVault": "unstorage/drivers/azure-key-vault",
|
|
1958
|
+
"azure-storage-blob": "unstorage/drivers/azure-storage-blob",
|
|
1959
|
+
"azureStorageBlob": "unstorage/drivers/azure-storage-blob",
|
|
1960
|
+
"azure-storage-table": "unstorage/drivers/azure-storage-table",
|
|
1961
|
+
"azureStorageTable": "unstorage/drivers/azure-storage-table",
|
|
1962
|
+
"capacitor-preferences": "unstorage/drivers/capacitor-preferences",
|
|
1963
|
+
"capacitorPreferences": "unstorage/drivers/capacitor-preferences",
|
|
1964
|
+
"cloudflare-kv-binding": "unstorage/drivers/cloudflare-kv-binding",
|
|
1965
|
+
"cloudflareKVBinding": "unstorage/drivers/cloudflare-kv-binding",
|
|
1966
|
+
"cloudflare-kv-http": "unstorage/drivers/cloudflare-kv-http",
|
|
1967
|
+
"cloudflareKVHttp": "unstorage/drivers/cloudflare-kv-http",
|
|
1968
|
+
"cloudflare-r2-binding": "unstorage/drivers/cloudflare-r2-binding",
|
|
1969
|
+
"cloudflareR2Binding": "unstorage/drivers/cloudflare-r2-binding",
|
|
1970
|
+
"db0": "unstorage/drivers/db0",
|
|
1971
|
+
"deno-kv-node": "unstorage/drivers/deno-kv-node",
|
|
1972
|
+
"denoKVNode": "unstorage/drivers/deno-kv-node",
|
|
1973
|
+
"deno-kv": "unstorage/drivers/deno-kv",
|
|
1974
|
+
"denoKV": "unstorage/drivers/deno-kv",
|
|
1975
|
+
"fs-lite": "unstorage/drivers/fs-lite",
|
|
1976
|
+
"fsLite": "unstorage/drivers/fs-lite",
|
|
1977
|
+
"fs": "unstorage/drivers/fs",
|
|
1978
|
+
"github": "unstorage/drivers/github",
|
|
1979
|
+
"http": "unstorage/drivers/http",
|
|
1980
|
+
"indexedb": "unstorage/drivers/indexedb",
|
|
1981
|
+
"localstorage": "unstorage/drivers/localstorage",
|
|
1982
|
+
"lru-cache": "unstorage/drivers/lru-cache",
|
|
1983
|
+
"lruCache": "unstorage/drivers/lru-cache",
|
|
1984
|
+
"memory": "unstorage/drivers/memory",
|
|
1985
|
+
"mongodb": "unstorage/drivers/mongodb",
|
|
1986
|
+
"netlify-blobs": "unstorage/drivers/netlify-blobs",
|
|
1987
|
+
"netlifyBlobs": "unstorage/drivers/netlify-blobs",
|
|
1988
|
+
"null": "unstorage/drivers/null",
|
|
1989
|
+
"overlay": "unstorage/drivers/overlay",
|
|
1990
|
+
"planetscale": "unstorage/drivers/planetscale",
|
|
1991
|
+
"redis": "unstorage/drivers/redis",
|
|
1992
|
+
"s3": "unstorage/drivers/s3",
|
|
1993
|
+
"session-storage": "unstorage/drivers/session-storage",
|
|
1994
|
+
"sessionStorage": "unstorage/drivers/session-storage",
|
|
1995
|
+
"uploadthing": "unstorage/drivers/uploadthing",
|
|
1996
|
+
"upstash": "unstorage/drivers/upstash",
|
|
1997
|
+
"vercel-blob": "unstorage/drivers/vercel-blob",
|
|
1998
|
+
"vercelBlob": "unstorage/drivers/vercel-blob",
|
|
1999
|
+
"vercel-kv": "unstorage/drivers/vercel-kv",
|
|
2000
|
+
"vercelKV": "unstorage/drivers/vercel-kv"
|
|
2001
|
+
};
|
|
2002
|
+
|
|
2003
|
+
const PERSIST_SYMBOL = Symbol();
|
|
2004
|
+
const DEFAULT_COOKIE_NAME = "astro-session";
|
|
2005
|
+
const VALID_COOKIE_REGEX = /^[\w-]+$/;
|
|
2006
|
+
const unflatten = (parsed, _) => {
|
|
2007
|
+
return unflatten$1(parsed, {
|
|
2008
|
+
URL: (href) => new URL(href)
|
|
2009
|
+
});
|
|
1707
2010
|
};
|
|
1708
2011
|
const stringify = (data, _) => {
|
|
1709
|
-
return stringify$
|
|
2012
|
+
return stringify$2(data, {
|
|
1710
2013
|
// Support URL objects
|
|
1711
2014
|
URL: (val) => val instanceof URL && val.href
|
|
1712
2015
|
});
|
|
@@ -1739,10 +2042,11 @@ class AstroSession {
|
|
|
1739
2042
|
// When we load the data from storage, we need to merge it with the local partial data,
|
|
1740
2043
|
// preserving in-memory changes and deletions.
|
|
1741
2044
|
#partial = true;
|
|
2045
|
+
static #sharedStorage = /* @__PURE__ */ new Map();
|
|
1742
2046
|
constructor(cookies, {
|
|
1743
2047
|
cookie: cookieConfig = DEFAULT_COOKIE_NAME,
|
|
1744
2048
|
...config
|
|
1745
|
-
}) {
|
|
2049
|
+
}, runtimeMode) {
|
|
1746
2050
|
this.#cookies = cookies;
|
|
1747
2051
|
let cookieConfigObject;
|
|
1748
2052
|
if (typeof cookieConfig === "object") {
|
|
@@ -1754,7 +2058,7 @@ class AstroSession {
|
|
|
1754
2058
|
}
|
|
1755
2059
|
this.#cookieConfig = {
|
|
1756
2060
|
sameSite: "lax",
|
|
1757
|
-
secure:
|
|
2061
|
+
secure: runtimeMode === "production",
|
|
1758
2062
|
path: "/",
|
|
1759
2063
|
...cookieConfigObject,
|
|
1760
2064
|
httpOnly: true
|
|
@@ -1906,6 +2210,19 @@ class AstroSession {
|
|
|
1906
2210
|
get sessionID() {
|
|
1907
2211
|
return this.#sessionID;
|
|
1908
2212
|
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Loads a session from storage with the given ID, and replaces the current session.
|
|
2215
|
+
* Any changes made to the current session will be lost.
|
|
2216
|
+
* This is not normally needed, as the session is automatically loaded using the cookie.
|
|
2217
|
+
* However it can be used to restore a session where the ID has been recorded somewhere
|
|
2218
|
+
* else (e.g. in a database).
|
|
2219
|
+
*/
|
|
2220
|
+
async load(sessionID) {
|
|
2221
|
+
this.#sessionID = sessionID;
|
|
2222
|
+
this.#data = void 0;
|
|
2223
|
+
await this.#setCookie();
|
|
2224
|
+
await this.#ensureData();
|
|
2225
|
+
}
|
|
1909
2226
|
/**
|
|
1910
2227
|
* Sets the session cookie.
|
|
1911
2228
|
*/
|
|
@@ -2000,6 +2317,10 @@ class AstroSession {
|
|
|
2000
2317
|
if (this.#storage) {
|
|
2001
2318
|
return this.#storage;
|
|
2002
2319
|
}
|
|
2320
|
+
if (AstroSession.#sharedStorage.has(this.#config.driver)) {
|
|
2321
|
+
this.#storage = AstroSession.#sharedStorage.get(this.#config.driver);
|
|
2322
|
+
return this.#storage;
|
|
2323
|
+
}
|
|
2003
2324
|
if (this.#config.driver === "test") {
|
|
2004
2325
|
this.#storage = this.#config.options.mockStorage;
|
|
2005
2326
|
return this.#storage;
|
|
@@ -2018,12 +2339,14 @@ class AstroSession {
|
|
|
2018
2339
|
});
|
|
2019
2340
|
}
|
|
2020
2341
|
let driver = null;
|
|
2021
|
-
const driverPackage = await resolveSessionDriver(this.#config.driver);
|
|
2022
2342
|
try {
|
|
2023
2343
|
if (this.#config.driverModule) {
|
|
2024
2344
|
driver = (await this.#config.driverModule()).default;
|
|
2025
|
-
} else if (
|
|
2026
|
-
|
|
2345
|
+
} else if (this.#config.driver) {
|
|
2346
|
+
const driverName = resolveSessionDriverName(this.#config.driver);
|
|
2347
|
+
if (driverName) {
|
|
2348
|
+
driver = (await import(driverName)).default;
|
|
2349
|
+
}
|
|
2027
2350
|
}
|
|
2028
2351
|
} catch (err) {
|
|
2029
2352
|
if (err.code === "ERR_MODULE_NOT_FOUND") {
|
|
@@ -2031,7 +2354,7 @@ class AstroSession {
|
|
|
2031
2354
|
{
|
|
2032
2355
|
...SessionStorageInitError,
|
|
2033
2356
|
message: SessionStorageInitError.message(
|
|
2034
|
-
err.message.includes(`Cannot find package
|
|
2357
|
+
err.message.includes(`Cannot find package`) ? "The driver module could not be found." : err.message,
|
|
2035
2358
|
this.#config.driver
|
|
2036
2359
|
)
|
|
2037
2360
|
},
|
|
@@ -2053,6 +2376,7 @@ class AstroSession {
|
|
|
2053
2376
|
this.#storage = createStorage({
|
|
2054
2377
|
driver: driver(this.#config.options)
|
|
2055
2378
|
});
|
|
2379
|
+
AstroSession.#sharedStorage.set(this.#config.driver, this.#storage);
|
|
2056
2380
|
return this.#storage;
|
|
2057
2381
|
} catch (err) {
|
|
2058
2382
|
throw new AstroError(
|
|
@@ -2065,16 +2389,16 @@ class AstroSession {
|
|
|
2065
2389
|
}
|
|
2066
2390
|
}
|
|
2067
2391
|
}
|
|
2068
|
-
|
|
2392
|
+
function resolveSessionDriverName(driver) {
|
|
2069
2393
|
if (!driver) {
|
|
2070
2394
|
return null;
|
|
2071
2395
|
}
|
|
2072
2396
|
try {
|
|
2073
2397
|
if (driver === "fs") {
|
|
2074
|
-
return
|
|
2398
|
+
return builtinDrivers.fsLite;
|
|
2075
2399
|
}
|
|
2076
2400
|
if (driver in builtinDrivers) {
|
|
2077
|
-
return
|
|
2401
|
+
return builtinDrivers[driver];
|
|
2078
2402
|
}
|
|
2079
2403
|
} catch {
|
|
2080
2404
|
return null;
|
|
@@ -2084,10 +2408,11 @@ async function resolveSessionDriver(driver) {
|
|
|
2084
2408
|
|
|
2085
2409
|
const apiContextRoutesSymbol = Symbol.for("context.routes");
|
|
2086
2410
|
class RenderContext {
|
|
2087
|
-
constructor(pipeline, locals, middleware, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig) : void 0) {
|
|
2411
|
+
constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig, pipeline.runtimeMode) : void 0) {
|
|
2088
2412
|
this.pipeline = pipeline;
|
|
2089
2413
|
this.locals = locals;
|
|
2090
2414
|
this.middleware = middleware;
|
|
2415
|
+
this.actions = actions;
|
|
2091
2416
|
this.pathname = pathname;
|
|
2092
2417
|
this.request = request;
|
|
2093
2418
|
this.routeData = routeData;
|
|
@@ -2108,6 +2433,7 @@ class RenderContext {
|
|
|
2108
2433
|
* A safety net in case of loops
|
|
2109
2434
|
*/
|
|
2110
2435
|
counter = 0;
|
|
2436
|
+
result = void 0;
|
|
2111
2437
|
static async create({
|
|
2112
2438
|
locals = {},
|
|
2113
2439
|
middleware,
|
|
@@ -2118,14 +2444,17 @@ class RenderContext {
|
|
|
2118
2444
|
clientAddress,
|
|
2119
2445
|
status = 200,
|
|
2120
2446
|
props,
|
|
2121
|
-
partial = void 0
|
|
2447
|
+
partial = void 0,
|
|
2448
|
+
actions
|
|
2122
2449
|
}) {
|
|
2123
2450
|
const pipelineMiddleware = await pipeline.getMiddleware();
|
|
2451
|
+
const pipelineActions = actions ?? await pipeline.getActions();
|
|
2124
2452
|
setOriginPathname(request, pathname);
|
|
2125
2453
|
return new RenderContext(
|
|
2126
2454
|
pipeline,
|
|
2127
2455
|
locals,
|
|
2128
2456
|
sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware),
|
|
2457
|
+
pipelineActions,
|
|
2129
2458
|
pathname,
|
|
2130
2459
|
request,
|
|
2131
2460
|
routeData,
|
|
@@ -2161,7 +2490,8 @@ class RenderContext {
|
|
|
2161
2490
|
serverLike,
|
|
2162
2491
|
base: manifest.base
|
|
2163
2492
|
});
|
|
2164
|
-
const
|
|
2493
|
+
const actionApiContext = this.createActionAPIContext();
|
|
2494
|
+
const apiContext = this.createAPIContext(props, actionApiContext);
|
|
2165
2495
|
this.counter++;
|
|
2166
2496
|
if (this.counter === 4) {
|
|
2167
2497
|
return new Response("Loop Detected", {
|
|
@@ -2172,6 +2502,7 @@ class RenderContext {
|
|
|
2172
2502
|
}
|
|
2173
2503
|
const lastNext = async (ctx, payload) => {
|
|
2174
2504
|
if (payload) {
|
|
2505
|
+
const oldPathname = this.pathname;
|
|
2175
2506
|
pipeline.logger.debug("router", "Called rewriting to:", payload);
|
|
2176
2507
|
const {
|
|
2177
2508
|
routeData,
|
|
@@ -2202,12 +2533,19 @@ class RenderContext {
|
|
|
2202
2533
|
}
|
|
2203
2534
|
this.isRewriting = true;
|
|
2204
2535
|
this.url = new URL(this.request.url);
|
|
2205
|
-
this.cookies = new AstroCookies(this.request);
|
|
2206
2536
|
this.params = getParams(routeData, pathname);
|
|
2207
2537
|
this.pathname = pathname;
|
|
2208
2538
|
this.status = 200;
|
|
2539
|
+
setOriginPathname(this.request, oldPathname);
|
|
2209
2540
|
}
|
|
2210
2541
|
let response2;
|
|
2542
|
+
if (!ctx.isPrerendered) {
|
|
2543
|
+
const { action, setActionResult, serializeActionResult } = getActionContext(ctx);
|
|
2544
|
+
if (action?.calledFrom === "form") {
|
|
2545
|
+
const actionResult = await action.handler();
|
|
2546
|
+
setActionResult(action.name, serializeActionResult(actionResult));
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2211
2549
|
switch (this.routeData.type) {
|
|
2212
2550
|
case "endpoint": {
|
|
2213
2551
|
response2 = await renderEndpoint(
|
|
@@ -2221,10 +2559,10 @@ class RenderContext {
|
|
|
2221
2559
|
case "redirect":
|
|
2222
2560
|
return renderRedirect(this);
|
|
2223
2561
|
case "page": {
|
|
2224
|
-
|
|
2562
|
+
this.result = await this.createResult(componentInstance, actionApiContext);
|
|
2225
2563
|
try {
|
|
2226
2564
|
response2 = await renderPage(
|
|
2227
|
-
result,
|
|
2565
|
+
this.result,
|
|
2228
2566
|
componentInstance?.default,
|
|
2229
2567
|
props,
|
|
2230
2568
|
slots,
|
|
@@ -2232,7 +2570,7 @@ class RenderContext {
|
|
|
2232
2570
|
this.routeData
|
|
2233
2571
|
);
|
|
2234
2572
|
} catch (e) {
|
|
2235
|
-
result.cancelled = true;
|
|
2573
|
+
this.result.cancelled = true;
|
|
2236
2574
|
throw e;
|
|
2237
2575
|
}
|
|
2238
2576
|
response2.headers.set(ROUTE_TYPE_HEADER, "page");
|
|
@@ -2264,8 +2602,7 @@ class RenderContext {
|
|
|
2264
2602
|
attachCookiesToResponse(response, cookies);
|
|
2265
2603
|
return response;
|
|
2266
2604
|
}
|
|
2267
|
-
createAPIContext(props) {
|
|
2268
|
-
const context = this.createActionAPIContext();
|
|
2605
|
+
createAPIContext(props, context) {
|
|
2269
2606
|
const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
|
|
2270
2607
|
Reflect.set(context, apiContextRoutesSymbol, this.pipeline);
|
|
2271
2608
|
return Object.assign(context, {
|
|
@@ -2277,11 +2614,12 @@ class RenderContext {
|
|
|
2277
2614
|
}
|
|
2278
2615
|
async #executeRewrite(reroutePayload) {
|
|
2279
2616
|
this.pipeline.logger.debug("router", "Calling rewrite: ", reroutePayload);
|
|
2617
|
+
const oldPathname = this.pathname;
|
|
2280
2618
|
const { routeData, componentInstance, newUrl, pathname } = await this.pipeline.tryRewrite(
|
|
2281
2619
|
reroutePayload,
|
|
2282
2620
|
this.request
|
|
2283
2621
|
);
|
|
2284
|
-
if (this.pipeline.serverLike
|
|
2622
|
+
if (this.pipeline.serverLike && !this.routeData.prerender && routeData.prerender) {
|
|
2285
2623
|
throw new AstroError({
|
|
2286
2624
|
...ForbiddenRewrite,
|
|
2287
2625
|
message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component),
|
|
@@ -2307,11 +2645,12 @@ class RenderContext {
|
|
|
2307
2645
|
this.pathname = pathname;
|
|
2308
2646
|
this.isRewriting = true;
|
|
2309
2647
|
this.status = 200;
|
|
2648
|
+
setOriginPathname(this.request, oldPathname);
|
|
2310
2649
|
return await this.render(componentInstance);
|
|
2311
2650
|
}
|
|
2312
2651
|
createActionAPIContext() {
|
|
2313
2652
|
const renderContext = this;
|
|
2314
|
-
const { cookies, params, pipeline, url
|
|
2653
|
+
const { cookies, params, pipeline, url } = this;
|
|
2315
2654
|
const generator = `Astro v${ASTRO_VERSION}`;
|
|
2316
2655
|
const rewrite = async (reroutePayload) => {
|
|
2317
2656
|
return await this.#executeRewrite(reroutePayload);
|
|
@@ -2347,10 +2686,56 @@ class RenderContext {
|
|
|
2347
2686
|
get originPathname() {
|
|
2348
2687
|
return getOriginPathname(renderContext.request);
|
|
2349
2688
|
},
|
|
2350
|
-
session
|
|
2689
|
+
get session() {
|
|
2690
|
+
if (this.isPrerendered) {
|
|
2691
|
+
pipeline.logger.warn(
|
|
2692
|
+
"session",
|
|
2693
|
+
`context.session was used when rendering the route ${green(this.routePattern)}, but it is not available on prerendered routes. If you need access to sessions, make sure that the route is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your routes server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/`
|
|
2694
|
+
);
|
|
2695
|
+
return void 0;
|
|
2696
|
+
}
|
|
2697
|
+
if (!renderContext.session) {
|
|
2698
|
+
pipeline.logger.warn(
|
|
2699
|
+
"session",
|
|
2700
|
+
`context.session was used when rendering the route ${green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/`
|
|
2701
|
+
);
|
|
2702
|
+
return void 0;
|
|
2703
|
+
}
|
|
2704
|
+
return renderContext.session;
|
|
2705
|
+
},
|
|
2706
|
+
insertDirective(payload) {
|
|
2707
|
+
if (!pipeline.manifest.csp) {
|
|
2708
|
+
throw new AstroError(CspNotEnabled);
|
|
2709
|
+
}
|
|
2710
|
+
renderContext.result?.directives.push(payload);
|
|
2711
|
+
},
|
|
2712
|
+
insertScriptResource(resource) {
|
|
2713
|
+
if (!pipeline.manifest.csp) {
|
|
2714
|
+
throw new AstroError(CspNotEnabled);
|
|
2715
|
+
}
|
|
2716
|
+
renderContext.result?.scriptResources.push(resource);
|
|
2717
|
+
},
|
|
2718
|
+
insertStyleResource(resource) {
|
|
2719
|
+
if (!pipeline.manifest.csp) {
|
|
2720
|
+
throw new AstroError(CspNotEnabled);
|
|
2721
|
+
}
|
|
2722
|
+
renderContext.result?.styleResources.push(resource);
|
|
2723
|
+
},
|
|
2724
|
+
insertStyleHash(hash) {
|
|
2725
|
+
if (!pipeline.manifest.csp) {
|
|
2726
|
+
throw new AstroError(CspNotEnabled);
|
|
2727
|
+
}
|
|
2728
|
+
renderContext.result?.styleHashes.push(hash);
|
|
2729
|
+
},
|
|
2730
|
+
insertScriptHash(hash) {
|
|
2731
|
+
if (!!pipeline.manifest.csp === false) {
|
|
2732
|
+
throw new AstroError(CspNotEnabled);
|
|
2733
|
+
}
|
|
2734
|
+
renderContext.result?.scriptHashes.push(hash);
|
|
2735
|
+
}
|
|
2351
2736
|
};
|
|
2352
2737
|
}
|
|
2353
|
-
async createResult(mod) {
|
|
2738
|
+
async createResult(mod, ctx) {
|
|
2354
2739
|
const { cookies, pathname, pipeline, routeData, status } = this;
|
|
2355
2740
|
const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline;
|
|
2356
2741
|
const { links, scripts, styles } = await pipeline.headElements(routeData);
|
|
@@ -2379,7 +2764,7 @@ class RenderContext {
|
|
|
2379
2764
|
compressHTML,
|
|
2380
2765
|
cookies,
|
|
2381
2766
|
/** This function returns the `Astro` faux-global */
|
|
2382
|
-
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots),
|
|
2767
|
+
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots, ctx),
|
|
2383
2768
|
links,
|
|
2384
2769
|
params: this.params,
|
|
2385
2770
|
partial,
|
|
@@ -2400,10 +2785,23 @@ class RenderContext {
|
|
|
2400
2785
|
hasRenderedHead: false,
|
|
2401
2786
|
renderedScripts: /* @__PURE__ */ new Set(),
|
|
2402
2787
|
hasDirectives: /* @__PURE__ */ new Set(),
|
|
2788
|
+
hasRenderedServerIslandRuntime: false,
|
|
2403
2789
|
headInTree: false,
|
|
2404
2790
|
extraHead: [],
|
|
2791
|
+
extraStyleHashes: [],
|
|
2792
|
+
extraScriptHashes: [],
|
|
2405
2793
|
propagators: /* @__PURE__ */ new Set()
|
|
2406
|
-
}
|
|
2794
|
+
},
|
|
2795
|
+
cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"),
|
|
2796
|
+
shouldInjectCspMetaTags: !!manifest.csp,
|
|
2797
|
+
cspAlgorithm: manifest.csp?.algorithm ?? "SHA-256",
|
|
2798
|
+
// The following arrays must be cloned, otherwise they become mutable across routes.
|
|
2799
|
+
scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [],
|
|
2800
|
+
scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [],
|
|
2801
|
+
styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [],
|
|
2802
|
+
styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [],
|
|
2803
|
+
directives: manifest.csp?.directives ? [...manifest.csp.directives] : [],
|
|
2804
|
+
isStrictDynamic: manifest.csp?.isStrictDynamic ?? false
|
|
2407
2805
|
};
|
|
2408
2806
|
return result;
|
|
2409
2807
|
}
|
|
@@ -2416,17 +2814,19 @@ class RenderContext {
|
|
|
2416
2814
|
*
|
|
2417
2815
|
* The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component.
|
|
2418
2816
|
*/
|
|
2419
|
-
createAstro(result, astroStaticPartial, props, slotValues) {
|
|
2817
|
+
createAstro(result, astroStaticPartial, props, slotValues, apiContext) {
|
|
2420
2818
|
let astroPagePartial;
|
|
2421
2819
|
if (this.isRewriting) {
|
|
2422
2820
|
astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial(
|
|
2423
2821
|
result,
|
|
2424
|
-
astroStaticPartial
|
|
2822
|
+
astroStaticPartial,
|
|
2823
|
+
apiContext
|
|
2425
2824
|
);
|
|
2426
2825
|
} else {
|
|
2427
2826
|
astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial(
|
|
2428
2827
|
result,
|
|
2429
|
-
astroStaticPartial
|
|
2828
|
+
astroStaticPartial,
|
|
2829
|
+
apiContext
|
|
2430
2830
|
);
|
|
2431
2831
|
}
|
|
2432
2832
|
const astroComponentPartial = { props, self: null };
|
|
@@ -2449,9 +2849,9 @@ class RenderContext {
|
|
|
2449
2849
|
});
|
|
2450
2850
|
return Astro;
|
|
2451
2851
|
}
|
|
2452
|
-
createAstroPagePartial(result, astroStaticPartial) {
|
|
2852
|
+
createAstroPagePartial(result, astroStaticPartial, apiContext) {
|
|
2453
2853
|
const renderContext = this;
|
|
2454
|
-
const { cookies, locals, params, pipeline, url
|
|
2854
|
+
const { cookies, locals, params, pipeline, url } = this;
|
|
2455
2855
|
const { response } = result;
|
|
2456
2856
|
const redirect = (path, status = 302) => {
|
|
2457
2857
|
if (this.request[responseSentSymbol$1]) {
|
|
@@ -2464,13 +2864,30 @@ class RenderContext {
|
|
|
2464
2864
|
const rewrite = async (reroutePayload) => {
|
|
2465
2865
|
return await this.#executeRewrite(reroutePayload);
|
|
2466
2866
|
};
|
|
2867
|
+
const callAction = createCallAction(apiContext);
|
|
2467
2868
|
return {
|
|
2468
2869
|
generator: astroStaticPartial.generator,
|
|
2469
2870
|
glob: astroStaticPartial.glob,
|
|
2470
2871
|
routePattern: this.routeData.route,
|
|
2471
2872
|
isPrerendered: this.routeData.prerender,
|
|
2472
2873
|
cookies,
|
|
2473
|
-
session
|
|
2874
|
+
get session() {
|
|
2875
|
+
if (this.isPrerendered) {
|
|
2876
|
+
pipeline.logger.warn(
|
|
2877
|
+
"session",
|
|
2878
|
+
`Astro.session was used when rendering the route ${green(this.routePattern)}, but it is not available on prerendered pages. If you need access to sessions, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/`
|
|
2879
|
+
);
|
|
2880
|
+
return void 0;
|
|
2881
|
+
}
|
|
2882
|
+
if (!renderContext.session) {
|
|
2883
|
+
pipeline.logger.warn(
|
|
2884
|
+
"session",
|
|
2885
|
+
`Astro.session was used when rendering the route ${green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/`
|
|
2886
|
+
);
|
|
2887
|
+
return void 0;
|
|
2888
|
+
}
|
|
2889
|
+
return renderContext.session;
|
|
2890
|
+
},
|
|
2474
2891
|
get clientAddress() {
|
|
2475
2892
|
return renderContext.getClientAddress();
|
|
2476
2893
|
},
|
|
@@ -2492,18 +2909,51 @@ class RenderContext {
|
|
|
2492
2909
|
site: pipeline.site,
|
|
2493
2910
|
getActionResult: createGetActionResult(locals),
|
|
2494
2911
|
get callAction() {
|
|
2495
|
-
return
|
|
2912
|
+
return callAction;
|
|
2496
2913
|
},
|
|
2497
2914
|
url,
|
|
2498
2915
|
get originPathname() {
|
|
2499
2916
|
return getOriginPathname(renderContext.request);
|
|
2917
|
+
},
|
|
2918
|
+
insertDirective(payload) {
|
|
2919
|
+
if (!pipeline.manifest.csp) {
|
|
2920
|
+
throw new AstroError(CspNotEnabled);
|
|
2921
|
+
}
|
|
2922
|
+
renderContext.result?.directives.push(payload);
|
|
2923
|
+
},
|
|
2924
|
+
insertScriptResource(resource) {
|
|
2925
|
+
if (!pipeline.manifest.csp) {
|
|
2926
|
+
throw new AstroError(CspNotEnabled);
|
|
2927
|
+
}
|
|
2928
|
+
renderContext.result?.scriptResources.push(resource);
|
|
2929
|
+
},
|
|
2930
|
+
insertStyleResource(resource) {
|
|
2931
|
+
if (!pipeline.manifest.csp) {
|
|
2932
|
+
throw new AstroError(CspNotEnabled);
|
|
2933
|
+
}
|
|
2934
|
+
renderContext.result?.styleResources.push(resource);
|
|
2935
|
+
},
|
|
2936
|
+
insertStyleHash(hash) {
|
|
2937
|
+
if (!pipeline.manifest.csp) {
|
|
2938
|
+
throw new AstroError(CspNotEnabled);
|
|
2939
|
+
}
|
|
2940
|
+
renderContext.result?.styleHashes.push(hash);
|
|
2941
|
+
},
|
|
2942
|
+
insertScriptHash(hash) {
|
|
2943
|
+
if (!!pipeline.manifest.csp === false) {
|
|
2944
|
+
throw new AstroError(CspNotEnabled);
|
|
2945
|
+
}
|
|
2946
|
+
renderContext.result?.scriptHashes.push(hash);
|
|
2500
2947
|
}
|
|
2501
2948
|
};
|
|
2502
2949
|
}
|
|
2503
2950
|
getClientAddress() {
|
|
2504
2951
|
const { pipeline, request, routeData, clientAddress } = this;
|
|
2505
2952
|
if (routeData.prerender) {
|
|
2506
|
-
throw new AstroError(
|
|
2953
|
+
throw new AstroError({
|
|
2954
|
+
...PrerenderClientAddressNotAvailable,
|
|
2955
|
+
message: PrerenderClientAddressNotAvailable.message(routeData.component)
|
|
2956
|
+
});
|
|
2507
2957
|
}
|
|
2508
2958
|
if (clientAddress) {
|
|
2509
2959
|
return clientAddress;
|
|
@@ -2581,1041 +3031,69 @@ class RenderContext {
|
|
|
2581
3031
|
}
|
|
2582
3032
|
}
|
|
2583
3033
|
|
|
2584
|
-
function
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
3034
|
+
function sequence(...handlers) {
|
|
3035
|
+
const filtered = handlers.filter((h) => !!h);
|
|
3036
|
+
const length = filtered.length;
|
|
3037
|
+
if (!length) {
|
|
3038
|
+
return defineMiddleware((_context, next) => {
|
|
3039
|
+
return next();
|
|
3040
|
+
});
|
|
2590
3041
|
}
|
|
2591
|
-
return
|
|
3042
|
+
return defineMiddleware((context, next) => {
|
|
3043
|
+
let carriedPayload = void 0;
|
|
3044
|
+
return applyHandle(0, context);
|
|
3045
|
+
function applyHandle(i, handleContext) {
|
|
3046
|
+
const handle = filtered[i];
|
|
3047
|
+
const result = handle(handleContext, async (payload) => {
|
|
3048
|
+
if (i < length - 1) {
|
|
3049
|
+
if (payload) {
|
|
3050
|
+
let newRequest;
|
|
3051
|
+
if (payload instanceof Request) {
|
|
3052
|
+
newRequest = payload;
|
|
3053
|
+
} else if (payload instanceof URL) {
|
|
3054
|
+
newRequest = new Request(payload, handleContext.request.clone());
|
|
3055
|
+
} else {
|
|
3056
|
+
newRequest = new Request(
|
|
3057
|
+
new URL(payload, handleContext.url.origin),
|
|
3058
|
+
handleContext.request.clone()
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
const oldPathname = handleContext.url.pathname;
|
|
3062
|
+
const pipeline = Reflect.get(handleContext, apiContextRoutesSymbol);
|
|
3063
|
+
const { routeData, pathname } = await pipeline.tryRewrite(
|
|
3064
|
+
payload,
|
|
3065
|
+
handleContext.request
|
|
3066
|
+
);
|
|
3067
|
+
if (pipeline.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) {
|
|
3068
|
+
throw new AstroError({
|
|
3069
|
+
...ForbiddenRewrite,
|
|
3070
|
+
message: ForbiddenRewrite.message(
|
|
3071
|
+
handleContext.url.pathname,
|
|
3072
|
+
pathname,
|
|
3073
|
+
routeData.component
|
|
3074
|
+
),
|
|
3075
|
+
hint: ForbiddenRewrite.hint(routeData.component)
|
|
3076
|
+
});
|
|
3077
|
+
}
|
|
3078
|
+
carriedPayload = payload;
|
|
3079
|
+
handleContext.request = newRequest;
|
|
3080
|
+
handleContext.url = new URL(newRequest.url);
|
|
3081
|
+
handleContext.cookies = new AstroCookies(newRequest);
|
|
3082
|
+
handleContext.params = getParams(routeData, pathname);
|
|
3083
|
+
setOriginPathname(handleContext.request, oldPathname);
|
|
3084
|
+
}
|
|
3085
|
+
return applyHandle(i + 1, handleContext);
|
|
3086
|
+
} else {
|
|
3087
|
+
return next(payload ?? carriedPayload);
|
|
3088
|
+
}
|
|
3089
|
+
});
|
|
3090
|
+
return result;
|
|
3091
|
+
}
|
|
3092
|
+
});
|
|
2592
3093
|
}
|
|
2593
3094
|
|
|
2594
|
-
function
|
|
2595
|
-
|
|
2596
|
-
const pf = getAssetsPrefix(fileExtension(href), assetsPrefix);
|
|
2597
|
-
return joinPaths(pf, slash(href));
|
|
2598
|
-
} else if (base) {
|
|
2599
|
-
return prependForwardSlash$1(joinPaths(base, slash(href)));
|
|
2600
|
-
} else {
|
|
2601
|
-
return href;
|
|
2602
|
-
}
|
|
2603
|
-
}
|
|
2604
|
-
function createStylesheetElement(stylesheet, base, assetsPrefix) {
|
|
2605
|
-
if (stylesheet.type === "inline") {
|
|
2606
|
-
return {
|
|
2607
|
-
props: {},
|
|
2608
|
-
children: stylesheet.content
|
|
2609
|
-
};
|
|
2610
|
-
} else {
|
|
2611
|
-
return {
|
|
2612
|
-
props: {
|
|
2613
|
-
rel: "stylesheet",
|
|
2614
|
-
href: createAssetLink(stylesheet.src, base, assetsPrefix)
|
|
2615
|
-
},
|
|
2616
|
-
children: ""
|
|
2617
|
-
};
|
|
2618
|
-
}
|
|
2619
|
-
}
|
|
2620
|
-
function createStylesheetElementSet(stylesheets, base, assetsPrefix) {
|
|
2621
|
-
return new Set(stylesheets.map((s) => createStylesheetElement(s, base, assetsPrefix)));
|
|
2622
|
-
}
|
|
2623
|
-
function createModuleScriptElement(script, base, assetsPrefix) {
|
|
2624
|
-
if (script.type === "external") {
|
|
2625
|
-
return createModuleScriptElementWithSrc(script.value, base, assetsPrefix);
|
|
2626
|
-
} else {
|
|
2627
|
-
return {
|
|
2628
|
-
props: {
|
|
2629
|
-
type: "module"
|
|
2630
|
-
},
|
|
2631
|
-
children: script.value
|
|
2632
|
-
};
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
function createModuleScriptElementWithSrc(src, base, assetsPrefix) {
|
|
2636
|
-
return {
|
|
2637
|
-
props: {
|
|
2638
|
-
type: "module",
|
|
2639
|
-
src: createAssetLink(src, base, assetsPrefix)
|
|
2640
|
-
},
|
|
2641
|
-
children: ""
|
|
2642
|
-
};
|
|
2643
|
-
}
|
|
2644
|
-
|
|
2645
|
-
function redirectTemplate({ status, location, from }) {
|
|
2646
|
-
const delay = status === 302 ? 2 : 0;
|
|
2647
|
-
return `<!doctype html>
|
|
2648
|
-
<title>Redirecting to: ${location}</title>
|
|
2649
|
-
<meta http-equiv="refresh" content="${delay};url=${location}">
|
|
2650
|
-
<meta name="robots" content="noindex">
|
|
2651
|
-
<link rel="canonical" href="${location}">
|
|
2652
|
-
<body>
|
|
2653
|
-
<a href="${location}">Redirecting ${from ? `from <code>${from}</code> ` : ""}to <code>${location}</code></a>
|
|
2654
|
-
</body>`;
|
|
2655
|
-
}
|
|
2656
|
-
|
|
2657
|
-
class AppPipeline extends Pipeline {
|
|
2658
|
-
#manifestData;
|
|
2659
|
-
static create(manifestData, {
|
|
2660
|
-
logger,
|
|
2661
|
-
manifest,
|
|
2662
|
-
runtimeMode,
|
|
2663
|
-
renderers,
|
|
2664
|
-
resolve,
|
|
2665
|
-
serverLike,
|
|
2666
|
-
streaming,
|
|
2667
|
-
defaultRoutes
|
|
2668
|
-
}) {
|
|
2669
|
-
const pipeline = new AppPipeline(
|
|
2670
|
-
logger,
|
|
2671
|
-
manifest,
|
|
2672
|
-
runtimeMode,
|
|
2673
|
-
renderers,
|
|
2674
|
-
resolve,
|
|
2675
|
-
serverLike,
|
|
2676
|
-
streaming,
|
|
2677
|
-
void 0,
|
|
2678
|
-
void 0,
|
|
2679
|
-
void 0,
|
|
2680
|
-
void 0,
|
|
2681
|
-
void 0,
|
|
2682
|
-
void 0,
|
|
2683
|
-
void 0,
|
|
2684
|
-
void 0,
|
|
2685
|
-
defaultRoutes
|
|
2686
|
-
);
|
|
2687
|
-
pipeline.#manifestData = manifestData;
|
|
2688
|
-
return pipeline;
|
|
2689
|
-
}
|
|
2690
|
-
headElements(routeData) {
|
|
2691
|
-
const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData);
|
|
2692
|
-
const links = /* @__PURE__ */ new Set();
|
|
2693
|
-
const scripts = /* @__PURE__ */ new Set();
|
|
2694
|
-
const styles = createStylesheetElementSet(routeInfo?.styles ?? []);
|
|
2695
|
-
for (const script of routeInfo?.scripts ?? []) {
|
|
2696
|
-
if ("stage" in script) {
|
|
2697
|
-
if (script.stage === "head-inline") {
|
|
2698
|
-
scripts.add({
|
|
2699
|
-
props: {},
|
|
2700
|
-
children: script.children
|
|
2701
|
-
});
|
|
2702
|
-
}
|
|
2703
|
-
} else {
|
|
2704
|
-
scripts.add(createModuleScriptElement(script));
|
|
2705
|
-
}
|
|
2706
|
-
}
|
|
2707
|
-
return { links, styles, scripts };
|
|
2708
|
-
}
|
|
2709
|
-
componentMetadata() {
|
|
2710
|
-
}
|
|
2711
|
-
async getComponentByRoute(routeData) {
|
|
2712
|
-
const module = await this.getModuleForRoute(routeData);
|
|
2713
|
-
return module.page();
|
|
2714
|
-
}
|
|
2715
|
-
async tryRewrite(payload, request) {
|
|
2716
|
-
const { newUrl, pathname, routeData } = findRouteToRewrite({
|
|
2717
|
-
payload,
|
|
2718
|
-
request,
|
|
2719
|
-
routes: this.manifest?.routes.map((r) => r.routeData),
|
|
2720
|
-
trailingSlash: this.manifest.trailingSlash,
|
|
2721
|
-
buildFormat: this.manifest.buildFormat,
|
|
2722
|
-
base: this.manifest.base
|
|
2723
|
-
});
|
|
2724
|
-
const componentInstance = await this.getComponentByRoute(routeData);
|
|
2725
|
-
return { newUrl, pathname, componentInstance, routeData };
|
|
2726
|
-
}
|
|
2727
|
-
async getModuleForRoute(route) {
|
|
2728
|
-
for (const defaultRoute of this.defaultRoutes) {
|
|
2729
|
-
if (route.component === defaultRoute.component) {
|
|
2730
|
-
return {
|
|
2731
|
-
page: () => Promise.resolve(defaultRoute.instance),
|
|
2732
|
-
renderers: []
|
|
2733
|
-
};
|
|
2734
|
-
}
|
|
2735
|
-
}
|
|
2736
|
-
if (route.type === "redirect") {
|
|
2737
|
-
return RedirectSinglePageBuiltModule;
|
|
2738
|
-
} else {
|
|
2739
|
-
if (this.manifest.pageMap) {
|
|
2740
|
-
const importComponentInstance = this.manifest.pageMap.get(route.component);
|
|
2741
|
-
if (!importComponentInstance) {
|
|
2742
|
-
throw new Error(
|
|
2743
|
-
`Unexpectedly unable to find a component instance for route ${route.route}`
|
|
2744
|
-
);
|
|
2745
|
-
}
|
|
2746
|
-
return await importComponentInstance();
|
|
2747
|
-
} else if (this.manifest.pageModule) {
|
|
2748
|
-
return this.manifest.pageModule;
|
|
2749
|
-
}
|
|
2750
|
-
throw new Error(
|
|
2751
|
-
"Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue."
|
|
2752
|
-
);
|
|
2753
|
-
}
|
|
2754
|
-
}
|
|
2755
|
-
}
|
|
2756
|
-
|
|
2757
|
-
class App {
|
|
2758
|
-
#manifest;
|
|
2759
|
-
#manifestData;
|
|
2760
|
-
#logger = new Logger({
|
|
2761
|
-
dest: consoleLogDestination,
|
|
2762
|
-
level: "info"
|
|
2763
|
-
});
|
|
2764
|
-
#baseWithoutTrailingSlash;
|
|
2765
|
-
#pipeline;
|
|
2766
|
-
#adapterLogger;
|
|
2767
|
-
#renderOptionsDeprecationWarningShown = false;
|
|
2768
|
-
constructor(manifest, streaming = true) {
|
|
2769
|
-
this.#manifest = manifest;
|
|
2770
|
-
this.#manifestData = {
|
|
2771
|
-
routes: manifest.routes.map((route) => route.routeData)
|
|
2772
|
-
};
|
|
2773
|
-
ensure404Route(this.#manifestData);
|
|
2774
|
-
this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base);
|
|
2775
|
-
this.#pipeline = this.#createPipeline(this.#manifestData, streaming);
|
|
2776
|
-
this.#adapterLogger = new AstroIntegrationLogger(
|
|
2777
|
-
this.#logger.options,
|
|
2778
|
-
this.#manifest.adapterName
|
|
2779
|
-
);
|
|
2780
|
-
}
|
|
2781
|
-
getAdapterLogger() {
|
|
2782
|
-
return this.#adapterLogger;
|
|
2783
|
-
}
|
|
2784
|
-
/**
|
|
2785
|
-
* Creates a pipeline by reading the stored manifest
|
|
2786
|
-
*
|
|
2787
|
-
* @param manifestData
|
|
2788
|
-
* @param streaming
|
|
2789
|
-
* @private
|
|
2790
|
-
*/
|
|
2791
|
-
#createPipeline(manifestData, streaming = false) {
|
|
2792
|
-
return AppPipeline.create(manifestData, {
|
|
2793
|
-
logger: this.#logger,
|
|
2794
|
-
manifest: this.#manifest,
|
|
2795
|
-
runtimeMode: "production",
|
|
2796
|
-
renderers: this.#manifest.renderers,
|
|
2797
|
-
defaultRoutes: createDefaultRoutes(this.#manifest),
|
|
2798
|
-
resolve: async (specifier) => {
|
|
2799
|
-
if (!(specifier in this.#manifest.entryModules)) {
|
|
2800
|
-
throw new Error(`Unable to resolve [${specifier}]`);
|
|
2801
|
-
}
|
|
2802
|
-
const bundlePath = this.#manifest.entryModules[specifier];
|
|
2803
|
-
if (bundlePath.startsWith("data:") || bundlePath.length === 0) {
|
|
2804
|
-
return bundlePath;
|
|
2805
|
-
} else {
|
|
2806
|
-
return createAssetLink(bundlePath, this.#manifest.base, this.#manifest.assetsPrefix);
|
|
2807
|
-
}
|
|
2808
|
-
},
|
|
2809
|
-
serverLike: true,
|
|
2810
|
-
streaming
|
|
2811
|
-
});
|
|
2812
|
-
}
|
|
2813
|
-
set setManifestData(newManifestData) {
|
|
2814
|
-
this.#manifestData = newManifestData;
|
|
2815
|
-
}
|
|
2816
|
-
removeBase(pathname) {
|
|
2817
|
-
if (pathname.startsWith(this.#manifest.base)) {
|
|
2818
|
-
return pathname.slice(this.#baseWithoutTrailingSlash.length + 1);
|
|
2819
|
-
}
|
|
2820
|
-
return pathname;
|
|
2821
|
-
}
|
|
2822
|
-
/**
|
|
2823
|
-
* It removes the base from the request URL, prepends it with a forward slash and attempts to decoded it.
|
|
2824
|
-
*
|
|
2825
|
-
* If the decoding fails, it logs the error and return the pathname as is.
|
|
2826
|
-
* @param request
|
|
2827
|
-
* @private
|
|
2828
|
-
*/
|
|
2829
|
-
#getPathnameFromRequest(request) {
|
|
2830
|
-
const url = new URL(request.url);
|
|
2831
|
-
const pathname = prependForwardSlash$1(this.removeBase(url.pathname));
|
|
2832
|
-
try {
|
|
2833
|
-
return decodeURI(pathname);
|
|
2834
|
-
} catch (e) {
|
|
2835
|
-
this.getAdapterLogger().error(e.toString());
|
|
2836
|
-
return pathname;
|
|
2837
|
-
}
|
|
2838
|
-
}
|
|
2839
|
-
match(request) {
|
|
2840
|
-
const url = new URL(request.url);
|
|
2841
|
-
if (this.#manifest.assets.has(url.pathname)) return void 0;
|
|
2842
|
-
let pathname = this.#computePathnameFromDomain(request);
|
|
2843
|
-
if (!pathname) {
|
|
2844
|
-
pathname = prependForwardSlash$1(this.removeBase(url.pathname));
|
|
2845
|
-
}
|
|
2846
|
-
let routeData = matchRoute(decodeURI(pathname), this.#manifestData);
|
|
2847
|
-
if (!routeData || routeData.prerender) return void 0;
|
|
2848
|
-
return routeData;
|
|
2849
|
-
}
|
|
2850
|
-
#computePathnameFromDomain(request) {
|
|
2851
|
-
let pathname = void 0;
|
|
2852
|
-
const url = new URL(request.url);
|
|
2853
|
-
if (this.#manifest.i18n && (this.#manifest.i18n.strategy === "domains-prefix-always" || this.#manifest.i18n.strategy === "domains-prefix-other-locales" || this.#manifest.i18n.strategy === "domains-prefix-always-no-redirect")) {
|
|
2854
|
-
let host = request.headers.get("X-Forwarded-Host");
|
|
2855
|
-
let protocol = request.headers.get("X-Forwarded-Proto");
|
|
2856
|
-
if (protocol) {
|
|
2857
|
-
protocol = protocol + ":";
|
|
2858
|
-
} else {
|
|
2859
|
-
protocol = url.protocol;
|
|
2860
|
-
}
|
|
2861
|
-
if (!host) {
|
|
2862
|
-
host = request.headers.get("Host");
|
|
2863
|
-
}
|
|
2864
|
-
if (host && protocol) {
|
|
2865
|
-
host = host.split(":")[0];
|
|
2866
|
-
try {
|
|
2867
|
-
let locale;
|
|
2868
|
-
const hostAsUrl = new URL(`${protocol}//${host}`);
|
|
2869
|
-
for (const [domainKey, localeValue] of Object.entries(
|
|
2870
|
-
this.#manifest.i18n.domainLookupTable
|
|
2871
|
-
)) {
|
|
2872
|
-
const domainKeyAsUrl = new URL(domainKey);
|
|
2873
|
-
if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) {
|
|
2874
|
-
locale = localeValue;
|
|
2875
|
-
break;
|
|
2876
|
-
}
|
|
2877
|
-
}
|
|
2878
|
-
if (locale) {
|
|
2879
|
-
pathname = prependForwardSlash$1(
|
|
2880
|
-
joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname))
|
|
2881
|
-
);
|
|
2882
|
-
if (url.pathname.endsWith("/")) {
|
|
2883
|
-
pathname = appendForwardSlash$1(pathname);
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
} catch (e) {
|
|
2887
|
-
this.#logger.error(
|
|
2888
|
-
"router",
|
|
2889
|
-
`Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`
|
|
2890
|
-
);
|
|
2891
|
-
this.#logger.error("router", `Error: ${e}`);
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
}
|
|
2895
|
-
return pathname;
|
|
2896
|
-
}
|
|
2897
|
-
#redirectTrailingSlash(pathname) {
|
|
2898
|
-
const { trailingSlash } = this.#manifest;
|
|
2899
|
-
if (pathname === "/" || pathname.startsWith("/_")) {
|
|
2900
|
-
return pathname;
|
|
2901
|
-
}
|
|
2902
|
-
const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never");
|
|
2903
|
-
if (path !== pathname) {
|
|
2904
|
-
return path;
|
|
2905
|
-
}
|
|
2906
|
-
if (trailingSlash === "ignore") {
|
|
2907
|
-
return pathname;
|
|
2908
|
-
}
|
|
2909
|
-
if (trailingSlash === "always" && !hasFileExtension$1(pathname)) {
|
|
2910
|
-
return appendForwardSlash$1(pathname);
|
|
2911
|
-
}
|
|
2912
|
-
if (trailingSlash === "never") {
|
|
2913
|
-
return removeTrailingForwardSlash(pathname);
|
|
2914
|
-
}
|
|
2915
|
-
return pathname;
|
|
2916
|
-
}
|
|
2917
|
-
async render(request, renderOptions) {
|
|
2918
|
-
let routeData;
|
|
2919
|
-
let locals;
|
|
2920
|
-
let clientAddress;
|
|
2921
|
-
let addCookieHeader;
|
|
2922
|
-
const url = new URL(request.url);
|
|
2923
|
-
const redirect = this.#redirectTrailingSlash(url.pathname);
|
|
2924
|
-
if (redirect !== url.pathname) {
|
|
2925
|
-
const status = request.method === "GET" ? 301 : 308;
|
|
2926
|
-
return new Response(redirectTemplate({ status, location: redirect, from: request.url }), {
|
|
2927
|
-
status,
|
|
2928
|
-
headers: {
|
|
2929
|
-
location: redirect + url.search
|
|
2930
|
-
}
|
|
2931
|
-
});
|
|
2932
|
-
}
|
|
2933
|
-
addCookieHeader = renderOptions?.addCookieHeader;
|
|
2934
|
-
clientAddress = renderOptions?.clientAddress ?? Reflect.get(request, clientAddressSymbol);
|
|
2935
|
-
routeData = renderOptions?.routeData;
|
|
2936
|
-
locals = renderOptions?.locals;
|
|
2937
|
-
if (routeData) {
|
|
2938
|
-
this.#logger.debug(
|
|
2939
|
-
"router",
|
|
2940
|
-
"The adapter " + this.#manifest.adapterName + " provided a custom RouteData for ",
|
|
2941
|
-
request.url
|
|
2942
|
-
);
|
|
2943
|
-
this.#logger.debug("router", "RouteData:\n" + routeData);
|
|
2944
|
-
}
|
|
2945
|
-
if (locals) {
|
|
2946
|
-
if (typeof locals !== "object") {
|
|
2947
|
-
const error = new AstroError(LocalsNotAnObject);
|
|
2948
|
-
this.#logger.error(null, error.stack);
|
|
2949
|
-
return this.#renderError(request, { status: 500, error, clientAddress });
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
if (!routeData) {
|
|
2953
|
-
routeData = this.match(request);
|
|
2954
|
-
this.#logger.debug("router", "Astro matched the following route for " + request.url);
|
|
2955
|
-
this.#logger.debug("router", "RouteData:\n" + routeData);
|
|
2956
|
-
}
|
|
2957
|
-
if (!routeData) {
|
|
2958
|
-
this.#logger.debug("router", "Astro hasn't found routes that match " + request.url);
|
|
2959
|
-
this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData);
|
|
2960
|
-
return this.#renderError(request, { locals, status: 404, clientAddress });
|
|
2961
|
-
}
|
|
2962
|
-
const pathname = this.#getPathnameFromRequest(request);
|
|
2963
|
-
const defaultStatus = this.#getDefaultStatusCode(routeData, pathname);
|
|
2964
|
-
let response;
|
|
2965
|
-
let session;
|
|
2966
|
-
try {
|
|
2967
|
-
const mod = await this.#pipeline.getModuleForRoute(routeData);
|
|
2968
|
-
const renderContext = await RenderContext.create({
|
|
2969
|
-
pipeline: this.#pipeline,
|
|
2970
|
-
locals,
|
|
2971
|
-
pathname,
|
|
2972
|
-
request,
|
|
2973
|
-
routeData,
|
|
2974
|
-
status: defaultStatus,
|
|
2975
|
-
clientAddress
|
|
2976
|
-
});
|
|
2977
|
-
session = renderContext.session;
|
|
2978
|
-
response = await renderContext.render(await mod.page());
|
|
2979
|
-
} catch (err) {
|
|
2980
|
-
this.#logger.error(null, err.stack || err.message || String(err));
|
|
2981
|
-
return this.#renderError(request, { locals, status: 500, error: err, clientAddress });
|
|
2982
|
-
} finally {
|
|
2983
|
-
await session?.[PERSIST_SYMBOL]();
|
|
2984
|
-
}
|
|
2985
|
-
if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
|
|
2986
|
-
return this.#renderError(request, {
|
|
2987
|
-
locals,
|
|
2988
|
-
response,
|
|
2989
|
-
status: response.status,
|
|
2990
|
-
// We don't have an error to report here. Passing null means we pass nothing intentionally
|
|
2991
|
-
// while undefined means there's no error
|
|
2992
|
-
error: response.status === 500 ? null : void 0,
|
|
2993
|
-
clientAddress
|
|
2994
|
-
});
|
|
2995
|
-
}
|
|
2996
|
-
if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) {
|
|
2997
|
-
response.headers.delete(REROUTE_DIRECTIVE_HEADER);
|
|
2998
|
-
}
|
|
2999
|
-
if (addCookieHeader) {
|
|
3000
|
-
for (const setCookieHeaderValue of App.getSetCookieFromResponse(response)) {
|
|
3001
|
-
response.headers.append("set-cookie", setCookieHeaderValue);
|
|
3002
|
-
}
|
|
3003
|
-
}
|
|
3004
|
-
Reflect.set(response, responseSentSymbol$1, true);
|
|
3005
|
-
return response;
|
|
3006
|
-
}
|
|
3007
|
-
setCookieHeaders(response) {
|
|
3008
|
-
return getSetCookiesFromResponse(response);
|
|
3009
|
-
}
|
|
3010
|
-
/**
|
|
3011
|
-
* Reads all the cookies written by `Astro.cookie.set()` onto the passed response.
|
|
3012
|
-
* For example,
|
|
3013
|
-
* ```ts
|
|
3014
|
-
* for (const cookie_ of App.getSetCookieFromResponse(response)) {
|
|
3015
|
-
* const cookie: string = cookie_
|
|
3016
|
-
* }
|
|
3017
|
-
* ```
|
|
3018
|
-
* @param response The response to read cookies from.
|
|
3019
|
-
* @returns An iterator that yields key-value pairs as equal-sign-separated strings.
|
|
3020
|
-
*/
|
|
3021
|
-
static getSetCookieFromResponse = getSetCookiesFromResponse;
|
|
3022
|
-
/**
|
|
3023
|
-
* If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro).
|
|
3024
|
-
* This also handles pre-rendered /404 or /500 routes
|
|
3025
|
-
*/
|
|
3026
|
-
async #renderError(request, {
|
|
3027
|
-
locals,
|
|
3028
|
-
status,
|
|
3029
|
-
response: originalResponse,
|
|
3030
|
-
skipMiddleware = false,
|
|
3031
|
-
error,
|
|
3032
|
-
clientAddress
|
|
3033
|
-
}) {
|
|
3034
|
-
const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`;
|
|
3035
|
-
const errorRouteData = matchRoute(errorRoutePath, this.#manifestData);
|
|
3036
|
-
const url = new URL(request.url);
|
|
3037
|
-
if (errorRouteData) {
|
|
3038
|
-
if (errorRouteData.prerender) {
|
|
3039
|
-
const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : "";
|
|
3040
|
-
const statusURL = new URL(
|
|
3041
|
-
`${this.#baseWithoutTrailingSlash}/${status}${maybeDotHtml}`,
|
|
3042
|
-
url
|
|
3043
|
-
);
|
|
3044
|
-
if (statusURL.toString() !== request.url) {
|
|
3045
|
-
const response2 = await fetch(statusURL.toString());
|
|
3046
|
-
const override = { status };
|
|
3047
|
-
return this.#mergeResponses(response2, originalResponse, override);
|
|
3048
|
-
}
|
|
3049
|
-
}
|
|
3050
|
-
const mod = await this.#pipeline.getModuleForRoute(errorRouteData);
|
|
3051
|
-
let session;
|
|
3052
|
-
try {
|
|
3053
|
-
const renderContext = await RenderContext.create({
|
|
3054
|
-
locals,
|
|
3055
|
-
pipeline: this.#pipeline,
|
|
3056
|
-
middleware: skipMiddleware ? NOOP_MIDDLEWARE_FN : void 0,
|
|
3057
|
-
pathname: this.#getPathnameFromRequest(request),
|
|
3058
|
-
request,
|
|
3059
|
-
routeData: errorRouteData,
|
|
3060
|
-
status,
|
|
3061
|
-
props: { error },
|
|
3062
|
-
clientAddress
|
|
3063
|
-
});
|
|
3064
|
-
session = renderContext.session;
|
|
3065
|
-
const response2 = await renderContext.render(await mod.page());
|
|
3066
|
-
return this.#mergeResponses(response2, originalResponse);
|
|
3067
|
-
} catch {
|
|
3068
|
-
if (skipMiddleware === false) {
|
|
3069
|
-
return this.#renderError(request, {
|
|
3070
|
-
locals,
|
|
3071
|
-
status,
|
|
3072
|
-
response: originalResponse,
|
|
3073
|
-
skipMiddleware: true,
|
|
3074
|
-
clientAddress
|
|
3075
|
-
});
|
|
3076
|
-
}
|
|
3077
|
-
} finally {
|
|
3078
|
-
await session?.[PERSIST_SYMBOL]();
|
|
3079
|
-
}
|
|
3080
|
-
}
|
|
3081
|
-
const response = this.#mergeResponses(new Response(null, { status }), originalResponse);
|
|
3082
|
-
Reflect.set(response, responseSentSymbol$1, true);
|
|
3083
|
-
return response;
|
|
3084
|
-
}
|
|
3085
|
-
#mergeResponses(newResponse, originalResponse, override) {
|
|
3086
|
-
if (!originalResponse) {
|
|
3087
|
-
if (override !== void 0) {
|
|
3088
|
-
return new Response(newResponse.body, {
|
|
3089
|
-
status: override.status,
|
|
3090
|
-
statusText: newResponse.statusText,
|
|
3091
|
-
headers: newResponse.headers
|
|
3092
|
-
});
|
|
3093
|
-
}
|
|
3094
|
-
return newResponse;
|
|
3095
|
-
}
|
|
3096
|
-
const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status;
|
|
3097
|
-
try {
|
|
3098
|
-
originalResponse.headers.delete("Content-type");
|
|
3099
|
-
} catch {
|
|
3100
|
-
}
|
|
3101
|
-
const mergedHeaders = new Map([
|
|
3102
|
-
...Array.from(newResponse.headers),
|
|
3103
|
-
...Array.from(originalResponse.headers)
|
|
3104
|
-
]);
|
|
3105
|
-
const newHeaders = new Headers();
|
|
3106
|
-
for (const [name, value] of mergedHeaders) {
|
|
3107
|
-
newHeaders.set(name, value);
|
|
3108
|
-
}
|
|
3109
|
-
return new Response(newResponse.body, {
|
|
3110
|
-
status,
|
|
3111
|
-
statusText: status === 200 ? newResponse.statusText : originalResponse.statusText,
|
|
3112
|
-
// If you're looking at here for possible bugs, it means that it's not a bug.
|
|
3113
|
-
// With the middleware, users can meddle with headers, and we should pass to the 404/500.
|
|
3114
|
-
// If users see something weird, it's because they are setting some headers they should not.
|
|
3115
|
-
//
|
|
3116
|
-
// Although, we don't want it to replace the content-type, because the error page must return `text/html`
|
|
3117
|
-
headers: newHeaders
|
|
3118
|
-
});
|
|
3119
|
-
}
|
|
3120
|
-
#getDefaultStatusCode(routeData, pathname) {
|
|
3121
|
-
if (!routeData.pattern.test(pathname)) {
|
|
3122
|
-
for (const fallbackRoute of routeData.fallbackRoutes) {
|
|
3123
|
-
if (fallbackRoute.pattern.test(pathname)) {
|
|
3124
|
-
return 302;
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
}
|
|
3128
|
-
const route = removeTrailingForwardSlash(routeData.route);
|
|
3129
|
-
if (route.endsWith("/404")) return 404;
|
|
3130
|
-
if (route.endsWith("/500")) return 500;
|
|
3131
|
-
return 200;
|
|
3132
|
-
}
|
|
3133
|
-
}
|
|
3134
|
-
|
|
3135
|
-
const createOutgoingHttpHeaders = (headers) => {
|
|
3136
|
-
if (!headers) {
|
|
3137
|
-
return void 0;
|
|
3138
|
-
}
|
|
3139
|
-
const nodeHeaders = Object.fromEntries(headers.entries());
|
|
3140
|
-
if (Object.keys(nodeHeaders).length === 0) {
|
|
3141
|
-
return void 0;
|
|
3142
|
-
}
|
|
3143
|
-
if (headers.has("set-cookie")) {
|
|
3144
|
-
const cookieHeaders = headers.getSetCookie();
|
|
3145
|
-
if (cookieHeaders.length > 1) {
|
|
3146
|
-
nodeHeaders["set-cookie"] = cookieHeaders;
|
|
3147
|
-
}
|
|
3148
|
-
}
|
|
3149
|
-
return nodeHeaders;
|
|
3150
|
-
};
|
|
3151
|
-
|
|
3152
|
-
function apply() {
|
|
3153
|
-
if (!globalThis.crypto) {
|
|
3154
|
-
Object.defineProperty(globalThis, "crypto", {
|
|
3155
|
-
value: crypto$1.webcrypto
|
|
3156
|
-
});
|
|
3157
|
-
}
|
|
3158
|
-
if (!globalThis.File) {
|
|
3159
|
-
Object.defineProperty(globalThis, "File", {
|
|
3160
|
-
value: buffer.File
|
|
3161
|
-
});
|
|
3162
|
-
}
|
|
3163
|
-
}
|
|
3164
|
-
|
|
3165
|
-
class NodeApp extends App {
|
|
3166
|
-
match(req) {
|
|
3167
|
-
if (!(req instanceof Request)) {
|
|
3168
|
-
req = NodeApp.createRequest(req, {
|
|
3169
|
-
skipBody: true
|
|
3170
|
-
});
|
|
3171
|
-
}
|
|
3172
|
-
return super.match(req);
|
|
3173
|
-
}
|
|
3174
|
-
render(req, routeDataOrOptions, maybeLocals) {
|
|
3175
|
-
if (!(req instanceof Request)) {
|
|
3176
|
-
req = NodeApp.createRequest(req);
|
|
3177
|
-
}
|
|
3178
|
-
return super.render(req, routeDataOrOptions, maybeLocals);
|
|
3179
|
-
}
|
|
3180
|
-
/**
|
|
3181
|
-
* Converts a NodeJS IncomingMessage into a web standard Request.
|
|
3182
|
-
* ```js
|
|
3183
|
-
* import { NodeApp } from 'astro/app/node';
|
|
3184
|
-
* import { createServer } from 'node:http';
|
|
3185
|
-
*
|
|
3186
|
-
* const server = createServer(async (req, res) => {
|
|
3187
|
-
* const request = NodeApp.createRequest(req);
|
|
3188
|
-
* const response = await app.render(request);
|
|
3189
|
-
* await NodeApp.writeResponse(response, res);
|
|
3190
|
-
* })
|
|
3191
|
-
* ```
|
|
3192
|
-
*/
|
|
3193
|
-
static createRequest(req, { skipBody = false } = {}) {
|
|
3194
|
-
const isEncrypted = "encrypted" in req.socket && req.socket.encrypted;
|
|
3195
|
-
const getFirstForwardedValue = (multiValueHeader) => {
|
|
3196
|
-
return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0];
|
|
3197
|
-
};
|
|
3198
|
-
const forwardedProtocol = getFirstForwardedValue(req.headers["x-forwarded-proto"]);
|
|
3199
|
-
const protocol = forwardedProtocol ?? (isEncrypted ? "https" : "http");
|
|
3200
|
-
const forwardedHostname = getFirstForwardedValue(req.headers["x-forwarded-host"]);
|
|
3201
|
-
const hostname = forwardedHostname ?? req.headers.host ?? req.headers[":authority"];
|
|
3202
|
-
const port = getFirstForwardedValue(req.headers["x-forwarded-port"]);
|
|
3203
|
-
const portInHostname = typeof hostname === "string" && /:\d+$/.test(hostname);
|
|
3204
|
-
const hostnamePort = portInHostname ? hostname : `${hostname}${port ? `:${port}` : ""}`;
|
|
3205
|
-
const url = `${protocol}://${hostnamePort}${req.url}`;
|
|
3206
|
-
const options = {
|
|
3207
|
-
method: req.method || "GET",
|
|
3208
|
-
headers: makeRequestHeaders(req)
|
|
3209
|
-
};
|
|
3210
|
-
const bodyAllowed = options.method !== "HEAD" && options.method !== "GET" && skipBody === false;
|
|
3211
|
-
if (bodyAllowed) {
|
|
3212
|
-
Object.assign(options, makeRequestBody(req));
|
|
3213
|
-
}
|
|
3214
|
-
const request = new Request(url, options);
|
|
3215
|
-
const forwardedClientIp = getFirstForwardedValue(req.headers["x-forwarded-for"]);
|
|
3216
|
-
const clientIp = forwardedClientIp || req.socket?.remoteAddress;
|
|
3217
|
-
if (clientIp) {
|
|
3218
|
-
Reflect.set(request, clientAddressSymbol, clientIp);
|
|
3219
|
-
}
|
|
3220
|
-
return request;
|
|
3221
|
-
}
|
|
3222
|
-
/**
|
|
3223
|
-
* Streams a web-standard Response into a NodeJS Server Response.
|
|
3224
|
-
* ```js
|
|
3225
|
-
* import { NodeApp } from 'astro/app/node';
|
|
3226
|
-
* import { createServer } from 'node:http';
|
|
3227
|
-
*
|
|
3228
|
-
* const server = createServer(async (req, res) => {
|
|
3229
|
-
* const request = NodeApp.createRequest(req);
|
|
3230
|
-
* const response = await app.render(request);
|
|
3231
|
-
* await NodeApp.writeResponse(response, res);
|
|
3232
|
-
* })
|
|
3233
|
-
* ```
|
|
3234
|
-
* @param source WhatWG Response
|
|
3235
|
-
* @param destination NodeJS ServerResponse
|
|
3236
|
-
*/
|
|
3237
|
-
static async writeResponse(source, destination) {
|
|
3238
|
-
const { status, headers, body, statusText } = source;
|
|
3239
|
-
if (!(destination instanceof Http2ServerResponse)) {
|
|
3240
|
-
destination.statusMessage = statusText;
|
|
3241
|
-
}
|
|
3242
|
-
destination.writeHead(status, createOutgoingHttpHeaders(headers));
|
|
3243
|
-
if (!body) return destination.end();
|
|
3244
|
-
try {
|
|
3245
|
-
const reader = body.getReader();
|
|
3246
|
-
destination.on("close", () => {
|
|
3247
|
-
reader.cancel().catch((err) => {
|
|
3248
|
-
console.error(
|
|
3249
|
-
`There was an uncaught error in the middle of the stream while rendering ${destination.req.url}.`,
|
|
3250
|
-
err
|
|
3251
|
-
);
|
|
3252
|
-
});
|
|
3253
|
-
});
|
|
3254
|
-
let result = await reader.read();
|
|
3255
|
-
while (!result.done) {
|
|
3256
|
-
destination.write(result.value);
|
|
3257
|
-
result = await reader.read();
|
|
3258
|
-
}
|
|
3259
|
-
destination.end();
|
|
3260
|
-
} catch (err) {
|
|
3261
|
-
destination.write("Internal server error", () => {
|
|
3262
|
-
err instanceof Error ? destination.destroy(err) : destination.destroy();
|
|
3263
|
-
});
|
|
3264
|
-
}
|
|
3265
|
-
}
|
|
3266
|
-
}
|
|
3267
|
-
function makeRequestHeaders(req) {
|
|
3268
|
-
const headers = new Headers();
|
|
3269
|
-
for (const [name, value] of Object.entries(req.headers)) {
|
|
3270
|
-
if (value === void 0) {
|
|
3271
|
-
continue;
|
|
3272
|
-
}
|
|
3273
|
-
if (Array.isArray(value)) {
|
|
3274
|
-
for (const item of value) {
|
|
3275
|
-
headers.append(name, item);
|
|
3276
|
-
}
|
|
3277
|
-
} else {
|
|
3278
|
-
headers.append(name, value);
|
|
3279
|
-
}
|
|
3280
|
-
}
|
|
3281
|
-
return headers;
|
|
3282
|
-
}
|
|
3283
|
-
function makeRequestBody(req) {
|
|
3284
|
-
if (req.body !== void 0) {
|
|
3285
|
-
if (typeof req.body === "string" && req.body.length > 0) {
|
|
3286
|
-
return { body: Buffer.from(req.body) };
|
|
3287
|
-
}
|
|
3288
|
-
if (typeof req.body === "object" && req.body !== null && Object.keys(req.body).length > 0) {
|
|
3289
|
-
return { body: Buffer.from(JSON.stringify(req.body)) };
|
|
3290
|
-
}
|
|
3291
|
-
if (typeof req.body === "object" && req.body !== null && typeof req.body[Symbol.asyncIterator] !== "undefined") {
|
|
3292
|
-
return asyncIterableToBodyProps(req.body);
|
|
3293
|
-
}
|
|
3294
|
-
}
|
|
3295
|
-
return asyncIterableToBodyProps(req);
|
|
3296
|
-
}
|
|
3297
|
-
function asyncIterableToBodyProps(iterable) {
|
|
3298
|
-
return {
|
|
3299
|
-
// Node uses undici for the Request implementation. Undici accepts
|
|
3300
|
-
// a non-standard async iterable for the body.
|
|
3301
|
-
// @ts-expect-error
|
|
3302
|
-
body: iterable,
|
|
3303
|
-
// The duplex property is required when using a ReadableStream or async
|
|
3304
|
-
// iterable for the body. The type definitions do not include the duplex
|
|
3305
|
-
// property because they are not up-to-date.
|
|
3306
|
-
duplex: "half"
|
|
3307
|
-
};
|
|
3308
|
-
}
|
|
3309
|
-
|
|
3310
|
-
apply();
|
|
3311
|
-
|
|
3312
|
-
function createAppHandler(app) {
|
|
3313
|
-
const als = new AsyncLocalStorage();
|
|
3314
|
-
const logger = app.getAdapterLogger();
|
|
3315
|
-
process.on("unhandledRejection", (reason) => {
|
|
3316
|
-
const requestUrl = als.getStore();
|
|
3317
|
-
logger.error(`Unhandled rejection while rendering ${requestUrl}`);
|
|
3318
|
-
console.error(reason);
|
|
3319
|
-
});
|
|
3320
|
-
return async (req, res, next, locals) => {
|
|
3321
|
-
let request;
|
|
3322
|
-
try {
|
|
3323
|
-
request = NodeApp.createRequest(req);
|
|
3324
|
-
} catch (err) {
|
|
3325
|
-
logger.error(`Could not render ${req.url}`);
|
|
3326
|
-
console.error(err);
|
|
3327
|
-
res.statusCode = 500;
|
|
3328
|
-
res.end("Internal Server Error");
|
|
3329
|
-
return;
|
|
3330
|
-
}
|
|
3331
|
-
const routeData = app.match(request);
|
|
3332
|
-
if (routeData) {
|
|
3333
|
-
const response = await als.run(
|
|
3334
|
-
request.url,
|
|
3335
|
-
() => app.render(request, {
|
|
3336
|
-
addCookieHeader: true,
|
|
3337
|
-
locals,
|
|
3338
|
-
routeData
|
|
3339
|
-
})
|
|
3340
|
-
);
|
|
3341
|
-
await NodeApp.writeResponse(response, res);
|
|
3342
|
-
} else if (next) {
|
|
3343
|
-
return next();
|
|
3344
|
-
} else {
|
|
3345
|
-
const response = await app.render(req);
|
|
3346
|
-
await NodeApp.writeResponse(response, res);
|
|
3347
|
-
}
|
|
3348
|
-
};
|
|
3349
|
-
}
|
|
3350
|
-
|
|
3351
|
-
function createMiddleware(app) {
|
|
3352
|
-
const handler = createAppHandler(app);
|
|
3353
|
-
const logger = app.getAdapterLogger();
|
|
3354
|
-
return async (...args) => {
|
|
3355
|
-
const [req, res, next, locals] = args;
|
|
3356
|
-
if (req instanceof Error) {
|
|
3357
|
-
const error = req;
|
|
3358
|
-
if (next) {
|
|
3359
|
-
return next(error);
|
|
3360
|
-
} else {
|
|
3361
|
-
throw error;
|
|
3362
|
-
}
|
|
3363
|
-
}
|
|
3364
|
-
try {
|
|
3365
|
-
await handler(req, res, next, locals);
|
|
3366
|
-
} catch (err) {
|
|
3367
|
-
logger.error(`Could not render ${req.url}`);
|
|
3368
|
-
console.error(err);
|
|
3369
|
-
if (!res.headersSent) {
|
|
3370
|
-
res.writeHead(500, `Server error`);
|
|
3371
|
-
res.end();
|
|
3372
|
-
}
|
|
3373
|
-
}
|
|
3374
|
-
};
|
|
3375
|
-
}
|
|
3376
|
-
|
|
3377
|
-
const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]);
|
|
3378
|
-
async function logListeningOn(logger, server, configuredHost) {
|
|
3379
|
-
await new Promise((resolve) => server.once("listening", resolve));
|
|
3380
|
-
const protocol = server instanceof https.Server ? "https" : "http";
|
|
3381
|
-
const host = getResolvedHostForHttpServer(configuredHost);
|
|
3382
|
-
const { port } = server.address();
|
|
3383
|
-
const address = getNetworkAddress(protocol, host, port);
|
|
3384
|
-
if (host === void 0 || wildcardHosts.has(host)) {
|
|
3385
|
-
logger.info(
|
|
3386
|
-
`Server listening on
|
|
3387
|
-
local: ${address.local[0]}
|
|
3388
|
-
network: ${address.network[0]}
|
|
3389
|
-
`
|
|
3390
|
-
);
|
|
3391
|
-
} else {
|
|
3392
|
-
logger.info(`Server listening on ${address.local[0]}`);
|
|
3393
|
-
}
|
|
3394
|
-
}
|
|
3395
|
-
function getResolvedHostForHttpServer(host) {
|
|
3396
|
-
if (host === false) {
|
|
3397
|
-
return "localhost";
|
|
3398
|
-
} else if (host === true) {
|
|
3399
|
-
return void 0;
|
|
3400
|
-
} else {
|
|
3401
|
-
return host;
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
|
-
function getNetworkAddress(protocol = "http", hostname, port, base) {
|
|
3405
|
-
const NetworkAddress = {
|
|
3406
|
-
local: [],
|
|
3407
|
-
network: []
|
|
3408
|
-
};
|
|
3409
|
-
Object.values(os.networkInterfaces()).flatMap((nInterface) => nInterface ?? []).filter(
|
|
3410
|
-
(detail) => detail && detail.address && (detail.family === "IPv4" || // @ts-expect-error Node 18.0 - 18.3 returns number
|
|
3411
|
-
detail.family === 4)
|
|
3412
|
-
).forEach((detail) => {
|
|
3413
|
-
let host = detail.address.replace(
|
|
3414
|
-
"127.0.0.1",
|
|
3415
|
-
hostname === void 0 || wildcardHosts.has(hostname) ? "localhost" : hostname
|
|
3416
|
-
);
|
|
3417
|
-
if (host.includes(":")) {
|
|
3418
|
-
host = `[${host}]`;
|
|
3419
|
-
}
|
|
3420
|
-
const url = `${protocol}://${host}:${port}${""}`;
|
|
3421
|
-
if (detail.address.includes("127.0.0.1")) {
|
|
3422
|
-
NetworkAddress.local.push(url);
|
|
3423
|
-
} else {
|
|
3424
|
-
NetworkAddress.network.push(url);
|
|
3425
|
-
}
|
|
3426
|
-
});
|
|
3427
|
-
return NetworkAddress;
|
|
3428
|
-
}
|
|
3429
|
-
|
|
3430
|
-
const WITH_FILE_EXT = /\/[^/]+\.\w+$/;
|
|
3431
|
-
function hasFileExtension(path) {
|
|
3432
|
-
return WITH_FILE_EXT.test(path);
|
|
3433
|
-
}
|
|
3434
|
-
|
|
3435
|
-
function createStaticHandler(app, options) {
|
|
3436
|
-
const client = resolveClientDir(options);
|
|
3437
|
-
return (req, res, ssr) => {
|
|
3438
|
-
if (req.url) {
|
|
3439
|
-
const [urlPath, urlQuery] = req.url.split("?");
|
|
3440
|
-
const filePath = path.join(client, app.removeBase(urlPath));
|
|
3441
|
-
let isDirectory = false;
|
|
3442
|
-
try {
|
|
3443
|
-
isDirectory = fs.lstatSync(filePath).isDirectory();
|
|
3444
|
-
} catch {
|
|
3445
|
-
}
|
|
3446
|
-
const { trailingSlash = "ignore" } = options;
|
|
3447
|
-
const hasSlash = urlPath.endsWith("/");
|
|
3448
|
-
let pathname = urlPath;
|
|
3449
|
-
switch (trailingSlash) {
|
|
3450
|
-
case "never": {
|
|
3451
|
-
if (isDirectory && urlPath !== "/" && hasSlash) {
|
|
3452
|
-
pathname = urlPath.slice(0, -1) + (urlQuery ? "?" + urlQuery : "");
|
|
3453
|
-
res.statusCode = 301;
|
|
3454
|
-
res.setHeader("Location", pathname);
|
|
3455
|
-
return res.end();
|
|
3456
|
-
}
|
|
3457
|
-
if (isDirectory && !hasSlash) {
|
|
3458
|
-
pathname = `${urlPath}/index.html`;
|
|
3459
|
-
}
|
|
3460
|
-
break;
|
|
3461
|
-
}
|
|
3462
|
-
case "ignore": {
|
|
3463
|
-
if (isDirectory && !hasSlash) {
|
|
3464
|
-
pathname = `${urlPath}/index.html`;
|
|
3465
|
-
}
|
|
3466
|
-
break;
|
|
3467
|
-
}
|
|
3468
|
-
case "always": {
|
|
3469
|
-
if (!hasSlash && !hasFileExtension(urlPath)) {
|
|
3470
|
-
pathname = urlPath + "/" + (urlQuery ? "?" + urlQuery : "");
|
|
3471
|
-
res.statusCode = 301;
|
|
3472
|
-
res.setHeader("Location", pathname);
|
|
3473
|
-
return res.end();
|
|
3474
|
-
}
|
|
3475
|
-
break;
|
|
3476
|
-
}
|
|
3477
|
-
}
|
|
3478
|
-
pathname = prependForwardSlash(app.removeBase(pathname));
|
|
3479
|
-
const stream = send(req, pathname, {
|
|
3480
|
-
root: client,
|
|
3481
|
-
dotfiles: pathname.startsWith("/.well-known/") ? "allow" : "deny"
|
|
3482
|
-
});
|
|
3483
|
-
let forwardError = false;
|
|
3484
|
-
stream.on("error", (err) => {
|
|
3485
|
-
if (forwardError) {
|
|
3486
|
-
console.error(err.toString());
|
|
3487
|
-
res.writeHead(500);
|
|
3488
|
-
res.end("Internal server error");
|
|
3489
|
-
return;
|
|
3490
|
-
}
|
|
3491
|
-
ssr();
|
|
3492
|
-
});
|
|
3493
|
-
stream.on("headers", (_res) => {
|
|
3494
|
-
if (pathname.startsWith(`/${options.assets}/`)) {
|
|
3495
|
-
_res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
3496
|
-
}
|
|
3497
|
-
});
|
|
3498
|
-
stream.on("file", () => {
|
|
3499
|
-
forwardError = true;
|
|
3500
|
-
});
|
|
3501
|
-
stream.pipe(res);
|
|
3502
|
-
} else {
|
|
3503
|
-
ssr();
|
|
3504
|
-
}
|
|
3505
|
-
};
|
|
3506
|
-
}
|
|
3507
|
-
function resolveClientDir(options) {
|
|
3508
|
-
const clientURLRaw = new URL(options.client);
|
|
3509
|
-
const serverURLRaw = new URL(options.server);
|
|
3510
|
-
const rel = path.relative(url.fileURLToPath(serverURLRaw), url.fileURLToPath(clientURLRaw));
|
|
3511
|
-
const serverFolder = path.basename(options.server);
|
|
3512
|
-
let serverEntryFolderURL = path.dirname(import.meta.url);
|
|
3513
|
-
while (!serverEntryFolderURL.endsWith(serverFolder)) {
|
|
3514
|
-
serverEntryFolderURL = path.dirname(serverEntryFolderURL);
|
|
3515
|
-
}
|
|
3516
|
-
const serverEntryURL = serverEntryFolderURL + "/entry.mjs";
|
|
3517
|
-
const clientURL = new URL(appendForwardSlash(rel), serverEntryURL);
|
|
3518
|
-
const client = url.fileURLToPath(clientURL);
|
|
3519
|
-
return client;
|
|
3520
|
-
}
|
|
3521
|
-
function prependForwardSlash(pth) {
|
|
3522
|
-
return pth.startsWith("/") ? pth : "/" + pth;
|
|
3523
|
-
}
|
|
3524
|
-
function appendForwardSlash(pth) {
|
|
3525
|
-
return pth.endsWith("/") ? pth : pth + "/";
|
|
3526
|
-
}
|
|
3527
|
-
|
|
3528
|
-
const hostOptions = (host) => {
|
|
3529
|
-
if (typeof host === "boolean") {
|
|
3530
|
-
return host ? "0.0.0.0" : "localhost";
|
|
3531
|
-
}
|
|
3532
|
-
return host;
|
|
3533
|
-
};
|
|
3534
|
-
function standalone(app, options) {
|
|
3535
|
-
const port = process.env.PORT ? Number(process.env.PORT) : options.port ?? 8080;
|
|
3536
|
-
const host = process.env.HOST ?? hostOptions(options.host);
|
|
3537
|
-
const handler = createStandaloneHandler(app, options);
|
|
3538
|
-
const server = createServer(handler, host, port);
|
|
3539
|
-
server.server.listen(port, host);
|
|
3540
|
-
if (process.env.ASTRO_NODE_LOGGING !== "disabled") {
|
|
3541
|
-
logListeningOn(app.getAdapterLogger(), server.server, host);
|
|
3542
|
-
}
|
|
3543
|
-
return {
|
|
3544
|
-
server,
|
|
3545
|
-
done: server.closed()
|
|
3546
|
-
};
|
|
3547
|
-
}
|
|
3548
|
-
function createStandaloneHandler(app, options) {
|
|
3549
|
-
const appHandler = createAppHandler(app);
|
|
3550
|
-
const staticHandler = createStaticHandler(app, options);
|
|
3551
|
-
return (req, res) => {
|
|
3552
|
-
try {
|
|
3553
|
-
decodeURI(req.url);
|
|
3554
|
-
} catch {
|
|
3555
|
-
res.writeHead(400);
|
|
3556
|
-
res.end("Bad request.");
|
|
3557
|
-
return;
|
|
3558
|
-
}
|
|
3559
|
-
staticHandler(req, res, () => appHandler(req, res));
|
|
3560
|
-
};
|
|
3561
|
-
}
|
|
3562
|
-
function createServer(listener, host, port) {
|
|
3563
|
-
let httpServer;
|
|
3564
|
-
if (process.env.SERVER_CERT_PATH && process.env.SERVER_KEY_PATH) {
|
|
3565
|
-
httpServer = https.createServer(
|
|
3566
|
-
{
|
|
3567
|
-
key: fs.readFileSync(process.env.SERVER_KEY_PATH),
|
|
3568
|
-
cert: fs.readFileSync(process.env.SERVER_CERT_PATH)
|
|
3569
|
-
},
|
|
3570
|
-
listener
|
|
3571
|
-
);
|
|
3572
|
-
} else {
|
|
3573
|
-
httpServer = http.createServer(listener);
|
|
3574
|
-
}
|
|
3575
|
-
enableDestroy(httpServer);
|
|
3576
|
-
const closed = new Promise((resolve, reject) => {
|
|
3577
|
-
httpServer.addListener("close", resolve);
|
|
3578
|
-
httpServer.addListener("error", reject);
|
|
3579
|
-
});
|
|
3580
|
-
const previewable = {
|
|
3581
|
-
host,
|
|
3582
|
-
port,
|
|
3583
|
-
closed() {
|
|
3584
|
-
return closed;
|
|
3585
|
-
},
|
|
3586
|
-
async stop() {
|
|
3587
|
-
await new Promise((resolve, reject) => {
|
|
3588
|
-
httpServer.destroy((err) => err ? reject(err) : resolve(void 0));
|
|
3589
|
-
});
|
|
3590
|
-
}
|
|
3591
|
-
};
|
|
3592
|
-
return {
|
|
3593
|
-
server: httpServer,
|
|
3594
|
-
...previewable
|
|
3595
|
-
};
|
|
3596
|
-
}
|
|
3597
|
-
|
|
3598
|
-
function createExports(manifest, options) {
|
|
3599
|
-
const app = new NodeApp(manifest);
|
|
3600
|
-
options.trailingSlash = manifest.trailingSlash;
|
|
3601
|
-
return {
|
|
3602
|
-
options,
|
|
3603
|
-
handler: options.mode === "middleware" ? createMiddleware(app) : createStandaloneHandler(app, options),
|
|
3604
|
-
startServer: () => standalone(app, options)
|
|
3605
|
-
};
|
|
3606
|
-
}
|
|
3607
|
-
function start(manifest, options) {
|
|
3608
|
-
if (options.mode !== "standalone" || process.env.ASTRO_NODE_AUTOSTART === "disabled") {
|
|
3609
|
-
return;
|
|
3610
|
-
}
|
|
3611
|
-
const app = new NodeApp(manifest);
|
|
3612
|
-
standalone(app, options);
|
|
3095
|
+
function defineMiddleware(fn) {
|
|
3096
|
+
return fn;
|
|
3613
3097
|
}
|
|
3614
3098
|
|
|
3615
|
-
|
|
3616
|
-
__proto__: null,
|
|
3617
|
-
createExports,
|
|
3618
|
-
start
|
|
3619
|
-
}, Symbol.toStringTag, { value: 'Module' }));
|
|
3620
|
-
|
|
3621
|
-
export { start as a, createExports as c, serverEntrypointModule as s };
|
|
3099
|
+
export { PERSIST_SYMBOL as P, RouteCache as R, SERVER_ISLAND_COMPONENT as S, redirectToFallback as a, redirectToDefaultLocale as b, requestHasLocale as c, normalizeTheLocale as d, defineMiddleware as e, SERVER_ISLAND_ROUTE as f, createEndpoint as g, findRouteToRewrite as h, isRequestServerIsland as i, RenderContext as j, getSetCookiesFromResponse as k, matchRoute as m, notFound as n, requestIs404Or500 as r, sequence as s };
|