astro 4.8.7 → 4.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/dist/@types/astro.d.ts +43 -96
- package/dist/actions/runtime/middleware.d.ts +1 -0
- package/dist/actions/runtime/middleware.js +27 -25
- package/dist/actions/runtime/route.js +1 -2
- package/dist/actions/runtime/utils.d.ts +6 -1
- package/dist/actions/runtime/utils.js +2 -1
- package/dist/actions/runtime/virtual/server.d.ts +4 -2
- package/dist/actions/runtime/virtual/server.js +9 -11
- package/dist/actions/utils.d.ts +2 -0
- package/dist/actions/utils.js +2 -1
- package/dist/container/index.d.ts +162 -0
- package/dist/container/index.js +234 -0
- package/dist/container/pipeline.d.ts +11 -0
- package/dist/container/pipeline.js +96 -0
- package/dist/core/app/node.js +4 -1
- package/dist/core/build/generate.js +3 -3
- package/dist/core/build/plugins/plugin-manifest.js +2 -2
- package/dist/core/config/schema.d.ts +92 -120
- package/dist/core/config/schema.js +18 -23
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.d.ts +1 -1
- package/dist/core/render-context.js +6 -3
- package/dist/core/routing/manifest/create.d.ts +4 -1
- package/dist/core/routing/manifest/create.js +10 -8
- package/dist/integrations/features-validation.js +1 -1
- package/dist/vite-plugin-astro-server/plugin.d.ts +0 -1
- package/dist/vite-plugin-astro-server/plugin.js +1 -1
- package/package.json +7 -3
- package/templates/actions.mjs +37 -12
package/dist/@types/astro.d.ts
CHANGED
|
@@ -676,6 +676,47 @@ export interface AstroUserConfig {
|
|
|
676
676
|
* Using `'attribute'` is useful when you are manipulating the `class` attribute of elements and need to avoid conflicts between your own styling logic and Astro's application of styles.
|
|
677
677
|
*/
|
|
678
678
|
scopedStyleStrategy?: 'where' | 'class' | 'attribute';
|
|
679
|
+
/**
|
|
680
|
+
* @docs
|
|
681
|
+
* @name security
|
|
682
|
+
* @type {boolean}
|
|
683
|
+
* @default `{}`
|
|
684
|
+
* @version 4.9.0
|
|
685
|
+
* @description
|
|
686
|
+
*
|
|
687
|
+
* Enables security measures for an Astro website.
|
|
688
|
+
*
|
|
689
|
+
* These features only exist for pages rendered on demand (SSR) using `server` mode or pages that opt out of prerendering in `hybrid` mode.
|
|
690
|
+
*
|
|
691
|
+
* ```js
|
|
692
|
+
* // astro.config.mjs
|
|
693
|
+
* export default defineConfig({
|
|
694
|
+
* output: "server",
|
|
695
|
+
* security: {
|
|
696
|
+
* checkOrigin: true
|
|
697
|
+
* }
|
|
698
|
+
* })
|
|
699
|
+
* ```
|
|
700
|
+
*/
|
|
701
|
+
security?: {
|
|
702
|
+
/**
|
|
703
|
+
* @docs
|
|
704
|
+
* @name security.checkOrigin
|
|
705
|
+
* @kind h4
|
|
706
|
+
* @type {boolean}
|
|
707
|
+
* @default 'false'
|
|
708
|
+
* @version 4.9.0
|
|
709
|
+
* @description
|
|
710
|
+
*
|
|
711
|
+
* When enabled, performs a check that the "origin" header, automatically passed by all modern browsers, matches the URL sent by each `Request`. This is used to provide Cross-Site Request Forgery (CSRF) protection.
|
|
712
|
+
*
|
|
713
|
+
* The "origin" check is executed only for pages rendered on demand, and only for the requests `POST`, `PATCH`, `DELETE` and `PUT` with
|
|
714
|
+
* one of the following `content-type` headers: `'application/x-www-form-urlencoded'`, `'multipart/form-data'`, `'text/plain'`.
|
|
715
|
+
*
|
|
716
|
+
* If the "origin" header doesn't match the `pathname` of the request, Astro will return a 403 status code and will not render the page.
|
|
717
|
+
*/
|
|
718
|
+
checkOrigin?: boolean;
|
|
719
|
+
};
|
|
679
720
|
/**
|
|
680
721
|
* @docs
|
|
681
722
|
* @name vite
|
|
@@ -1820,102 +1861,6 @@ export interface AstroUserConfig {
|
|
|
1820
1861
|
* In the event of route collisions, where two routes of equal route priority attempt to build the same URL, Astro will log a warning identifying the conflicting routes.
|
|
1821
1862
|
*/
|
|
1822
1863
|
globalRoutePriority?: boolean;
|
|
1823
|
-
/**
|
|
1824
|
-
* @docs
|
|
1825
|
-
* @name experimental.i18nDomains
|
|
1826
|
-
* @type {boolean}
|
|
1827
|
-
* @default `false`
|
|
1828
|
-
* @version 4.3.0
|
|
1829
|
-
* @description
|
|
1830
|
-
*
|
|
1831
|
-
* Enables domain support for the [experimental `domains` routing strategy](https://docs.astro.build/en/guides/internationalization/#domains-experimental) which allows you to configure the URL pattern of one or more supported languages to use a custom domain (or sub-domain).
|
|
1832
|
-
*
|
|
1833
|
-
* When a locale is mapped to a domain, a `/[locale]/` path prefix will not be used. However, localized folders within `src/pages/` are still required, including for your configured `defaultLocale`.
|
|
1834
|
-
*
|
|
1835
|
-
* Any other locale not configured will default to a localized path-based URL according to your `prefixDefaultLocale` strategy (e.g. `https://example.com/[locale]/blog`).
|
|
1836
|
-
*
|
|
1837
|
-
* ```js
|
|
1838
|
-
* //astro.config.mjs
|
|
1839
|
-
* export default defineConfig({
|
|
1840
|
-
* site: "https://example.com",
|
|
1841
|
-
* output: "server", // required, with no prerendered pages
|
|
1842
|
-
* adapter: node({
|
|
1843
|
-
* mode: 'standalone',
|
|
1844
|
-
* }),
|
|
1845
|
-
* i18n: {
|
|
1846
|
-
* defaultLocale: "en",
|
|
1847
|
-
* locales: ["en", "fr", "pt-br", "es"],
|
|
1848
|
-
* prefixDefaultLocale: false,
|
|
1849
|
-
* domains: {
|
|
1850
|
-
* fr: "https://fr.example.com",
|
|
1851
|
-
* es: "https://example.es",
|
|
1852
|
-
* },
|
|
1853
|
-
* },
|
|
1854
|
-
* experimental: {
|
|
1855
|
-
* i18nDomains: true,
|
|
1856
|
-
* },
|
|
1857
|
-
* });
|
|
1858
|
-
* ```
|
|
1859
|
-
*
|
|
1860
|
-
* Both page routes built and URLs returned by the `astro:i18n` helper functions [`getAbsoluteLocaleUrl()`](https://docs.astro.build/en/reference/api-reference/#getabsolutelocaleurl) and [`getAbsoluteLocaleUrlList()`](https://docs.astro.build/en/reference/api-reference/#getabsolutelocaleurllist) will use the options set in `i18n.domains`.
|
|
1861
|
-
*
|
|
1862
|
-
* See the [Internationalization Guide](https://docs.astro.build/en/guides/internationalization/#domains-experimental) for more details, including the limitations of this experimental feature.
|
|
1863
|
-
*/
|
|
1864
|
-
i18nDomains?: boolean;
|
|
1865
|
-
/**
|
|
1866
|
-
* @docs
|
|
1867
|
-
* @name experimental.security
|
|
1868
|
-
* @type {boolean}
|
|
1869
|
-
* @default `false`
|
|
1870
|
-
* @version 4.6.0
|
|
1871
|
-
* @description
|
|
1872
|
-
*
|
|
1873
|
-
* Enables CSRF protection for Astro websites.
|
|
1874
|
-
*
|
|
1875
|
-
* The CSRF protection works only for pages rendered on demand (SSR) using `server` or `hybrid` mode. The pages must opt out of prerendering in `hybrid` mode.
|
|
1876
|
-
*
|
|
1877
|
-
* ```js
|
|
1878
|
-
* // astro.config.mjs
|
|
1879
|
-
* export default defineConfig({
|
|
1880
|
-
* output: "server",
|
|
1881
|
-
* experimental: {
|
|
1882
|
-
* security: {
|
|
1883
|
-
* csrfProtection: {
|
|
1884
|
-
* origin: true
|
|
1885
|
-
* }
|
|
1886
|
-
* }
|
|
1887
|
-
* }
|
|
1888
|
-
* })
|
|
1889
|
-
* ```
|
|
1890
|
-
*/
|
|
1891
|
-
security?: {
|
|
1892
|
-
/**
|
|
1893
|
-
* @name security.csrfProtection
|
|
1894
|
-
* @type {object}
|
|
1895
|
-
* @default '{}'
|
|
1896
|
-
* @version 4.6.0
|
|
1897
|
-
* @description
|
|
1898
|
-
*
|
|
1899
|
-
* Allows you to enable security measures to prevent CSRF attacks: https://owasp.org/www-community/attacks/csrf
|
|
1900
|
-
*/
|
|
1901
|
-
csrfProtection?: {
|
|
1902
|
-
/**
|
|
1903
|
-
* @name security.csrfProtection.origin
|
|
1904
|
-
* @type {boolean}
|
|
1905
|
-
* @default 'false'
|
|
1906
|
-
* @version 4.6.0
|
|
1907
|
-
* @description
|
|
1908
|
-
*
|
|
1909
|
-
* When enabled, performs a check that the "origin" header, automatically passed by all modern browsers, matches the URL sent by each `Request`.
|
|
1910
|
-
*
|
|
1911
|
-
* The "origin" check is executed only for pages rendered on demand, and only for the requests `POST, `PATCH`, `DELETE` and `PUT` with
|
|
1912
|
-
* the following `content-type` header: 'application/x-www-form-urlencoded', 'multipart/form-data', 'text/plain'.
|
|
1913
|
-
*
|
|
1914
|
-
* If the "origin" header doesn't match the `pathname` of the request, Astro will return a 403 status code and will not render the page.
|
|
1915
|
-
*/
|
|
1916
|
-
origin?: boolean;
|
|
1917
|
-
};
|
|
1918
|
-
};
|
|
1919
1864
|
/**
|
|
1920
1865
|
* @docs
|
|
1921
1866
|
* @name experimental.rewriting
|
|
@@ -2848,6 +2793,8 @@ export interface SSRResult {
|
|
|
2848
2793
|
createAstro(Astro: AstroGlobalPartial, props: Record<string, any>, slots: Record<string, any> | null): AstroGlobal;
|
|
2849
2794
|
resolve: (s: string) => Promise<string>;
|
|
2850
2795
|
response: AstroGlobal['response'];
|
|
2796
|
+
request: AstroGlobal['request'];
|
|
2797
|
+
actionResult?: ReturnType<AstroGlobal['getActionResult']>;
|
|
2851
2798
|
renderers: SSRLoadedRenderer[];
|
|
2852
2799
|
/**
|
|
2853
2800
|
* Map of directive name (e.g. `load`) to the directive script code
|
|
@@ -2,6 +2,7 @@ import type { APIContext } from '../../@types/astro.js';
|
|
|
2
2
|
export type Locals = {
|
|
3
3
|
_actionsInternal: {
|
|
4
4
|
getActionResult: APIContext['getActionResult'];
|
|
5
|
+
actionResult?: ReturnType<APIContext['getActionResult']>;
|
|
5
6
|
};
|
|
6
7
|
};
|
|
7
8
|
export declare const onRequest: import("../../@types/astro.js").MiddlewareHandler;
|
|
@@ -5,45 +5,47 @@ import { formContentTypes, getAction, hasContentType } from "./utils.js";
|
|
|
5
5
|
import { callSafely } from "./virtual/shared.js";
|
|
6
6
|
const onRequest = defineMiddleware(async (context, next) => {
|
|
7
7
|
const locals = context.locals;
|
|
8
|
+
if (locals._actionsInternal) return ApiContextStorage.run(context, () => next());
|
|
8
9
|
if (context.request.method === "GET") {
|
|
9
|
-
return nextWithLocalsStub(next,
|
|
10
|
+
return nextWithLocalsStub(next, context);
|
|
10
11
|
}
|
|
11
12
|
if (context.request.method === "POST" && context.request.body === null) {
|
|
12
|
-
return nextWithStaticStub(next,
|
|
13
|
+
return nextWithStaticStub(next, context);
|
|
13
14
|
}
|
|
14
|
-
if (locals._actionsInternal) return next();
|
|
15
15
|
const { request, url } = context;
|
|
16
16
|
const contentType = request.headers.get("Content-Type");
|
|
17
|
-
if (url.pathname.startsWith("/_actions")) return nextWithLocalsStub(next,
|
|
17
|
+
if (url.pathname.startsWith("/_actions")) return nextWithLocalsStub(next, context);
|
|
18
18
|
if (!contentType || !hasContentType(contentType, formContentTypes)) {
|
|
19
|
-
return nextWithLocalsStub(next,
|
|
19
|
+
return nextWithLocalsStub(next, context);
|
|
20
20
|
}
|
|
21
21
|
const formData = await request.clone().formData();
|
|
22
22
|
const actionPath = formData.get("_astroAction");
|
|
23
|
-
if (typeof actionPath !== "string") return nextWithLocalsStub(next,
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
if (!action) return nextWithLocalsStub(next, locals);
|
|
23
|
+
if (typeof actionPath !== "string") return nextWithLocalsStub(next, context);
|
|
24
|
+
const action = await getAction(actionPath);
|
|
25
|
+
if (!action) return nextWithLocalsStub(next, context);
|
|
27
26
|
const result = await ApiContextStorage.run(context, () => callSafely(() => action(formData)));
|
|
28
27
|
const actionsInternal = {
|
|
29
28
|
getActionResult: (actionFn) => {
|
|
30
29
|
if (actionFn.toString() !== actionPath) return Promise.resolve(void 0);
|
|
31
30
|
return result;
|
|
32
|
-
}
|
|
31
|
+
},
|
|
32
|
+
actionResult: result
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(locals, "_actionsInternal", { writable: false, value: actionsInternal });
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
return ApiContextStorage.run(context, async () => {
|
|
36
|
+
const response = await next();
|
|
37
|
+
if (result.error) {
|
|
38
|
+
return new Response(response.body, {
|
|
39
|
+
status: result.error.status,
|
|
40
|
+
statusText: result.error.name,
|
|
41
|
+
headers: response.headers
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return response;
|
|
45
|
+
});
|
|
44
46
|
});
|
|
45
|
-
function nextWithStaticStub(next,
|
|
46
|
-
Object.defineProperty(locals, "_actionsInternal", {
|
|
47
|
+
function nextWithStaticStub(next, context) {
|
|
48
|
+
Object.defineProperty(context.locals, "_actionsInternal", {
|
|
47
49
|
writable: false,
|
|
48
50
|
value: {
|
|
49
51
|
getActionResult: () => {
|
|
@@ -55,16 +57,16 @@ function nextWithStaticStub(next, locals) {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
});
|
|
58
|
-
return next();
|
|
60
|
+
return ApiContextStorage.run(context, () => next());
|
|
59
61
|
}
|
|
60
|
-
function nextWithLocalsStub(next,
|
|
61
|
-
Object.defineProperty(locals, "_actionsInternal", {
|
|
62
|
+
function nextWithLocalsStub(next, context) {
|
|
63
|
+
Object.defineProperty(context.locals, "_actionsInternal", {
|
|
62
64
|
writable: false,
|
|
63
65
|
value: {
|
|
64
66
|
getActionResult: () => void 0
|
|
65
67
|
}
|
|
66
68
|
});
|
|
67
|
-
return next();
|
|
69
|
+
return ApiContextStorage.run(context, () => next());
|
|
68
70
|
}
|
|
69
71
|
export {
|
|
70
72
|
onRequest
|
|
@@ -3,8 +3,7 @@ import { formContentTypes, getAction, hasContentType } from "./utils.js";
|
|
|
3
3
|
import { callSafely } from "./virtual/shared.js";
|
|
4
4
|
const POST = async (context) => {
|
|
5
5
|
const { request, url } = context;
|
|
6
|
-
const
|
|
7
|
-
const action = await getAction(actionPathKeys);
|
|
6
|
+
const action = await getAction(url.pathname);
|
|
8
7
|
if (!action) {
|
|
9
8
|
return new Response(null, { status: 404 });
|
|
10
9
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export declare const formContentTypes: string[];
|
|
2
2
|
export declare function hasContentType(contentType: string, expected: string[]): boolean;
|
|
3
3
|
export type MaybePromise<T> = T | Promise<T>;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Get server-side action based on the route path.
|
|
6
|
+
* Imports from `import.meta.env.ACTIONS_PATH`, which maps to
|
|
7
|
+
* the user's `src/actions/index.ts` file at build-time.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAction(path: string): Promise<((param: unknown) => MaybePromise<unknown>) | undefined>;
|
|
@@ -3,7 +3,8 @@ function hasContentType(contentType, expected) {
|
|
|
3
3
|
const type = contentType.split(";")[0].toLowerCase();
|
|
4
4
|
return expected.some((t) => type === t);
|
|
5
5
|
}
|
|
6
|
-
async function getAction(
|
|
6
|
+
async function getAction(path) {
|
|
7
|
+
const pathKeys = path.replace("/_actions/", "").split(".");
|
|
7
8
|
let { server: actionLookup } = await import(import.meta.env.ACTIONS_PATH);
|
|
8
9
|
for (const key of pathKeys) {
|
|
9
10
|
if (!(key in actionLookup)) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { type ActionAPIContext, getApiContext as _getApiContext } from '../store.js';
|
|
2
3
|
import { type MaybePromise } from '../utils.js';
|
|
3
4
|
import { type ErrorInferenceObject, type SafeResult } from './shared.js';
|
|
4
5
|
export * from './shared.js';
|
|
5
6
|
export { z } from 'zod';
|
|
6
|
-
|
|
7
|
+
/** @deprecated Access context from the second `handler()` parameter. */
|
|
8
|
+
export declare const getApiContext: typeof _getApiContext;
|
|
7
9
|
export type Accept = 'form' | 'json';
|
|
8
10
|
export type InputSchema<T extends Accept> = T extends 'form' ? z.AnyZodObject | z.ZodType<FormData> : z.ZodType;
|
|
9
|
-
type Handler<TInputSchema, TOutput> = TInputSchema extends z.ZodType ? (input: z.infer<TInputSchema
|
|
11
|
+
type Handler<TInputSchema, TOutput> = TInputSchema extends z.ZodType ? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput> : (input: any, context: ActionAPIContext) => MaybePromise<TOutput>;
|
|
10
12
|
export type ActionClient<TOutput, TAccept extends Accept, TInputSchema extends InputSchema<TAccept> | undefined> = TInputSchema extends z.ZodType ? ((input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<Awaited<TOutput>>) & {
|
|
11
13
|
safe: (input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<SafeResult<z.input<TInputSchema> extends ErrorInferenceObject ? z.input<TInputSchema> : ErrorInferenceObject, Awaited<TOutput>>>;
|
|
12
14
|
} : ((input?: any) => Promise<Awaited<TOutput>>) & {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { getApiContext } from "../store.js";
|
|
3
|
-
import {
|
|
2
|
+
import { getApiContext as _getApiContext } from "../store.js";
|
|
3
|
+
import {} from "../utils.js";
|
|
4
4
|
import {
|
|
5
5
|
ActionError,
|
|
6
6
|
ActionInputError,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./shared.js";
|
|
9
9
|
export * from "./shared.js";
|
|
10
10
|
import { z as z2 } from "zod";
|
|
11
|
-
|
|
11
|
+
const getApiContext = _getApiContext;
|
|
12
12
|
function defineAction({
|
|
13
13
|
accept,
|
|
14
14
|
input: inputSchema,
|
|
@@ -30,30 +30,28 @@ function getFormServerHandler(handler, inputSchema) {
|
|
|
30
30
|
message: "This action only accepts FormData."
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
if (!(inputSchema instanceof z.ZodObject)) return await handler(unparsedInput);
|
|
33
|
+
if (!(inputSchema instanceof z.ZodObject)) return await handler(unparsedInput, getApiContext());
|
|
34
34
|
const parsed = await inputSchema.safeParseAsync(formDataToObject(unparsedInput, inputSchema));
|
|
35
35
|
if (!parsed.success) {
|
|
36
36
|
throw new ActionInputError(parsed.error.issues);
|
|
37
37
|
}
|
|
38
|
-
return await handler(parsed.data);
|
|
38
|
+
return await handler(parsed.data, getApiContext());
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
function getJsonServerHandler(handler, inputSchema) {
|
|
42
42
|
return async (unparsedInput) => {
|
|
43
|
-
|
|
44
|
-
const contentType = context.request.headers.get("content-type");
|
|
45
|
-
if (!contentType || !hasContentType(contentType, ["application/json"])) {
|
|
43
|
+
if (unparsedInput instanceof FormData) {
|
|
46
44
|
throw new ActionError({
|
|
47
45
|
code: "UNSUPPORTED_MEDIA_TYPE",
|
|
48
46
|
message: "This action only accepts JSON."
|
|
49
47
|
});
|
|
50
48
|
}
|
|
51
|
-
if (!inputSchema) return await handler(unparsedInput);
|
|
49
|
+
if (!inputSchema) return await handler(unparsedInput, getApiContext());
|
|
52
50
|
const parsed = await inputSchema.safeParseAsync(unparsedInput);
|
|
53
51
|
if (!parsed.success) {
|
|
54
52
|
throw new ActionInputError(parsed.error.issues);
|
|
55
53
|
}
|
|
56
|
-
return await handler(parsed.data);
|
|
54
|
+
return await handler(parsed.data, getApiContext());
|
|
57
55
|
};
|
|
58
56
|
}
|
|
59
57
|
function formDataToObject(formData, schema) {
|
|
@@ -93,6 +91,6 @@ function handleFormDataGet(key, formData, validator, baseValidator) {
|
|
|
93
91
|
export {
|
|
94
92
|
defineAction,
|
|
95
93
|
formDataToObject,
|
|
96
|
-
|
|
94
|
+
getApiContext,
|
|
97
95
|
z2 as z
|
|
98
96
|
};
|
package/dist/actions/utils.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import type { APIContext } from '../@types/astro.js';
|
|
2
|
+
import type { Locals } from './runtime/middleware.js';
|
|
3
|
+
export declare function hasActionsInternal(locals: APIContext['locals']): locals is Locals;
|
|
2
4
|
export declare function createGetActionResult(locals: APIContext['locals']): APIContext['getActionResult'];
|
package/dist/actions/utils.js
CHANGED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { AstroRenderer, AstroUserConfig, RouteType } from '../@types/astro.js';
|
|
2
|
+
import type { AstroComponentFactory } from '../runtime/server/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options to be passed when rendering a route
|
|
5
|
+
*/
|
|
6
|
+
export type ContainerRenderOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* If your component renders slots, that's where you want to fill the slots.
|
|
9
|
+
* A single slot should have the `default` field:
|
|
10
|
+
*
|
|
11
|
+
* ## Examples
|
|
12
|
+
*
|
|
13
|
+
* **Default slot**
|
|
14
|
+
*
|
|
15
|
+
* ```js
|
|
16
|
+
* container.renderToString(Component, { slots: { default: "Some value"}});
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* **Named slots**
|
|
20
|
+
*
|
|
21
|
+
* ```js
|
|
22
|
+
* container.renderToString(Component, { slots: { "foo": "Some value", "bar": "Lorem Ipsum" }});
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
slots?: Record<string, any>;
|
|
26
|
+
/**
|
|
27
|
+
* The request is used to understand which path/URL the component is about to render.
|
|
28
|
+
*
|
|
29
|
+
* Use this option in case your component or middleware needs to read information like `Astro.url` or `Astro.request`.
|
|
30
|
+
*/
|
|
31
|
+
request?: Request;
|
|
32
|
+
/**
|
|
33
|
+
* Useful for dynamic routes. If your component is something like `src/pages/blog/[id]/[...slug]`, you'll want to provide:
|
|
34
|
+
* ```js
|
|
35
|
+
* container.renderToString(Component, { params: ["id", "...slug"] });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
params?: Record<string, string | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Useful if your component needs to access some locals without the use a middleware.
|
|
41
|
+
* ```js
|
|
42
|
+
* container.renderToString(Component, { locals: { getSomeValue() {} } });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
locals?: App.Locals;
|
|
46
|
+
/**
|
|
47
|
+
* Useful in case you're attempting to render an endpoint:
|
|
48
|
+
* ```js
|
|
49
|
+
* container.renderToString(Endpoint, { routeType: "endpoint" });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
routeType?: RouteType;
|
|
53
|
+
};
|
|
54
|
+
export type AstroContainerUserConfig = Omit<AstroUserConfig, 'integrations' | 'adapter'>;
|
|
55
|
+
/**
|
|
56
|
+
* Options that are used for the entire lifecycle of the current instance of the container.
|
|
57
|
+
*/
|
|
58
|
+
export type AstroContainerOptions = {
|
|
59
|
+
/**
|
|
60
|
+
* @default false
|
|
61
|
+
*
|
|
62
|
+
* @description
|
|
63
|
+
*
|
|
64
|
+
* Enables streaming during rendering
|
|
65
|
+
*
|
|
66
|
+
* ## Example
|
|
67
|
+
*
|
|
68
|
+
* ```js
|
|
69
|
+
* const container = await AstroContainer.create({
|
|
70
|
+
* streaming: true
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
streaming?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* @default []
|
|
77
|
+
* @description
|
|
78
|
+
*
|
|
79
|
+
* List or renderers to use when rendering components. Usually they are entry points
|
|
80
|
+
*
|
|
81
|
+
* ## Example
|
|
82
|
+
*
|
|
83
|
+
* ```js
|
|
84
|
+
* const container = await AstroContainer.create({
|
|
85
|
+
* renderers: [{
|
|
86
|
+
* name: "@astrojs/react"
|
|
87
|
+
* client: "@astrojs/react/client.js"
|
|
88
|
+
* server: "@astrojs/react/server.js"
|
|
89
|
+
* }]
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
renderers?: AstroRenderer[];
|
|
94
|
+
/**
|
|
95
|
+
* @default {}
|
|
96
|
+
* @description
|
|
97
|
+
*
|
|
98
|
+
* A subset of the astro configuration object.
|
|
99
|
+
*
|
|
100
|
+
* ## Example
|
|
101
|
+
*
|
|
102
|
+
* ```js
|
|
103
|
+
* const container = await AstroContainer.create({
|
|
104
|
+
* astroConfig: {
|
|
105
|
+
* trailingSlash: "never"
|
|
106
|
+
* }
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
astroConfig?: AstroContainerUserConfig;
|
|
111
|
+
};
|
|
112
|
+
export declare class experimental_AstroContainer {
|
|
113
|
+
#private;
|
|
114
|
+
private constructor();
|
|
115
|
+
/**
|
|
116
|
+
* Creates a new instance of a container.
|
|
117
|
+
*
|
|
118
|
+
* @param {AstroContainerOptions=} containerOptions
|
|
119
|
+
*/
|
|
120
|
+
static create(containerOptions?: AstroContainerOptions): Promise<experimental_AstroContainer>;
|
|
121
|
+
private static createFromManifest;
|
|
122
|
+
/**
|
|
123
|
+
* @description
|
|
124
|
+
* It renders a component and returns the result as a string.
|
|
125
|
+
*
|
|
126
|
+
* ## Example
|
|
127
|
+
*
|
|
128
|
+
* ```js
|
|
129
|
+
* import Card from "../src/components/Card.astro";
|
|
130
|
+
*
|
|
131
|
+
* const container = await AstroContainer.create();
|
|
132
|
+
* const result = await container.renderToString(Card);
|
|
133
|
+
*
|
|
134
|
+
* console.log(result); // it's a string
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
*
|
|
138
|
+
* @param {AstroComponentFactory} component The instance of the component.
|
|
139
|
+
* @param {ContainerRenderOptions=} options Possible options to pass when rendering the component.
|
|
140
|
+
*/
|
|
141
|
+
renderToString(component: AstroComponentFactory, options?: ContainerRenderOptions): Promise<string>;
|
|
142
|
+
/**
|
|
143
|
+
* @description
|
|
144
|
+
* It renders a component and returns the `Response` as result of the rendering phase.
|
|
145
|
+
*
|
|
146
|
+
* ## Example
|
|
147
|
+
*
|
|
148
|
+
* ```js
|
|
149
|
+
* import Card from "../src/components/Card.astro";
|
|
150
|
+
*
|
|
151
|
+
* const container = await AstroContainer.create();
|
|
152
|
+
* const response = await container.renderToResponse(Card);
|
|
153
|
+
*
|
|
154
|
+
* console.log(response.status); // it's a number
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
*
|
|
158
|
+
* @param {AstroComponentFactory} component The instance of the component.
|
|
159
|
+
* @param {ContainerRenderOptions=} options Possible options to pass when rendering the component.
|
|
160
|
+
*/
|
|
161
|
+
renderToResponse(component: AstroComponentFactory, options?: ContainerRenderOptions): Promise<Response>;
|
|
162
|
+
}
|