astro 2.8.5 → 2.9.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/client-base.d.ts +9 -0
- package/components/ViewTransitions.astro +157 -0
- package/components/index.ts +1 -0
- package/components/viewtransitions.css +44 -0
- package/dist/@types/astro.d.ts +28 -10
- package/dist/assets/services/vendor/squoosh/impl.js +1 -1
- package/dist/content/runtime.js +1 -1
- package/dist/content/vite-plugin-content-assets.js +2 -2
- package/dist/core/app/index.js +115 -95
- package/dist/core/build/generate.js +18 -33
- package/dist/core/build/graph.js +1 -1
- package/dist/core/build/plugins/plugin-analyzer.js +101 -3
- package/dist/core/build/plugins/plugin-css.js +1 -1
- package/dist/core/build/types.d.ts +1 -1
- package/dist/core/compile/compile.js +2 -0
- package/dist/core/config/config.js +3 -5
- package/dist/core/config/schema.d.ts +85 -48
- package/dist/core/config/schema.js +36 -10
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +4 -2
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/endpoint/dev/index.d.ts +2 -11
- package/dist/core/endpoint/index.d.ts +2 -3
- package/dist/core/endpoint/index.js +1 -11
- package/dist/core/errors/index.d.ts +1 -1
- package/dist/core/errors/index.js +3 -3
- package/dist/core/messages.js +2 -2
- package/dist/core/middleware/index.d.ts +1 -1
- package/dist/core/render/core.d.ts +9 -3
- package/dist/core/render/core.js +42 -18
- package/dist/core/render/environment.d.ts +7 -2
- package/dist/core/render/index.d.ts +22 -1
- package/dist/core/render/index.js +2 -2
- package/dist/core/render/route-cache.js +1 -1
- package/dist/core/routing/validation.d.ts +2 -3
- package/dist/core/routing/validation.js +0 -9
- package/dist/jsx-runtime/index.d.ts +1 -1
- package/dist/prerender/routing.d.ts +1 -1
- package/dist/prerender/routing.js +1 -1
- package/dist/runtime/server/astro-component.d.ts +1 -1
- package/dist/runtime/server/astro-component.js +5 -5
- package/dist/runtime/server/index.d.ts +2 -1
- package/dist/runtime/server/index.js +3 -1
- package/dist/runtime/server/jsx.js +1 -1
- package/dist/runtime/server/render/component.js +1 -1
- package/dist/runtime/server/render/page.js +1 -1
- package/dist/runtime/server/transition.d.ts +2 -0
- package/dist/runtime/server/transition.js +133 -0
- package/dist/transitions/index.d.ts +7 -0
- package/dist/transitions/index.js +67 -0
- package/dist/transitions/vite-plugin-transitions.d.ts +5 -0
- package/dist/transitions/vite-plugin-transitions.js +36 -0
- package/dist/{core/render/dev → vite-plugin-astro-server}/css.d.ts +2 -2
- package/dist/{core/render/dev → vite-plugin-astro-server}/css.js +1 -1
- package/dist/vite-plugin-astro-server/environment.d.ts +5 -0
- package/dist/{core/render/dev → vite-plugin-astro-server}/environment.js +3 -3
- package/dist/vite-plugin-astro-server/index.d.ts +6 -0
- package/dist/vite-plugin-astro-server/index.js +21 -0
- package/dist/{core/render/dev → vite-plugin-astro-server}/metadata.d.ts +2 -2
- package/dist/{core/render/dev → vite-plugin-astro-server}/metadata.js +2 -2
- package/dist/vite-plugin-astro-server/plugin.js +1 -1
- package/dist/vite-plugin-astro-server/request.d.ts +1 -1
- package/dist/{core/render/dev → vite-plugin-astro-server}/resolve.d.ts +1 -1
- package/dist/{core/render/dev → vite-plugin-astro-server}/resolve.js +1 -1
- package/dist/vite-plugin-astro-server/route.d.ts +1 -1
- package/dist/vite-plugin-astro-server/route.js +93 -20
- package/dist/vite-plugin-astro-server/scripts.d.ts +3 -0
- package/dist/{core/render/dev → vite-plugin-astro-server}/scripts.js +2 -2
- package/dist/{core/render/dev → vite-plugin-astro-server}/vite.d.ts +1 -1
- package/dist/{core/render/dev → vite-plugin-astro-server}/vite.js +2 -2
- package/dist/vite-plugin-scanner/index.d.ts +6 -3
- package/dist/vite-plugin-scanner/index.js +21 -4
- package/dist/vite-plugin-scanner/scan.d.ts +2 -1
- package/dist/vite-plugin-scanner/scan.js +6 -2
- package/package.json +6 -3
- package/dist/core/render/dev/environment.d.ts +0 -9
- package/dist/core/render/dev/index.d.ts +0 -27
- package/dist/core/render/dev/index.js +0 -112
- package/dist/core/render/dev/scripts.d.ts +0 -3
- /package/dist/{core/render/dev → vite-plugin-astro-server}/util.d.ts +0 -0
- /package/dist/{core/render/dev → vite-plugin-astro-server}/util.js +0 -0
package/client-base.d.ts
CHANGED
|
@@ -70,6 +70,15 @@ declare module 'astro:assets' {
|
|
|
70
70
|
export const { getImage, getConfiguredImageService, Image }: AstroAssets;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
declare module 'astro:transitions' {
|
|
74
|
+
type TransitionModule = typeof import('./dist/transitions/index.js');
|
|
75
|
+
export const slide: TransitionModule['slide'];
|
|
76
|
+
export const fade: TransitionModule['fade'];
|
|
77
|
+
|
|
78
|
+
type ViewTransitionsModule = typeof import('./components/ViewTransitions.astro');
|
|
79
|
+
export const ViewTransitions: ViewTransitionsModule['default'];
|
|
80
|
+
}
|
|
81
|
+
|
|
73
82
|
type MD = import('./dist/@types/astro').MarkdownInstance<Record<string, any>>;
|
|
74
83
|
interface ExportedMarkdownModuleEntities {
|
|
75
84
|
frontmatter: MD['frontmatter'];
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Fallback = 'none' | 'animate' | 'swap';
|
|
3
|
+
|
|
4
|
+
export interface Props {
|
|
5
|
+
fallback?: Fallback;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { fallback = 'animate' } = Astro.props as Props;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<meta name="astro-view-transitions-enabled" content="true" />
|
|
12
|
+
<meta name="astro-view-transitions-fallback" content={fallback} />
|
|
13
|
+
<script>
|
|
14
|
+
type Fallback = 'none' | 'animate' | 'swap';
|
|
15
|
+
type Direction = 'forward' | 'back';
|
|
16
|
+
|
|
17
|
+
// The History API does not tell you if navigation is forward or back, so
|
|
18
|
+
// you can figure it using an index. On pushState the index is incremented so you
|
|
19
|
+
// can use that to determine popstate if going forward or back.
|
|
20
|
+
let currentHistoryIndex = history.state?.index || 0;
|
|
21
|
+
if (!history.state) {
|
|
22
|
+
history.replaceState({ index: currentHistoryIndex }, document.title);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const supportsViewTransitions = !!document.startViewTransition;
|
|
26
|
+
const transitionEnabledOnThisPage = () =>
|
|
27
|
+
!!document.querySelector('[name="astro-view-transitions-enabled"]');
|
|
28
|
+
|
|
29
|
+
async function getHTML(href: string) {
|
|
30
|
+
const res = await fetch(href);
|
|
31
|
+
const html = await res.text();
|
|
32
|
+
return { ok: res.ok, html };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getFallback(): Fallback {
|
|
36
|
+
const el = document.querySelector('[name="astro-view-transitions-fallback"]');
|
|
37
|
+
if (el) {
|
|
38
|
+
return el.getAttribute('content') as Fallback;
|
|
39
|
+
}
|
|
40
|
+
return 'animate';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const parser = new DOMParser();
|
|
44
|
+
|
|
45
|
+
async function updateDOM(dir: Direction, html: string, fallback?: Fallback) {
|
|
46
|
+
const doc = parser.parseFromString(html, 'text/html');
|
|
47
|
+
doc.documentElement.dataset.astroTransition = dir;
|
|
48
|
+
const swap = () => document.documentElement.replaceWith(doc.documentElement);
|
|
49
|
+
|
|
50
|
+
if (fallback === 'animate') {
|
|
51
|
+
let isAnimating = false;
|
|
52
|
+
addEventListener('animationstart', () => (isAnimating = true), { once: true });
|
|
53
|
+
|
|
54
|
+
// Trigger the animations
|
|
55
|
+
document.documentElement.dataset.astroTransitionFallback = 'old';
|
|
56
|
+
doc.documentElement.dataset.astroTransitionFallback = 'new';
|
|
57
|
+
// If there are any animations, want for the animationend event.
|
|
58
|
+
addEventListener('animationend', swap, { once: true });
|
|
59
|
+
// If there are no animations, go ahead and swap on next tick
|
|
60
|
+
// This is necessary because we do not know if there are animations.
|
|
61
|
+
// The setTimeout is a fallback in case there are none.
|
|
62
|
+
setTimeout(() => !isAnimating && swap());
|
|
63
|
+
} else {
|
|
64
|
+
swap();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function navigate(dir: Direction, href: string) {
|
|
69
|
+
let finished: Promise<void>;
|
|
70
|
+
const { html, ok } = await getHTML(href);
|
|
71
|
+
// If there is a problem fetching the new page, just do an MPA navigation to it.
|
|
72
|
+
if (!ok) {
|
|
73
|
+
location.href = href;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (supportsViewTransitions) {
|
|
77
|
+
finished = document.startViewTransition(() => updateDOM(dir, html)).finished;
|
|
78
|
+
} else {
|
|
79
|
+
finished = updateDOM(dir, html, getFallback());
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await finished;
|
|
83
|
+
} finally {
|
|
84
|
+
document.documentElement.removeAttribute('data-astro-transition');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Prefetching
|
|
89
|
+
function maybePrefetch(pathname: string) {
|
|
90
|
+
if (document.querySelector(`link[rel=prefetch][href="${pathname}"]`)) return;
|
|
91
|
+
if (navigator.connection) {
|
|
92
|
+
let conn = navigator.connection;
|
|
93
|
+
if (conn.saveData || /(2|3)g/.test(conn.effectiveType || '')) return;
|
|
94
|
+
}
|
|
95
|
+
let link = document.createElement('link');
|
|
96
|
+
link.setAttribute('rel', 'prefetch');
|
|
97
|
+
link.setAttribute('href', pathname);
|
|
98
|
+
document.head.append(link);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (supportsViewTransitions || getFallback() !== 'none') {
|
|
102
|
+
document.addEventListener('click', (ev) => {
|
|
103
|
+
let link = ev.target;
|
|
104
|
+
if (link instanceof Element && link.tagName !== 'A') {
|
|
105
|
+
link = link.closest('a');
|
|
106
|
+
}
|
|
107
|
+
// This check verifies that the click is happening on an anchor
|
|
108
|
+
// that is going to another page within the same origin. Basically it determines
|
|
109
|
+
// same-origin navigation, but omits special key combos for new tabs, etc.
|
|
110
|
+
if (
|
|
111
|
+
link &&
|
|
112
|
+
link instanceof HTMLAnchorElement &&
|
|
113
|
+
link.href &&
|
|
114
|
+
(!link.target || link.target === '_self') &&
|
|
115
|
+
link.origin === location.origin &&
|
|
116
|
+
ev.button === 0 && // left clicks only
|
|
117
|
+
!ev.metaKey && // new tab (mac)
|
|
118
|
+
!ev.ctrlKey && // new tab (windows)
|
|
119
|
+
!ev.altKey && // download
|
|
120
|
+
!ev.shiftKey &&
|
|
121
|
+
!ev.defaultPrevented &&
|
|
122
|
+
transitionEnabledOnThisPage()
|
|
123
|
+
) {
|
|
124
|
+
ev.preventDefault();
|
|
125
|
+
navigate('forward', link.href);
|
|
126
|
+
currentHistoryIndex++;
|
|
127
|
+
history.pushState({ index: currentHistoryIndex }, '', link.href);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
window.addEventListener('popstate', () => {
|
|
131
|
+
if (!transitionEnabledOnThisPage()) return;
|
|
132
|
+
const nextIndex = history.state?.index ?? currentHistoryIndex + 1;
|
|
133
|
+
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
|
|
134
|
+
navigate(direction, location.href);
|
|
135
|
+
currentHistoryIndex = nextIndex;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
['mouseenter', 'touchstart', 'focus'].forEach((evName) => {
|
|
139
|
+
document.addEventListener(
|
|
140
|
+
evName,
|
|
141
|
+
(ev) => {
|
|
142
|
+
if (ev.target instanceof HTMLAnchorElement) {
|
|
143
|
+
let el = ev.target;
|
|
144
|
+
if (
|
|
145
|
+
el.origin === location.origin &&
|
|
146
|
+
el.pathname !== location.pathname &&
|
|
147
|
+
transitionEnabledOnThisPage()
|
|
148
|
+
) {
|
|
149
|
+
maybePrefetch(el.pathname);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{ passive: true, capture: true }
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
</script>
|
package/components/index.ts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
@keyframes astroFadeInOut {
|
|
2
|
+
from {
|
|
3
|
+
opacity: 1;
|
|
4
|
+
}
|
|
5
|
+
to {
|
|
6
|
+
opacity: 0;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@keyframes astroFadeIn {
|
|
11
|
+
from {
|
|
12
|
+
opacity: 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@keyframes astroFadeOut {
|
|
17
|
+
to {
|
|
18
|
+
opacity: 0;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@keyframes astroSlideFromRight {
|
|
23
|
+
from {
|
|
24
|
+
transform: translateX(100%);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@keyframes astroSlideFromLeft {
|
|
29
|
+
from {
|
|
30
|
+
transform: translateX(-100%);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@keyframes astroSlideToRight {
|
|
35
|
+
to {
|
|
36
|
+
transform: translateX(100%);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@keyframes astroSlideToLeft {
|
|
41
|
+
to {
|
|
42
|
+
transform: translateX(-100%);
|
|
43
|
+
}
|
|
44
|
+
}
|
package/dist/@types/astro.d.ts
CHANGED
|
@@ -29,6 +29,23 @@ export interface AstroBuiltinProps {
|
|
|
29
29
|
'client:visible'?: boolean;
|
|
30
30
|
'client:only'?: boolean | string;
|
|
31
31
|
}
|
|
32
|
+
export interface TransitionAnimation {
|
|
33
|
+
name: string;
|
|
34
|
+
delay?: number | string;
|
|
35
|
+
duration?: number | string;
|
|
36
|
+
easing?: string;
|
|
37
|
+
fillMode?: string;
|
|
38
|
+
direction?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface TransitionAnimationPair {
|
|
41
|
+
old: TransitionAnimation | TransitionAnimation[];
|
|
42
|
+
new: TransitionAnimation | TransitionAnimation[];
|
|
43
|
+
}
|
|
44
|
+
export interface TransitionDirectionalAnimations {
|
|
45
|
+
forwards: TransitionAnimationPair;
|
|
46
|
+
backwards: TransitionAnimationPair;
|
|
47
|
+
}
|
|
48
|
+
export type TransitionAnimationValue = 'morph' | 'slide' | 'fade' | TransitionDirectionalAnimations;
|
|
32
49
|
export interface AstroClientDirectives {
|
|
33
50
|
}
|
|
34
51
|
export interface AstroBuiltinAttributes {
|
|
@@ -36,6 +53,8 @@ export interface AstroBuiltinAttributes {
|
|
|
36
53
|
'set:html'?: any;
|
|
37
54
|
'set:text'?: any;
|
|
38
55
|
'is:raw'?: boolean;
|
|
56
|
+
'transition:animate'?: 'morph' | 'slide' | 'fade' | TransitionDirectionalAnimations;
|
|
57
|
+
'transition:name'?: string;
|
|
39
58
|
}
|
|
40
59
|
export interface AstroDefineVarsAttribute {
|
|
41
60
|
'define:vars'?: any;
|
|
@@ -73,7 +92,6 @@ export interface CLIFlags {
|
|
|
73
92
|
drafts?: boolean;
|
|
74
93
|
open?: boolean;
|
|
75
94
|
experimentalAssets?: boolean;
|
|
76
|
-
experimentalRedirects?: boolean;
|
|
77
95
|
}
|
|
78
96
|
/**
|
|
79
97
|
* Astro global available in all contexts in .astro files
|
|
@@ -399,10 +417,10 @@ export interface AstroUserConfig {
|
|
|
399
417
|
cacheDir?: string;
|
|
400
418
|
/**
|
|
401
419
|
* @docs
|
|
402
|
-
* @name redirects
|
|
420
|
+
* @name redirects
|
|
403
421
|
* @type {Record<string, RedirectConfig>}
|
|
404
422
|
* @default `{}`
|
|
405
|
-
* @version 2.
|
|
423
|
+
* @version 2.9.0
|
|
406
424
|
* @description Specify a mapping of redirects where the key is the route to match
|
|
407
425
|
* and the value is the path to redirect to.
|
|
408
426
|
*
|
|
@@ -1149,24 +1167,24 @@ export interface AstroUserConfig {
|
|
|
1149
1167
|
assets?: boolean;
|
|
1150
1168
|
/**
|
|
1151
1169
|
* @docs
|
|
1152
|
-
* @name experimental.
|
|
1170
|
+
* @name experimental.viewTransitions
|
|
1153
1171
|
* @type {boolean}
|
|
1154
1172
|
* @default `false`
|
|
1155
|
-
* @version 2.
|
|
1173
|
+
* @version 2.9.0
|
|
1156
1174
|
* @description
|
|
1157
|
-
* Enable experimental support for
|
|
1158
|
-
* you can
|
|
1159
|
-
*
|
|
1175
|
+
* Enable experimental support for the `<ViewTransitions / >` component. With this enabled
|
|
1176
|
+
* you can opt-in to [client-side routing](https://docs.astro.build/en/guides/client-side-routing/) on a per-page basis using this component
|
|
1177
|
+
* and enable animations with the `transition:animate` directive.
|
|
1160
1178
|
*
|
|
1161
1179
|
* ```js
|
|
1162
1180
|
* {
|
|
1163
1181
|
* experimental: {
|
|
1164
|
-
*
|
|
1182
|
+
* viewTransitions: true,
|
|
1165
1183
|
* },
|
|
1166
1184
|
* }
|
|
1167
1185
|
* ```
|
|
1168
1186
|
*/
|
|
1169
|
-
|
|
1187
|
+
viewTransitions?: boolean;
|
|
1170
1188
|
};
|
|
1171
1189
|
/** @deprecated - Use "integrations" instead. Run Astro to learn more about migrating. */
|
|
1172
1190
|
renderers?: never;
|
package/dist/content/runtime.js
CHANGED
|
@@ -4,8 +4,8 @@ import { moduleIsTopLevelPage, walkParentInfos } from "../core/build/graph.js";
|
|
|
4
4
|
import { getPageDataByViteID } from "../core/build/internal.js";
|
|
5
5
|
import { createViteLoader } from "../core/module-loader/vite.js";
|
|
6
6
|
import { joinPaths, prependForwardSlash } from "../core/path.js";
|
|
7
|
-
import { getStylesForURL } from "../
|
|
8
|
-
import { getScriptsForURL } from "../
|
|
7
|
+
import { getStylesForURL } from "../vite-plugin-astro-server/css.js";
|
|
8
|
+
import { getScriptsForURL } from "../vite-plugin-astro-server/scripts.js";
|
|
9
9
|
import {
|
|
10
10
|
CONTENT_RENDER_FLAG,
|
|
11
11
|
LINKS_PLACEHOLDER,
|
package/dist/core/app/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import mime from "mime";
|
|
2
2
|
import { attachToResponse, getSetCookiesFromResponse } from "../cookies/index.js";
|
|
3
|
-
import { callEndpoint } from "../endpoint/index.js";
|
|
4
3
|
import { consoleLogDestination } from "../logger/console.js";
|
|
5
4
|
import { error } from "../logger/core.js";
|
|
6
5
|
import { prependForwardSlash, removeTrailingForwardSlash } from "../path.js";
|
|
7
6
|
import { RedirectSinglePageBuiltModule } from "../redirects/index.js";
|
|
7
|
+
import { isResponse } from "../render/core";
|
|
8
8
|
import {
|
|
9
9
|
createEnvironment,
|
|
10
10
|
createRenderContext,
|
|
11
|
-
|
|
11
|
+
tryRenderRoute
|
|
12
12
|
} from "../render/index.js";
|
|
13
13
|
import { RouteCache } from "../render/route-cache.js";
|
|
14
14
|
import {
|
|
@@ -131,34 +131,140 @@ class App {
|
|
|
131
131
|
defaultStatus = 404;
|
|
132
132
|
}
|
|
133
133
|
let mod = await this.#getModuleForRoute(routeData);
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
const pageModule = await mod.page();
|
|
135
|
+
const url = new URL(request.url);
|
|
136
|
+
const renderContext = await this.#createRenderContext(
|
|
137
|
+
url,
|
|
138
|
+
request,
|
|
139
|
+
routeData,
|
|
140
|
+
mod,
|
|
141
|
+
defaultStatus
|
|
142
|
+
);
|
|
143
|
+
let response;
|
|
144
|
+
try {
|
|
145
|
+
response = await tryRenderRoute(
|
|
146
|
+
routeData.type,
|
|
147
|
+
renderContext,
|
|
148
|
+
this.#env,
|
|
149
|
+
pageModule,
|
|
150
|
+
mod.onRequest
|
|
151
|
+
);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
error(this.#logging, "ssr", err.stack || err.message || String(err));
|
|
154
|
+
response = new Response(null, {
|
|
155
|
+
status: 500,
|
|
156
|
+
statusText: "Internal server error"
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (isResponse(response, routeData.type)) {
|
|
136
160
|
if (response.status === 500 || response.status === 404) {
|
|
137
161
|
const errorRouteData = matchRoute("/" + response.status, this.#manifestData);
|
|
138
162
|
if (errorRouteData && errorRouteData.route !== routeData.route) {
|
|
139
163
|
mod = await this.#getModuleForRoute(errorRouteData);
|
|
140
164
|
try {
|
|
141
|
-
|
|
165
|
+
const newRenderContext = await this.#createRenderContext(
|
|
166
|
+
url,
|
|
142
167
|
request,
|
|
143
|
-
|
|
168
|
+
routeData,
|
|
144
169
|
mod,
|
|
145
170
|
response.status
|
|
146
171
|
);
|
|
172
|
+
const page = await mod.page();
|
|
173
|
+
const errorResponse = await tryRenderRoute(
|
|
174
|
+
routeData.type,
|
|
175
|
+
newRenderContext,
|
|
176
|
+
this.#env,
|
|
177
|
+
page
|
|
178
|
+
);
|
|
147
179
|
return errorResponse;
|
|
148
180
|
} catch {
|
|
149
181
|
}
|
|
150
182
|
}
|
|
151
183
|
}
|
|
184
|
+
Reflect.set(response, responseSentSymbol, true);
|
|
152
185
|
return response;
|
|
153
|
-
} else if (routeData.type === "endpoint") {
|
|
154
|
-
return this.#callEndpoint(request, routeData, mod, defaultStatus);
|
|
155
186
|
} else {
|
|
156
|
-
|
|
187
|
+
if (response.type === "response") {
|
|
188
|
+
if (response.response.headers.get("X-Astro-Response") === "Not-Found") {
|
|
189
|
+
const fourOhFourRequest = new Request(new URL("/404", request.url));
|
|
190
|
+
const fourOhFourRouteData = this.match(fourOhFourRequest);
|
|
191
|
+
if (fourOhFourRouteData) {
|
|
192
|
+
return this.render(fourOhFourRequest, fourOhFourRouteData);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return response.response;
|
|
196
|
+
} else {
|
|
197
|
+
const body = response.body;
|
|
198
|
+
const headers = new Headers();
|
|
199
|
+
const mimeType = mime.getType(url.pathname);
|
|
200
|
+
if (mimeType) {
|
|
201
|
+
headers.set("Content-Type", `${mimeType};charset=utf-8`);
|
|
202
|
+
} else {
|
|
203
|
+
headers.set("Content-Type", "text/plain;charset=utf-8");
|
|
204
|
+
}
|
|
205
|
+
const bytes = this.#encoder.encode(body);
|
|
206
|
+
headers.set("Content-Length", bytes.byteLength.toString());
|
|
207
|
+
const newResponse = new Response(bytes, {
|
|
208
|
+
status: 200,
|
|
209
|
+
headers
|
|
210
|
+
});
|
|
211
|
+
attachToResponse(newResponse, response.cookies);
|
|
212
|
+
return newResponse;
|
|
213
|
+
}
|
|
157
214
|
}
|
|
158
215
|
}
|
|
159
216
|
setCookieHeaders(response) {
|
|
160
217
|
return getSetCookiesFromResponse(response);
|
|
161
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Creates the render context of the current route
|
|
221
|
+
*/
|
|
222
|
+
async #createRenderContext(url, request, routeData, page, status = 200) {
|
|
223
|
+
if (routeData.type === "endpoint") {
|
|
224
|
+
const pathname = "/" + this.removeBase(url.pathname);
|
|
225
|
+
const mod = await page.page();
|
|
226
|
+
const handler = mod;
|
|
227
|
+
return await createRenderContext({
|
|
228
|
+
request,
|
|
229
|
+
pathname,
|
|
230
|
+
route: routeData,
|
|
231
|
+
status,
|
|
232
|
+
env: this.#env,
|
|
233
|
+
mod: handler
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
const pathname = prependForwardSlash(this.removeBase(url.pathname));
|
|
237
|
+
const info = this.#routeDataToRouteInfo.get(routeData);
|
|
238
|
+
const links = /* @__PURE__ */ new Set();
|
|
239
|
+
const styles = createStylesheetElementSet(info.styles);
|
|
240
|
+
let scripts = /* @__PURE__ */ new Set();
|
|
241
|
+
for (const script of info.scripts) {
|
|
242
|
+
if ("stage" in script) {
|
|
243
|
+
if (script.stage === "head-inline") {
|
|
244
|
+
scripts.add({
|
|
245
|
+
props: {},
|
|
246
|
+
children: script.children
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
scripts.add(createModuleScriptElement(script));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const mod = await page.page();
|
|
254
|
+
return await createRenderContext({
|
|
255
|
+
request,
|
|
256
|
+
pathname,
|
|
257
|
+
componentMetadata: this.#manifest.componentMetadata,
|
|
258
|
+
scripts,
|
|
259
|
+
styles,
|
|
260
|
+
links,
|
|
261
|
+
route: routeData,
|
|
262
|
+
status,
|
|
263
|
+
mod,
|
|
264
|
+
env: this.#env
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
162
268
|
async #getModuleForRoute(route) {
|
|
163
269
|
if (route.type === "redirect") {
|
|
164
270
|
return RedirectSinglePageBuiltModule;
|
|
@@ -182,92 +288,6 @@ class App {
|
|
|
182
288
|
}
|
|
183
289
|
}
|
|
184
290
|
}
|
|
185
|
-
async #renderPage(request, routeData, page, status = 200) {
|
|
186
|
-
const url = new URL(request.url);
|
|
187
|
-
const pathname = prependForwardSlash(this.removeBase(url.pathname));
|
|
188
|
-
const info = this.#routeDataToRouteInfo.get(routeData);
|
|
189
|
-
const links = /* @__PURE__ */ new Set();
|
|
190
|
-
const styles = createStylesheetElementSet(info.styles);
|
|
191
|
-
let scripts = /* @__PURE__ */ new Set();
|
|
192
|
-
for (const script of info.scripts) {
|
|
193
|
-
if ("stage" in script) {
|
|
194
|
-
if (script.stage === "head-inline") {
|
|
195
|
-
scripts.add({
|
|
196
|
-
props: {},
|
|
197
|
-
children: script.children
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
} else {
|
|
201
|
-
scripts.add(createModuleScriptElement(script));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
try {
|
|
205
|
-
const mod = await page.page();
|
|
206
|
-
const renderContext = await createRenderContext({
|
|
207
|
-
request,
|
|
208
|
-
pathname,
|
|
209
|
-
componentMetadata: this.#manifest.componentMetadata,
|
|
210
|
-
scripts,
|
|
211
|
-
styles,
|
|
212
|
-
links,
|
|
213
|
-
route: routeData,
|
|
214
|
-
status,
|
|
215
|
-
mod,
|
|
216
|
-
env: this.#env
|
|
217
|
-
});
|
|
218
|
-
const response = await tryRenderPage(renderContext, this.#env, mod, page.onRequest);
|
|
219
|
-
Reflect.set(request, responseSentSymbol, true);
|
|
220
|
-
return response;
|
|
221
|
-
} catch (err) {
|
|
222
|
-
error(this.#logging, "ssr", err.stack || err.message || String(err));
|
|
223
|
-
return new Response(null, {
|
|
224
|
-
status: 500,
|
|
225
|
-
statusText: "Internal server error"
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async #callEndpoint(request, routeData, page, status = 200) {
|
|
230
|
-
const url = new URL(request.url);
|
|
231
|
-
const pathname = "/" + this.removeBase(url.pathname);
|
|
232
|
-
const mod = await page.page();
|
|
233
|
-
const handler = mod;
|
|
234
|
-
const ctx = await createRenderContext({
|
|
235
|
-
request,
|
|
236
|
-
pathname,
|
|
237
|
-
route: routeData,
|
|
238
|
-
status,
|
|
239
|
-
env: this.#env,
|
|
240
|
-
mod: handler
|
|
241
|
-
});
|
|
242
|
-
const result = await callEndpoint(handler, this.#env, ctx, page.onRequest);
|
|
243
|
-
if (result.type === "response") {
|
|
244
|
-
if (result.response.headers.get("X-Astro-Response") === "Not-Found") {
|
|
245
|
-
const fourOhFourRequest = new Request(new URL("/404", request.url));
|
|
246
|
-
const fourOhFourRouteData = this.match(fourOhFourRequest);
|
|
247
|
-
if (fourOhFourRouteData) {
|
|
248
|
-
return this.render(fourOhFourRequest, fourOhFourRouteData);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return result.response;
|
|
252
|
-
} else {
|
|
253
|
-
const body = result.body;
|
|
254
|
-
const headers = new Headers();
|
|
255
|
-
const mimeType = mime.getType(url.pathname);
|
|
256
|
-
if (mimeType) {
|
|
257
|
-
headers.set("Content-Type", `${mimeType};charset=utf-8`);
|
|
258
|
-
} else {
|
|
259
|
-
headers.set("Content-Type", "text/plain;charset=utf-8");
|
|
260
|
-
}
|
|
261
|
-
const bytes = this.#encoder.encode(body);
|
|
262
|
-
headers.set("Content-Length", bytes.byteLength.toString());
|
|
263
|
-
const response = new Response(bytes, {
|
|
264
|
-
status: 200,
|
|
265
|
-
headers
|
|
266
|
-
});
|
|
267
|
-
attachToResponse(response, result.cookies);
|
|
268
|
-
return response;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
291
|
}
|
|
272
292
|
export {
|
|
273
293
|
App,
|
|
@@ -20,15 +20,11 @@ import {
|
|
|
20
20
|
import { runHookBuildGenerated } from "../../integrations/index.js";
|
|
21
21
|
import { isServerLikeOutput } from "../../prerender/utils.js";
|
|
22
22
|
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
|
23
|
-
import { callEndpoint, throwIfRedirectNotAllowed } from "../endpoint/index.js";
|
|
24
23
|
import { AstroError, AstroErrorData } from "../errors/index.js";
|
|
25
24
|
import { debug, info } from "../logger/core.js";
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
routeIsRedirect
|
|
30
|
-
} from "../redirects/index.js";
|
|
31
|
-
import { createEnvironment, createRenderContext, tryRenderPage } from "../render/index.js";
|
|
25
|
+
import { RedirectSinglePageBuiltModule, getRedirectLocationOrThrow } from "../redirects/index.js";
|
|
26
|
+
import { isEndpointResult } from "../render/core.js";
|
|
27
|
+
import { createEnvironment, createRenderContext, tryRenderRoute } from "../render/index.js";
|
|
32
28
|
import { callGetStaticPaths } from "../render/route-cache.js";
|
|
33
29
|
import {
|
|
34
30
|
createAssetLink,
|
|
@@ -165,9 +161,6 @@ async function generateImage(opts, transform, path) {
|
|
|
165
161
|
info(opts.logging, null, ` ${green("\u25B6")} ${path} ${dim(statsText)} ${dim(timeIncrease)}`);
|
|
166
162
|
}
|
|
167
163
|
async function generatePage(opts, internals, pageData, ssrEntry, builtPaths, manifest) {
|
|
168
|
-
if (routeIsRedirect(pageData.route) && !opts.settings.config.experimental.redirects) {
|
|
169
|
-
throw new Error(`To use redirects first set experimental.redirects to \`true\``);
|
|
170
|
-
}
|
|
171
164
|
let timeStart = performance.now();
|
|
172
165
|
const pageInfo = getPageDataByComponent(internals, pageData.route.component);
|
|
173
166
|
const linkIds = [];
|
|
@@ -399,34 +392,26 @@ async function generatePath(pathname, opts, gopts, manifest, onRequest) {
|
|
|
399
392
|
});
|
|
400
393
|
let body;
|
|
401
394
|
let encoding;
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
395
|
+
let response;
|
|
396
|
+
try {
|
|
397
|
+
response = await tryRenderRoute(pageData.route.type, renderContext, env, mod, onRequest);
|
|
398
|
+
} catch (err) {
|
|
399
|
+
if (!AstroError.is(err) && !err.id && typeof err === "object") {
|
|
400
|
+
err.id = pageData.component;
|
|
401
|
+
}
|
|
402
|
+
throw err;
|
|
403
|
+
}
|
|
404
|
+
if (isEndpointResult(response, pageData.route.type)) {
|
|
405
|
+
if (response.type === "response") {
|
|
406
|
+
if (!response.response.body)
|
|
413
407
|
return;
|
|
414
|
-
const ab = await
|
|
408
|
+
const ab = await response.response.arrayBuffer();
|
|
415
409
|
body = new Uint8Array(ab);
|
|
416
410
|
} else {
|
|
417
|
-
body =
|
|
418
|
-
encoding =
|
|
411
|
+
body = response.body;
|
|
412
|
+
encoding = response.encoding;
|
|
419
413
|
}
|
|
420
414
|
} else {
|
|
421
|
-
let response;
|
|
422
|
-
try {
|
|
423
|
-
response = await tryRenderPage(renderContext, env, mod, onRequest);
|
|
424
|
-
} catch (err) {
|
|
425
|
-
if (!AstroError.is(err) && !err.id && typeof err === "object") {
|
|
426
|
-
err.id = pageData.component;
|
|
427
|
-
}
|
|
428
|
-
throw err;
|
|
429
|
-
}
|
|
430
415
|
if (response.status >= 300 && response.status < 400) {
|
|
431
416
|
if (!opts.settings.config.build.redirects) {
|
|
432
417
|
return;
|
package/dist/core/build/graph.js
CHANGED
|
@@ -21,7 +21,7 @@ function* walkParentInfos(id, ctx, until, depth = 0, order = 0, seen = /* @__PUR
|
|
|
21
21
|
if (seen.has(imp)) {
|
|
22
22
|
continue;
|
|
23
23
|
}
|
|
24
|
-
yield* walkParentInfos(imp, ctx, until,
|
|
24
|
+
yield* walkParentInfos(imp, ctx, until, depth + 1, order, seen, id);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
function moduleIsTopLevelPage(info) {
|