astro 2.5.6 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/@types/astro.d.ts +115 -90
- package/dist/assets/generate.js +2 -2
- package/dist/config/index.js +11 -3
- package/dist/config/vite-plugin-content-listen.d.ts +18 -0
- package/dist/config/vite-plugin-content-listen.js +26 -0
- package/dist/content/consts.d.ts +2 -1
- package/dist/content/consts.js +8 -1
- package/dist/content/runtime.js +67 -47
- package/dist/content/vite-plugin-content-assets.js +26 -10
- package/dist/content/vite-plugin-content-virtual-mod.js +18 -9
- package/dist/core/app/index.js +27 -18
- package/dist/core/app/node.js +4 -3
- package/dist/core/app/types.d.ts +1 -2
- package/dist/core/build/common.js +2 -0
- package/dist/core/build/generate.js +76 -13
- package/dist/core/build/internal.d.ts +2 -0
- package/dist/core/build/internal.js +18 -1
- package/dist/core/build/plugins/plugin-css.js +1 -1
- package/dist/core/build/plugins/plugin-middleware.js +1 -7
- package/dist/core/build/plugins/plugin-pages.d.ts +1 -0
- package/dist/core/build/plugins/plugin-pages.js +14 -4
- package/dist/core/build/plugins/plugin-ssr.js +10 -14
- package/dist/core/build/static-build.js +9 -10
- package/dist/core/config/config.js +1 -10
- package/dist/core/config/schema.d.ts +48 -64
- package/dist/core/config/schema.js +13 -11
- package/dist/core/config/settings.js +2 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/endpoint/index.js +2 -2
- package/dist/core/errors/errors-data.d.ts +12 -20
- package/dist/core/errors/errors-data.js +13 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/path.d.ts +1 -15
- package/dist/core/path.js +1 -80
- package/dist/core/redirects/component.d.ts +4 -0
- package/dist/core/redirects/component.js +19 -0
- package/dist/core/redirects/helpers.d.ts +4 -0
- package/dist/core/redirects/helpers.js +29 -0
- package/dist/core/redirects/index.d.ts +3 -0
- package/dist/core/redirects/index.js +11 -0
- package/dist/core/redirects/validate.d.ts +1 -0
- package/dist/core/redirects/validate.js +13 -0
- package/dist/core/render/context.d.ts +2 -1
- package/dist/core/render/core.d.ts +2 -1
- package/dist/core/render/core.js +18 -1
- package/dist/core/render/dev/environment.js +2 -2
- package/dist/core/render/dev/vite.js +12 -13
- package/dist/core/render/result.d.ts +2 -0
- package/dist/core/render/result.js +3 -3
- package/dist/core/routing/manifest/create.js +50 -4
- package/dist/core/util.js +10 -3
- package/dist/integrations/index.js +3 -8
- package/dist/prerender/utils.d.ts +2 -2
- package/dist/prerender/utils.js +6 -6
- package/dist/runtime/server/astro-island.js +7 -4
- package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
- package/dist/runtime/server/astro-island.prebuilt.js +1 -1
- package/dist/runtime/server/render/any.js +4 -2
- package/dist/runtime/server/render/astro/render-template.d.ts +1 -1
- package/dist/runtime/server/render/astro/render-template.js +5 -9
- package/dist/runtime/server/render/common.js +6 -0
- package/dist/runtime/server/render/component.js +2 -2
- package/dist/runtime/server/render/page.d.ts +1 -1
- package/dist/runtime/server/render/page.js +10 -6
- package/dist/runtime/server/render/util.d.ts +6 -0
- package/dist/runtime/server/render/util.js +8 -0
- package/dist/vite-plugin-astro-server/request.js +2 -2
- package/dist/vite-plugin-astro-server/route.js +16 -9
- package/dist/vite-plugin-head/index.js +1 -1
- package/dist/vite-plugin-html/transform/index.js +3 -7
- package/dist/vite-plugin-markdown/content-entry-type.js +6 -1
- package/dist/vite-plugin-scanner/index.js +4 -4
- package/dist/vite-plugin-utils/index.js +1 -1
- package/env.d.ts +2 -2
- package/package.json +2 -1
- package/src/content/template/virtual-mod.mjs +1 -1
- package/tsconfigs/base.json +3 -1
- package/tsconfigs/strictest.json +3 -1
package/dist/@types/astro.d.ts
CHANGED
|
@@ -73,7 +73,7 @@ export interface CLIFlags {
|
|
|
73
73
|
drafts?: boolean;
|
|
74
74
|
open?: boolean;
|
|
75
75
|
experimentalAssets?: boolean;
|
|
76
|
-
|
|
76
|
+
experimentalRedirects?: boolean;
|
|
77
77
|
}
|
|
78
78
|
export interface BuildConfig {
|
|
79
79
|
/**
|
|
@@ -396,6 +396,50 @@ export interface AstroUserConfig {
|
|
|
396
396
|
* ```
|
|
397
397
|
*/
|
|
398
398
|
cacheDir?: string;
|
|
399
|
+
/**
|
|
400
|
+
* @docs
|
|
401
|
+
* @name redirects (Experimental)
|
|
402
|
+
* @type {RedirectConfig}
|
|
403
|
+
* @default `{}`
|
|
404
|
+
* @version 2.6.0
|
|
405
|
+
* @description Specify a mapping of redirects where the key is the route to match
|
|
406
|
+
* and the value is the path to redirect to.
|
|
407
|
+
*
|
|
408
|
+
* You can redirect both static and dynamic routes, but only to the same kind of route.
|
|
409
|
+
* For example you cannot have a `'/article': '/blog/[...slug]'` redirect.
|
|
410
|
+
*
|
|
411
|
+
*
|
|
412
|
+
* ```js
|
|
413
|
+
* {
|
|
414
|
+
* redirects: {
|
|
415
|
+
* '/old': '/new',
|
|
416
|
+
* '/blog/[...slug]': '/articles/[...slug]',
|
|
417
|
+
* }
|
|
418
|
+
* }
|
|
419
|
+
* ```
|
|
420
|
+
*
|
|
421
|
+
*
|
|
422
|
+
* For statically-generated sites with no adapter installed, this will produce a client redirect using a [`<meta http-equiv="refresh">` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv) and does not support status codes.
|
|
423
|
+
*
|
|
424
|
+
* When using SSR or with a static adapter in `output: static`
|
|
425
|
+
* mode, status codes are supported.
|
|
426
|
+
* Astro will serve redirected GET requests with a status of `301`
|
|
427
|
+
* and use a status of `308` for any other request method.
|
|
428
|
+
*
|
|
429
|
+
* You can customize the [redirection status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages) using an object in the redirect config:
|
|
430
|
+
*
|
|
431
|
+
* ```js
|
|
432
|
+
* {
|
|
433
|
+
* redirects: {
|
|
434
|
+
* '/other': {
|
|
435
|
+
* status: 302,
|
|
436
|
+
* destination: '/place',
|
|
437
|
+
* },
|
|
438
|
+
* }
|
|
439
|
+
* }
|
|
440
|
+
* ```
|
|
441
|
+
*/
|
|
442
|
+
redirects?: RedirectConfig;
|
|
399
443
|
/**
|
|
400
444
|
* @docs
|
|
401
445
|
* @name site
|
|
@@ -670,6 +714,50 @@ export interface AstroUserConfig {
|
|
|
670
714
|
* ```
|
|
671
715
|
*/
|
|
672
716
|
serverEntry?: string;
|
|
717
|
+
/**
|
|
718
|
+
* @docs
|
|
719
|
+
* @name build.redirects
|
|
720
|
+
* @type {boolean}
|
|
721
|
+
* @default `true`
|
|
722
|
+
* @version 2.6.0
|
|
723
|
+
* @description
|
|
724
|
+
* Specifies whether redirects will be output to HTML during the build.
|
|
725
|
+
* This option only applies to `output: 'static'` mode; in SSR redirects
|
|
726
|
+
* are treated the same as all responses.
|
|
727
|
+
*
|
|
728
|
+
* This option is mostly meant to be used by adapters that have special
|
|
729
|
+
* configuration files for redirects and do not need/want HTML based redirects.
|
|
730
|
+
*
|
|
731
|
+
* ```js
|
|
732
|
+
* {
|
|
733
|
+
* build: {
|
|
734
|
+
* redirects: false
|
|
735
|
+
* }
|
|
736
|
+
* }
|
|
737
|
+
* ```
|
|
738
|
+
*/
|
|
739
|
+
redirects?: boolean;
|
|
740
|
+
/**
|
|
741
|
+
* @docs
|
|
742
|
+
* @name build.inlineStylesheets
|
|
743
|
+
* @type {('always' | 'auto' | 'never')}
|
|
744
|
+
* @default `never`
|
|
745
|
+
* @version 2.6.0
|
|
746
|
+
* @description
|
|
747
|
+
* Control whether styles are sent to the browser in a separate css file or inlined into `<style>` tags. Choose from the following options:
|
|
748
|
+
* - `'always'` - all styles are inlined into `<style>` tags
|
|
749
|
+
* - `'auto'` - only stylesheets smaller than `ViteConfig.build.assetsInlineLimit` (default: 4kb) are inlined. Otherwise, styles are sent in external stylesheets.
|
|
750
|
+
* - `'never'` - all styles are sent in external stylesheets
|
|
751
|
+
*
|
|
752
|
+
* ```js
|
|
753
|
+
* {
|
|
754
|
+
* build: {
|
|
755
|
+
* inlineStylesheets: `auto`,
|
|
756
|
+
* },
|
|
757
|
+
* }
|
|
758
|
+
* ```
|
|
759
|
+
*/
|
|
760
|
+
inlineStylesheets?: 'always' | 'auto' | 'never';
|
|
673
761
|
};
|
|
674
762
|
/**
|
|
675
763
|
* @docs
|
|
@@ -1001,103 +1089,24 @@ export interface AstroUserConfig {
|
|
|
1001
1089
|
assets?: boolean;
|
|
1002
1090
|
/**
|
|
1003
1091
|
* @docs
|
|
1004
|
-
* @name experimental.
|
|
1005
|
-
* @type {('always' | 'auto' | 'never')}
|
|
1006
|
-
* @default `never`
|
|
1007
|
-
* @version 2.4.0
|
|
1008
|
-
* @description
|
|
1009
|
-
* Control whether styles are sent to the browser in a separate css file or inlined into `<style>` tags. Choose from the following options:
|
|
1010
|
-
* - `'always'` - all styles are inlined into `<style>` tags
|
|
1011
|
-
* - `'auto'` - only stylesheets smaller than `ViteConfig.build.assetsInlineLimit` (default: 4kb) are inlined. Otherwise, styles are sent in external stylesheets.
|
|
1012
|
-
* - `'never'` - all styles are sent in external stylesheets
|
|
1013
|
-
*
|
|
1014
|
-
* ```js
|
|
1015
|
-
* {
|
|
1016
|
-
* experimental: {
|
|
1017
|
-
* inlineStylesheets: `auto`,
|
|
1018
|
-
* },
|
|
1019
|
-
* }
|
|
1020
|
-
* ```
|
|
1021
|
-
*/
|
|
1022
|
-
inlineStylesheets?: 'always' | 'auto' | 'never';
|
|
1023
|
-
/**
|
|
1024
|
-
* @docs
|
|
1025
|
-
* @name experimental.customClientDirectives
|
|
1026
|
-
* @type {boolean}
|
|
1027
|
-
* @default `false`
|
|
1028
|
-
* @version 2.5.0
|
|
1029
|
-
* @description
|
|
1030
|
-
* Allow integrations to use the [experimental `addClientDirective` API](/en/reference/integrations-reference/#addclientdirective-option) in the `astro:config:setup` hook
|
|
1031
|
-
* to add custom client directives in Astro files.
|
|
1032
|
-
*
|
|
1033
|
-
* To enable this feature, set `experimental.customClientDirectives` to `true` in your Astro config:
|
|
1034
|
-
*
|
|
1035
|
-
* ```js
|
|
1036
|
-
* {
|
|
1037
|
-
* experimental: {
|
|
1038
|
-
* customClientDirectives: true,
|
|
1039
|
-
* },
|
|
1040
|
-
* }
|
|
1041
|
-
* ```
|
|
1042
|
-
*/
|
|
1043
|
-
customClientDirectives?: boolean;
|
|
1044
|
-
/**
|
|
1045
|
-
* @docs
|
|
1046
|
-
* @name experimental.middleware
|
|
1047
|
-
* @type {boolean}
|
|
1048
|
-
* @default `false`
|
|
1049
|
-
* @version 2.4.0
|
|
1050
|
-
* @description
|
|
1051
|
-
* Enable experimental support for Astro middleware.
|
|
1052
|
-
*
|
|
1053
|
-
* To enable this feature, set `experimental.middleware` to `true` in your Astro config:
|
|
1054
|
-
*
|
|
1055
|
-
* ```js
|
|
1056
|
-
* {
|
|
1057
|
-
* experimental: {
|
|
1058
|
-
* middleware: true,
|
|
1059
|
-
* },
|
|
1060
|
-
* }
|
|
1061
|
-
* ```
|
|
1062
|
-
*/
|
|
1063
|
-
middleware?: boolean;
|
|
1064
|
-
/**
|
|
1065
|
-
* @docs
|
|
1066
|
-
* @name experimental.hybridOutput
|
|
1092
|
+
* @name experimental.redirects
|
|
1067
1093
|
* @type {boolean}
|
|
1068
1094
|
* @default `false`
|
|
1069
|
-
* @version 2.
|
|
1095
|
+
* @version 2.6.0
|
|
1070
1096
|
* @description
|
|
1071
|
-
* Enable experimental support for
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1097
|
+
* Enable experimental support for redirect configuration. With this enabled
|
|
1098
|
+
* you can set redirects via the top-level `redirects` property. To enable
|
|
1099
|
+
* this feature, set `experimental.redirects` to `true`.
|
|
1074
1100
|
*
|
|
1075
1101
|
* ```js
|
|
1076
1102
|
* {
|
|
1077
|
-
* output: 'hybrid',
|
|
1078
1103
|
* experimental: {
|
|
1079
|
-
*
|
|
1104
|
+
* redirects: true,
|
|
1080
1105
|
* },
|
|
1081
1106
|
* }
|
|
1082
1107
|
* ```
|
|
1083
|
-
* Then add `export const prerender = false` to any page or endpoint you want to opt-out of pre-rendering.
|
|
1084
|
-
* ```astro
|
|
1085
|
-
* ---
|
|
1086
|
-
* // pages/contact.astro
|
|
1087
|
-
* export const prerender = false
|
|
1088
|
-
*
|
|
1089
|
-
* if (Astro.request.method === 'POST') {
|
|
1090
|
-
* // handle form submission
|
|
1091
|
-
* }
|
|
1092
|
-
* ---
|
|
1093
|
-
* <form method="POST">
|
|
1094
|
-
* <input type="text" name="name" />
|
|
1095
|
-
* <input type="email" name="email" />
|
|
1096
|
-
* <button type="submit">Submit</button>
|
|
1097
|
-
* </form>
|
|
1098
|
-
* ```
|
|
1099
1108
|
*/
|
|
1100
|
-
|
|
1109
|
+
redirects?: boolean;
|
|
1101
1110
|
};
|
|
1102
1111
|
/** @deprecated - Use "integrations" instead. Run Astro to learn more about migrating. */
|
|
1103
1112
|
renderers?: never;
|
|
@@ -1171,6 +1180,12 @@ export interface ContentEntryType {
|
|
|
1171
1180
|
viteId: string;
|
|
1172
1181
|
}): rollup.LoadResult | Promise<rollup.LoadResult>;
|
|
1173
1182
|
contentModuleTypes?: string;
|
|
1183
|
+
/**
|
|
1184
|
+
* Handle asset propagation for rendered content to avoid bleed.
|
|
1185
|
+
* Ex. MDX content can import styles and scripts, so `handlePropagation` should be true.
|
|
1186
|
+
* @default true
|
|
1187
|
+
*/
|
|
1188
|
+
handlePropagation?: boolean;
|
|
1174
1189
|
}
|
|
1175
1190
|
type GetContentEntryInfoReturnType = {
|
|
1176
1191
|
data: Record<string, unknown>;
|
|
@@ -1414,6 +1429,7 @@ export interface AstroAdapter {
|
|
|
1414
1429
|
args?: any;
|
|
1415
1430
|
}
|
|
1416
1431
|
type Body = string;
|
|
1432
|
+
export type ValidRedirectStatus = 300 | 301 | 302 | 303 | 304 | 307 | 308;
|
|
1417
1433
|
interface AstroSharedContext<Props extends Record<string, any> = Record<string, any>> {
|
|
1418
1434
|
/**
|
|
1419
1435
|
* The address (usually IP address) of the user. Used with SSR only.
|
|
@@ -1442,7 +1458,7 @@ interface AstroSharedContext<Props extends Record<string, any> = Record<string,
|
|
|
1442
1458
|
/**
|
|
1443
1459
|
* Redirect to another page (**SSR Only**).
|
|
1444
1460
|
*/
|
|
1445
|
-
redirect(path: string, status?:
|
|
1461
|
+
redirect(path: string, status?: ValidRedirectStatus): Response;
|
|
1446
1462
|
/**
|
|
1447
1463
|
* Object accessed via Astro middleware
|
|
1448
1464
|
*/
|
|
@@ -1625,7 +1641,7 @@ export interface AstroIntegration {
|
|
|
1625
1641
|
};
|
|
1626
1642
|
}
|
|
1627
1643
|
export type MiddlewareNext<R> = () => Promise<R>;
|
|
1628
|
-
export type MiddlewareHandler<R> = (context: APIContext, next: MiddlewareNext<R>) => Promise<R> | Promise<void> | void;
|
|
1644
|
+
export type MiddlewareHandler<R> = (context: APIContext, next: MiddlewareNext<R>) => Promise<R> | R | Promise<void> | void;
|
|
1629
1645
|
export type MiddlewareResponseHandler = MiddlewareHandler<Response>;
|
|
1630
1646
|
export type MiddlewareEndpointHandler = MiddlewareHandler<Response | EndpointOutput>;
|
|
1631
1647
|
export type MiddlewareNextResponse = MiddlewareNext<Response>;
|
|
@@ -1636,12 +1652,16 @@ export interface AstroPluginOptions {
|
|
|
1636
1652
|
settings: AstroSettings;
|
|
1637
1653
|
logging: LogOptions;
|
|
1638
1654
|
}
|
|
1639
|
-
export type RouteType = 'page' | 'endpoint';
|
|
1655
|
+
export type RouteType = 'page' | 'endpoint' | 'redirect';
|
|
1640
1656
|
export interface RoutePart {
|
|
1641
1657
|
content: string;
|
|
1642
1658
|
dynamic: boolean;
|
|
1643
1659
|
spread: boolean;
|
|
1644
1660
|
}
|
|
1661
|
+
type RedirectConfig = string | {
|
|
1662
|
+
status: ValidRedirectStatus;
|
|
1663
|
+
destination: string;
|
|
1664
|
+
};
|
|
1645
1665
|
export interface RouteData {
|
|
1646
1666
|
route: string;
|
|
1647
1667
|
component: string;
|
|
@@ -1653,7 +1673,12 @@ export interface RouteData {
|
|
|
1653
1673
|
segments: RoutePart[][];
|
|
1654
1674
|
type: RouteType;
|
|
1655
1675
|
prerender: boolean;
|
|
1676
|
+
redirect?: RedirectConfig;
|
|
1677
|
+
redirectRoute?: RouteData;
|
|
1656
1678
|
}
|
|
1679
|
+
export type RedirectRouteData = RouteData & {
|
|
1680
|
+
redirect: string;
|
|
1681
|
+
};
|
|
1657
1682
|
export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern'> & {
|
|
1658
1683
|
generate: undefined;
|
|
1659
1684
|
pattern: string;
|
package/dist/assets/generate.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import { basename, join } from "node:path/posix";
|
|
3
3
|
import { warn } from "../core/logger/core.js";
|
|
4
4
|
import { prependForwardSlash } from "../core/path.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isServerLikeOutput } from "../prerender/utils.js";
|
|
6
6
|
import { getConfiguredImageService, isESMImportedImage } from "./internal.js";
|
|
7
7
|
async function generateImage(buildOpts, options, filepath) {
|
|
8
8
|
if (!isESMImportedImage(options.src)) {
|
|
@@ -21,7 +21,7 @@ async function generateImage(buildOpts, options, filepath) {
|
|
|
21
21
|
useCache = false;
|
|
22
22
|
}
|
|
23
23
|
let serverRoot, clientRoot;
|
|
24
|
-
if (
|
|
24
|
+
if (isServerLikeOutput(buildOpts.settings.config)) {
|
|
25
25
|
serverRoot = buildOpts.settings.config.build.server;
|
|
26
26
|
clientRoot = buildOpts.settings.config.build.client;
|
|
27
27
|
} else {
|
package/dist/config/index.js
CHANGED
|
@@ -5,17 +5,21 @@ function getViteConfig(inlineConfig) {
|
|
|
5
5
|
return async ({ mode, command }) => {
|
|
6
6
|
const cmd = command === "serve" ? "dev" : command;
|
|
7
7
|
const [
|
|
8
|
+
fs,
|
|
8
9
|
{ mergeConfig },
|
|
9
10
|
{ nodeLogDestination },
|
|
10
11
|
{ openConfig, createSettings },
|
|
11
12
|
{ createVite },
|
|
12
|
-
{ runHookConfigSetup, runHookConfigDone }
|
|
13
|
+
{ runHookConfigSetup, runHookConfigDone },
|
|
14
|
+
{ astroContentListenPlugin }
|
|
13
15
|
] = await Promise.all([
|
|
16
|
+
import("fs"),
|
|
14
17
|
import("vite"),
|
|
15
18
|
import("../core/logger/node.js"),
|
|
16
19
|
import("../core/config/index.js"),
|
|
17
20
|
import("../core/create-vite.js"),
|
|
18
|
-
import("../integrations/index.js")
|
|
21
|
+
import("../integrations/index.js"),
|
|
22
|
+
import("./vite-plugin-content-listen.js")
|
|
19
23
|
]);
|
|
20
24
|
const logging = {
|
|
21
25
|
dest: nodeLogDestination,
|
|
@@ -29,7 +33,11 @@ function getViteConfig(inlineConfig) {
|
|
|
29
33
|
await runHookConfigSetup({ settings, command: cmd, logging });
|
|
30
34
|
const viteConfig = await createVite(
|
|
31
35
|
{
|
|
32
|
-
mode
|
|
36
|
+
mode,
|
|
37
|
+
plugins: [
|
|
38
|
+
// Initialize the content listener
|
|
39
|
+
astroContentListenPlugin({ settings, logging, fs })
|
|
40
|
+
]
|
|
33
41
|
},
|
|
34
42
|
{ settings, logging, mode }
|
|
35
43
|
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type fsMod from 'node:fs';
|
|
3
|
+
import type { Plugin } from 'vite';
|
|
4
|
+
import type { AstroSettings } from '../@types/astro';
|
|
5
|
+
import type { LogOptions } from '../core/logger/core.js';
|
|
6
|
+
/**
|
|
7
|
+
* Listen for Astro content directory changes and generate types.
|
|
8
|
+
*
|
|
9
|
+
* This is a separate plugin for `getViteConfig` as the `attachContentServerListeners` API
|
|
10
|
+
* needs to be called at different times in `astro dev` and `getViteConfig`. For `astro dev`,
|
|
11
|
+
* it needs to be called after the Astro server is started (packages/astro/src/core/dev/dev.ts).
|
|
12
|
+
* For `getViteConfig`, it needs to be called after the Vite server is started.
|
|
13
|
+
*/
|
|
14
|
+
export declare function astroContentListenPlugin({ settings, logging, fs, }: {
|
|
15
|
+
settings: AstroSettings;
|
|
16
|
+
logging: LogOptions;
|
|
17
|
+
fs: typeof fsMod;
|
|
18
|
+
}): Plugin;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { attachContentServerListeners } from "../content/server-listeners.js";
|
|
2
|
+
function astroContentListenPlugin({
|
|
3
|
+
settings,
|
|
4
|
+
logging,
|
|
5
|
+
fs
|
|
6
|
+
}) {
|
|
7
|
+
let server;
|
|
8
|
+
return {
|
|
9
|
+
name: "astro:content-listen",
|
|
10
|
+
apply: "serve",
|
|
11
|
+
configureServer(_server) {
|
|
12
|
+
server = _server;
|
|
13
|
+
},
|
|
14
|
+
async buildStart() {
|
|
15
|
+
await attachContentServerListeners({
|
|
16
|
+
fs,
|
|
17
|
+
settings,
|
|
18
|
+
logging,
|
|
19
|
+
viteServer: server
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
astroContentListenPlugin
|
|
26
|
+
};
|
package/dist/content/consts.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export declare const PROPAGATED_ASSET_FLAG = "astroPropagatedAssets";
|
|
2
|
+
export declare const CONTENT_RENDER_FLAG = "astroRenderContent";
|
|
2
3
|
export declare const CONTENT_FLAG = "astroContentCollectionEntry";
|
|
3
4
|
export declare const DATA_FLAG = "astroDataCollectionEntry";
|
|
4
|
-
export declare const CONTENT_FLAGS: readonly ["astroContentCollectionEntry", "astroDataCollectionEntry", "astroPropagatedAssets"];
|
|
5
5
|
export declare const VIRTUAL_MODULE_ID = "astro:content";
|
|
6
6
|
export declare const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
|
|
7
7
|
export declare const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
|
|
8
8
|
export declare const SCRIPTS_PLACEHOLDER = "@@ASTRO-SCRIPTS@@";
|
|
9
|
+
export declare const CONTENT_FLAGS: readonly ["astroContentCollectionEntry", "astroRenderContent", "astroDataCollectionEntry", "astroPropagatedAssets"];
|
|
9
10
|
export declare const CONTENT_TYPES_FILE = "types.d.ts";
|
package/dist/content/consts.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
const PROPAGATED_ASSET_FLAG = "astroPropagatedAssets";
|
|
2
|
+
const CONTENT_RENDER_FLAG = "astroRenderContent";
|
|
2
3
|
const CONTENT_FLAG = "astroContentCollectionEntry";
|
|
3
4
|
const DATA_FLAG = "astroDataCollectionEntry";
|
|
4
|
-
const CONTENT_FLAGS = [CONTENT_FLAG, DATA_FLAG, PROPAGATED_ASSET_FLAG];
|
|
5
5
|
const VIRTUAL_MODULE_ID = "astro:content";
|
|
6
6
|
const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
|
|
7
7
|
const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
|
|
8
8
|
const SCRIPTS_PLACEHOLDER = "@@ASTRO-SCRIPTS@@";
|
|
9
|
+
const CONTENT_FLAGS = [
|
|
10
|
+
CONTENT_FLAG,
|
|
11
|
+
CONTENT_RENDER_FLAG,
|
|
12
|
+
DATA_FLAG,
|
|
13
|
+
PROPAGATED_ASSET_FLAG
|
|
14
|
+
];
|
|
9
15
|
const CONTENT_TYPES_FILE = "types.d.ts";
|
|
10
16
|
export {
|
|
11
17
|
CONTENT_FLAG,
|
|
12
18
|
CONTENT_FLAGS,
|
|
19
|
+
CONTENT_RENDER_FLAG,
|
|
13
20
|
CONTENT_TYPES_FILE,
|
|
14
21
|
DATA_FLAG,
|
|
15
22
|
LINKS_PLACEHOLDER,
|
package/dist/content/runtime.js
CHANGED
|
@@ -184,7 +184,7 @@ async function render({
|
|
|
184
184
|
id,
|
|
185
185
|
renderEntryImport
|
|
186
186
|
}) {
|
|
187
|
-
var _a;
|
|
187
|
+
var _a, _b;
|
|
188
188
|
const UnexpectedRenderError = new AstroError({
|
|
189
189
|
...AstroErrorData.UnknownContentCollectionError,
|
|
190
190
|
message: `Unexpected error while rendering ${String(collection)} \u2192 ${String(id)}.`
|
|
@@ -194,53 +194,70 @@ async function render({
|
|
|
194
194
|
const baseMod = await renderEntryImport();
|
|
195
195
|
if (baseMod == null || typeof baseMod !== "object")
|
|
196
196
|
throw UnexpectedRenderError;
|
|
197
|
-
const {
|
|
198
|
-
if (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
197
|
+
const { default: defaultMod } = baseMod;
|
|
198
|
+
if (isPropagatedAssetsModule(defaultMod)) {
|
|
199
|
+
const { collectedStyles, collectedLinks, collectedScripts, getMod } = defaultMod;
|
|
200
|
+
if (typeof getMod !== "function")
|
|
201
|
+
throw UnexpectedRenderError;
|
|
202
|
+
const propagationMod = await getMod();
|
|
203
|
+
if (propagationMod == null || typeof propagationMod !== "object")
|
|
204
|
+
throw UnexpectedRenderError;
|
|
205
|
+
const Content = createComponent({
|
|
206
|
+
factory(result, baseProps, slots) {
|
|
207
|
+
let styles = "", links = "", scripts = "";
|
|
208
|
+
if (Array.isArray(collectedStyles)) {
|
|
209
|
+
styles = collectedStyles.map((style) => {
|
|
210
|
+
return renderUniqueStylesheet(result, {
|
|
211
|
+
type: "inline",
|
|
212
|
+
content: style
|
|
213
|
+
});
|
|
214
|
+
}).join("");
|
|
215
|
+
}
|
|
216
|
+
if (Array.isArray(collectedLinks)) {
|
|
217
|
+
links = collectedLinks.map((link) => {
|
|
218
|
+
return renderUniqueStylesheet(result, {
|
|
219
|
+
type: "external",
|
|
220
|
+
src: prependForwardSlash(link)
|
|
221
|
+
});
|
|
222
|
+
}).join("");
|
|
223
|
+
}
|
|
224
|
+
if (Array.isArray(collectedScripts)) {
|
|
225
|
+
scripts = collectedScripts.map((script) => renderScriptElement(script)).join("");
|
|
226
|
+
}
|
|
227
|
+
let props = baseProps;
|
|
228
|
+
if (id.endsWith("mdx")) {
|
|
229
|
+
props = {
|
|
230
|
+
components: propagationMod.components ?? {},
|
|
231
|
+
...baseProps
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return createHeadAndContent(
|
|
235
|
+
unescapeHTML(styles + links + scripts),
|
|
236
|
+
renderTemplate`${renderComponent(
|
|
237
|
+
result,
|
|
238
|
+
"Content",
|
|
239
|
+
propagationMod.Content,
|
|
240
|
+
props,
|
|
241
|
+
slots
|
|
242
|
+
)}`
|
|
243
|
+
);
|
|
244
|
+
},
|
|
245
|
+
propagation: "self"
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
Content,
|
|
249
|
+
headings: ((_a = propagationMod.getHeadings) == null ? void 0 : _a.call(propagationMod)) ?? [],
|
|
250
|
+
remarkPluginFrontmatter: propagationMod.frontmatter ?? {}
|
|
251
|
+
};
|
|
252
|
+
} else if (baseMod.Content && typeof baseMod.Content === "function") {
|
|
253
|
+
return {
|
|
254
|
+
Content: baseMod.Content,
|
|
255
|
+
headings: ((_b = baseMod.getHeadings) == null ? void 0 : _b.call(baseMod)) ?? [],
|
|
256
|
+
remarkPluginFrontmatter: baseMod.frontmatter ?? {}
|
|
257
|
+
};
|
|
258
|
+
} else {
|
|
202
259
|
throw UnexpectedRenderError;
|
|
203
|
-
|
|
204
|
-
factory(result, baseProps, slots) {
|
|
205
|
-
let styles = "", links = "", scripts = "";
|
|
206
|
-
if (Array.isArray(collectedStyles)) {
|
|
207
|
-
styles = collectedStyles.map((style) => {
|
|
208
|
-
return renderUniqueStylesheet(result, {
|
|
209
|
-
type: "inline",
|
|
210
|
-
content: style
|
|
211
|
-
});
|
|
212
|
-
}).join("");
|
|
213
|
-
}
|
|
214
|
-
if (Array.isArray(collectedLinks)) {
|
|
215
|
-
links = collectedLinks.map((link) => {
|
|
216
|
-
return renderUniqueStylesheet(result, {
|
|
217
|
-
type: "external",
|
|
218
|
-
src: prependForwardSlash(link)
|
|
219
|
-
});
|
|
220
|
-
}).join("");
|
|
221
|
-
}
|
|
222
|
-
if (Array.isArray(collectedScripts)) {
|
|
223
|
-
scripts = collectedScripts.map((script) => renderScriptElement(script)).join("");
|
|
224
|
-
}
|
|
225
|
-
let props = baseProps;
|
|
226
|
-
if (id.endsWith(".mdx")) {
|
|
227
|
-
props = {
|
|
228
|
-
components: mod.components ?? {},
|
|
229
|
-
...baseProps
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
return createHeadAndContent(
|
|
233
|
-
unescapeHTML(styles + links + scripts),
|
|
234
|
-
renderTemplate`${renderComponent(result, "Content", mod.Content, props, slots)}`
|
|
235
|
-
);
|
|
236
|
-
},
|
|
237
|
-
propagation: "self"
|
|
238
|
-
});
|
|
239
|
-
return {
|
|
240
|
-
Content,
|
|
241
|
-
headings: ((_a = mod.getHeadings) == null ? void 0 : _a.call(mod)) ?? [],
|
|
242
|
-
remarkPluginFrontmatter: mod.frontmatter ?? {}
|
|
243
|
-
};
|
|
260
|
+
}
|
|
244
261
|
}
|
|
245
262
|
function createReference({ lookupMap }) {
|
|
246
263
|
return function reference(collection) {
|
|
@@ -271,6 +288,9 @@ function createReference({ lookupMap }) {
|
|
|
271
288
|
});
|
|
272
289
|
};
|
|
273
290
|
}
|
|
291
|
+
function isPropagatedAssetsModule(module) {
|
|
292
|
+
return typeof module === "object" && module != null && "__astroPropagation" in module;
|
|
293
|
+
}
|
|
274
294
|
export {
|
|
275
295
|
createCollectionToGlobResultMap,
|
|
276
296
|
createGetCollection,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { extname } from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
2
3
|
import { moduleIsTopLevelPage, walkParentInfos } from "../core/build/graph.js";
|
|
3
4
|
import { getPageDataByViteID } from "../core/build/internal.js";
|
|
4
5
|
import { createViteLoader } from "../core/module-loader/vite.js";
|
|
@@ -6,15 +7,13 @@ import { joinPaths, prependForwardSlash } from "../core/path.js";
|
|
|
6
7
|
import { getStylesForURL } from "../core/render/dev/css.js";
|
|
7
8
|
import { getScriptsForURL } from "../core/render/dev/scripts.js";
|
|
8
9
|
import {
|
|
10
|
+
CONTENT_RENDER_FLAG,
|
|
9
11
|
LINKS_PLACEHOLDER,
|
|
10
12
|
PROPAGATED_ASSET_FLAG,
|
|
11
13
|
SCRIPTS_PLACEHOLDER,
|
|
12
14
|
STYLES_PLACEHOLDER
|
|
13
15
|
} from "./consts.js";
|
|
14
|
-
|
|
15
|
-
const flags = new URLSearchParams(viteId.split("?")[1]);
|
|
16
|
-
return flags.has(PROPAGATED_ASSET_FLAG);
|
|
17
|
-
}
|
|
16
|
+
import { hasContentFlag } from "./utils.js";
|
|
18
17
|
function astroContentAssetPropagationPlugin({
|
|
19
18
|
mode,
|
|
20
19
|
settings
|
|
@@ -22,6 +21,21 @@ function astroContentAssetPropagationPlugin({
|
|
|
22
21
|
let devModuleLoader;
|
|
23
22
|
return {
|
|
24
23
|
name: "astro:content-asset-propagation",
|
|
24
|
+
enforce: "pre",
|
|
25
|
+
async resolveId(id, importer, opts) {
|
|
26
|
+
if (hasContentFlag(id, CONTENT_RENDER_FLAG)) {
|
|
27
|
+
const base = id.split("?")[0];
|
|
28
|
+
for (const { extensions, handlePropagation = true } of settings.contentEntryTypes) {
|
|
29
|
+
if (handlePropagation && extensions.includes(extname(base))) {
|
|
30
|
+
return this.resolve(`${base}?${PROPAGATED_ASSET_FLAG}`, importer, {
|
|
31
|
+
skipSelf: true,
|
|
32
|
+
...opts
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return this.resolve(base, importer, { skipSelf: true, ...opts });
|
|
37
|
+
}
|
|
38
|
+
},
|
|
25
39
|
configureServer(server) {
|
|
26
40
|
if (mode === "dev") {
|
|
27
41
|
devModuleLoader = createViteLoader(server);
|
|
@@ -29,7 +43,7 @@ function astroContentAssetPropagationPlugin({
|
|
|
29
43
|
},
|
|
30
44
|
async transform(_, id, options) {
|
|
31
45
|
var _a;
|
|
32
|
-
if (
|
|
46
|
+
if (hasContentFlag(id, PROPAGATED_ASSET_FLAG)) {
|
|
33
47
|
const basePath = id.split("?")[0];
|
|
34
48
|
let stringifiedLinks, stringifiedStyles, stringifiedScripts;
|
|
35
49
|
if ((options == null ? void 0 : options.ssr) && devModuleLoader) {
|
|
@@ -55,12 +69,14 @@ function astroContentAssetPropagationPlugin({
|
|
|
55
69
|
stringifiedScripts = JSON.stringify(SCRIPTS_PLACEHOLDER);
|
|
56
70
|
}
|
|
57
71
|
const code = `
|
|
58
|
-
|
|
72
|
+
async function getMod() {
|
|
59
73
|
return import(${JSON.stringify(basePath)});
|
|
60
74
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
const collectedLinks = ${stringifiedLinks};
|
|
76
|
+
const collectedStyles = ${stringifiedStyles};
|
|
77
|
+
const collectedScripts = ${stringifiedScripts};
|
|
78
|
+
const defaultMod = { __astroPropagation: true, getMod, collectedLinks, collectedStyles, collectedScripts };
|
|
79
|
+
export default defaultMod;
|
|
64
80
|
`;
|
|
65
81
|
return { code, map: { mappings: "" } };
|
|
66
82
|
}
|
|
@@ -29,15 +29,20 @@ function astroContentVirtualModPlugin({
|
|
|
29
29
|
"@@COLLECTION_NAME_BY_REFERENCE_KEY@@",
|
|
30
30
|
new URL("reference-map.json", contentPaths.cacheDir).pathname
|
|
31
31
|
).replace("@@CONTENT_DIR@@", relContentDir).replace(
|
|
32
|
-
"@@CONTENT_ENTRY_GLOB_PATH@@",
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
"'@@CONTENT_ENTRY_GLOB_PATH@@'",
|
|
33
|
+
JSON.stringify(globWithUnderscoresIgnored(relContentDir, contentEntryExts))
|
|
34
|
+
).replace(
|
|
35
|
+
"'@@DATA_ENTRY_GLOB_PATH@@'",
|
|
36
|
+
JSON.stringify(globWithUnderscoresIgnored(relContentDir, dataEntryExts))
|
|
37
|
+
).replace(
|
|
38
|
+
"'@@RENDER_ENTRY_GLOB_PATH@@'",
|
|
39
|
+
JSON.stringify(
|
|
40
|
+
globWithUnderscoresIgnored(
|
|
41
|
+
relContentDir,
|
|
42
|
+
/** Note: data collections excluded */
|
|
43
|
+
contentEntryExts
|
|
44
|
+
)
|
|
45
|
+
)
|
|
41
46
|
);
|
|
42
47
|
const astroContentVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
|
|
43
48
|
return {
|
|
@@ -150,6 +155,10 @@ const UnexpectedLookupMapError = new AstroError({
|
|
|
150
155
|
...AstroErrorData.UnknownContentCollectionError,
|
|
151
156
|
message: `Unexpected error while parsing content entry IDs and slugs.`
|
|
152
157
|
});
|
|
158
|
+
function globWithUnderscoresIgnored(relContentDir, exts) {
|
|
159
|
+
const extGlob = getExtGlob(exts);
|
|
160
|
+
return [`${relContentDir}/**/*${extGlob}`, `!**/_*/**${extGlob}`, `!**/_*${extGlob}`];
|
|
161
|
+
}
|
|
153
162
|
export {
|
|
154
163
|
astroContentVirtualModPlugin,
|
|
155
164
|
getStringifiedLookupMap
|