astro 2.0.17 → 2.1.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/README.md +3 -3
- package/client-base.d.ts +27 -0
- package/client-image.d.ts +48 -0
- package/components/Image.astro +28 -0
- package/dist/@types/astro.d.ts +101 -1
- package/dist/assets/consts.d.ts +4 -0
- package/dist/assets/consts.js +20 -0
- package/dist/assets/image-endpoint.d.ts +5 -0
- package/dist/assets/image-endpoint.js +50 -0
- package/dist/assets/index.d.ts +4 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/internal.d.ts +36 -0
- package/dist/assets/internal.js +70 -0
- package/dist/assets/services/service.d.ts +71 -0
- package/dist/assets/services/service.js +88 -0
- package/dist/assets/services/sharp.d.ts +3 -0
- package/dist/assets/services/sharp.js +57 -0
- package/dist/assets/services/squoosh.d.ts +3 -0
- package/dist/assets/services/squoosh.js +56 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_enc.d.js +11 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_node_dec.d.ts +2 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_node_dec.js +1628 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_node_dec.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_node_enc.d.ts +2 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_node_enc.js +1850 -0
- package/dist/assets/services/vendor/squoosh/avif/avif_node_enc.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/codecs.d.ts +158 -0
- package/dist/assets/services/vendor/squoosh/codecs.js +284 -0
- package/dist/assets/services/vendor/squoosh/copy-wasm.d.ts +1 -0
- package/dist/assets/services/vendor/squoosh/copy-wasm.js +24 -0
- package/dist/assets/services/vendor/squoosh/emscripten-types.d.js +0 -0
- package/dist/assets/services/vendor/squoosh/emscripten-utils.d.ts +9 -0
- package/dist/assets/services/vendor/squoosh/emscripten-utils.js +33 -0
- package/dist/assets/services/vendor/squoosh/image-pool.d.ts +4 -0
- package/dist/assets/services/vendor/squoosh/image-pool.js +94 -0
- package/dist/assets/services/vendor/squoosh/image.d.ts +14 -0
- package/dist/assets/services/vendor/squoosh/image.js +27 -0
- package/dist/assets/services/vendor/squoosh/image_data.d.ts +9 -0
- package/dist/assets/services/vendor/squoosh/image_data.js +22 -0
- package/dist/assets/services/vendor/squoosh/impl.d.ts +22 -0
- package/dist/assets/services/vendor/squoosh/impl.js +110 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_enc.d.js +11 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_dec.d.ts +2 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_dec.js +1631 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_dec.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_enc.d.ts +2 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_enc.js +1737 -0
- package/dist/assets/services/vendor/squoosh/mozjpeg/mozjpeg_node_enc.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/png/squoosh_oxipng.d.ts +10 -0
- package/dist/assets/services/vendor/squoosh/png/squoosh_oxipng.js +89 -0
- package/dist/assets/services/vendor/squoosh/png/squoosh_oxipng_bg.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/png/squoosh_png.d.ts +15 -0
- package/dist/assets/services/vendor/squoosh/png/squoosh_png.js +138 -0
- package/dist/assets/services/vendor/squoosh/png/squoosh_png_bg.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/resize/squoosh_resize.d.ts +15 -0
- package/dist/assets/services/vendor/squoosh/resize/squoosh_resize.js +95 -0
- package/dist/assets/services/vendor/squoosh/resize/squoosh_resize_bg.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/rotate/rotate.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/utils/execOnce.d.ts +1 -0
- package/dist/assets/services/vendor/squoosh/utils/execOnce.js +14 -0
- package/dist/assets/services/vendor/squoosh/utils/workerPool.d.ts +22 -0
- package/dist/assets/services/vendor/squoosh/utils/workerPool.js +95 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_enc.d.js +4 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_node_dec.d.ts +2 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_node_dec.js +1473 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_node_dec.wasm +0 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_node_enc.d.ts +2 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_node_enc.js +1640 -0
- package/dist/assets/services/vendor/squoosh/webp/webp_node_enc.wasm +0 -0
- package/dist/assets/types.d.ts +119 -0
- package/dist/assets/types.js +0 -0
- package/dist/assets/utils/etag.d.ts +12 -0
- package/dist/assets/utils/etag.js +28 -0
- package/dist/assets/utils/metadata.d.ts +6 -0
- package/dist/assets/utils/metadata.js +30 -0
- package/dist/assets/utils/queryParams.d.ts +2 -0
- package/dist/assets/utils/queryParams.js +16 -0
- package/dist/assets/utils/transformToPath.d.ts +2 -0
- package/dist/assets/utils/transformToPath.js +17 -0
- package/dist/assets/vite-plugin-assets.d.ts +5 -0
- package/dist/assets/vite-plugin-assets.js +187 -0
- package/dist/cli/check/index.d.ts +81 -2
- package/dist/cli/check/index.js +190 -44
- package/dist/cli/index.js +39 -16
- package/dist/cli/telemetry.js +1 -1
- package/dist/content/consts.d.ts +0 -1
- package/dist/content/consts.js +1 -3
- package/dist/content/internal.d.ts +7 -0
- package/dist/content/internal.js +27 -5
- package/dist/content/template/virtual-mod.d.mts +1 -0
- package/dist/content/types-generator.js +25 -10
- package/dist/content/utils.d.ts +16 -13
- package/dist/content/utils.js +29 -6
- package/dist/content/vite-plugin-content-assets.d.ts +3 -1
- package/dist/content/vite-plugin-content-assets.js +10 -6
- package/dist/content/vite-plugin-content-imports.js +54 -27
- package/dist/content/vite-plugin-content-virtual-mod.js +7 -4
- package/dist/core/add/index.js +2 -1
- package/dist/core/app/index.js +104 -134
- package/dist/core/build/generate.js +30 -5
- package/dist/core/build/index.d.ts +2 -0
- package/dist/core/build/index.js +16 -0
- package/dist/core/build/plugins/plugin-ssr.js +3 -5
- package/dist/core/config/config.js +2 -1
- package/dist/core/config/schema.d.ts +64 -8
- package/dist/core/config/schema.js +17 -3
- package/dist/core/config/settings.js +4 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/cookies/cookies.js +36 -68
- package/dist/core/create-vite.js +5 -1
- package/dist/core/dev/dev.d.ts +2 -2
- package/dist/core/dev/dev.js +24 -4
- package/dist/core/errors/dev/vite.js +6 -1
- package/dist/core/errors/errors-data.d.ts +17 -1
- package/dist/core/errors/errors-data.js +16 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/path.d.ts +1 -0
- package/dist/core/path.js +4 -0
- package/dist/core/preview/index.d.ts +3 -1
- package/dist/core/preview/index.js +16 -1
- package/dist/core/render/dev/css.js +2 -2
- package/dist/core/render/dev/environment.js +1 -5
- package/dist/core/render/environment.js +1 -2
- package/dist/core/render/result.js +13 -35
- package/dist/core/sync/index.d.ts +18 -5
- package/dist/core/sync/index.js +13 -1
- package/dist/integrations/index.js +12 -1
- package/dist/runtime/server/render/component.js +1 -1
- package/dist/runtime/server/response.js +11 -30
- package/dist/vite-plugin-astro-postprocess/index.js +1 -1
- package/dist/vite-plugin-astro-server/plugin.js +1 -1
- package/dist/vite-plugin-env/index.js +4 -4
- package/dist/vite-plugin-inject-env-ts/index.js +17 -2
- package/dist/vite-plugin-markdown/content-entry-type.d.ts +7 -0
- package/dist/vite-plugin-markdown/content-entry-type.js +39 -0
- package/dist/vite-plugin-markdown/index.js +70 -4
- package/dist/vite-plugin-ssr-manifest/index.d.ts +2 -0
- package/dist/vite-plugin-ssr-manifest/index.js +25 -0
- package/package.json +26 -9
- package/src/content/template/types.d.ts +18 -9
- package/src/content/template/virtual-mod.mjs +6 -0
- package/tsconfigs/base.json +6 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<br/>
|
|
2
2
|
<p align="center">
|
|
3
|
-
<img src="
|
|
3
|
+
<img src="../../.github/assets/banner.png" alt="Build the web you want">
|
|
4
4
|
<br/><br/>
|
|
5
|
-
<a href="https://astro.build">Astro</a> is
|
|
5
|
+
<a href="https://astro.build">Astro</a> is the all-in-one web framework designed for speed.
|
|
6
6
|
<br/>
|
|
7
|
-
|
|
7
|
+
Pull your content from anywhere and deploy everywhere, all powered by your favorite UI components and libraries.
|
|
8
8
|
<br/><br/>
|
|
9
9
|
</p>
|
|
10
10
|
|
package/client-base.d.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
/// <reference path="./import-meta.d.ts" />
|
|
2
2
|
|
|
3
|
+
declare module 'astro:assets' {
|
|
4
|
+
// Exporting things one by one is a bit cumbersome, not sure if there's a better way - erika, 2023-02-03
|
|
5
|
+
type AstroAssets = {
|
|
6
|
+
getImage: typeof import('./dist/assets/index.js').getImage;
|
|
7
|
+
Image: typeof import('./components/Image.astro').default;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
|
11
|
+
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] };
|
|
12
|
+
type ImgAttributes = WithRequired<
|
|
13
|
+
Omit<import('./types').HTMLAttributes<'img'>, 'src' | 'width' | 'height'>,
|
|
14
|
+
'alt'
|
|
15
|
+
>;
|
|
16
|
+
|
|
17
|
+
export type LocalImageProps = Simplify<
|
|
18
|
+
import('./dist/assets/types.js').LocalImageProps<ImgAttributes>
|
|
19
|
+
>;
|
|
20
|
+
export type RemoteImageProps = Simplify<
|
|
21
|
+
import('./dist/assets/types.js').RemoteImageProps<ImgAttributes>
|
|
22
|
+
>;
|
|
23
|
+
export const { getImage, Image }: AstroAssets;
|
|
24
|
+
}
|
|
25
|
+
|
|
3
26
|
type MD = import('./dist/@types/astro').MarkdownInstance<Record<string, any>>;
|
|
4
27
|
interface ExportedMarkdownModuleEntities {
|
|
5
28
|
frontmatter: MD['frontmatter'];
|
|
@@ -117,6 +140,10 @@ declare module '*.mdx' {
|
|
|
117
140
|
export default load;
|
|
118
141
|
}
|
|
119
142
|
|
|
143
|
+
declare module 'astro:ssr-manifest' {
|
|
144
|
+
export const manifest: import('./dist/@types/astro').SSRManifest;
|
|
145
|
+
}
|
|
146
|
+
|
|
120
147
|
// Everything below are Vite's types (apart from image types, which are in `client.d.ts`)
|
|
121
148
|
|
|
122
149
|
// CSS modules
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference path="./client-base.d.ts" />
|
|
2
|
+
|
|
3
|
+
type InputFormat = 'avif' | 'gif' | 'heic' | 'heif' | 'jpeg' | 'jpg' | 'png' | 'tiff' | 'webp';
|
|
4
|
+
|
|
5
|
+
interface ImageMetadata {
|
|
6
|
+
src: string;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
format: InputFormat;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// images
|
|
13
|
+
declare module '*.avif' {
|
|
14
|
+
const metadata: ImageMetadata;
|
|
15
|
+
export default metadata;
|
|
16
|
+
}
|
|
17
|
+
declare module '*.gif' {
|
|
18
|
+
const metadata: ImageMetadata;
|
|
19
|
+
export default metadata;
|
|
20
|
+
}
|
|
21
|
+
declare module '*.heic' {
|
|
22
|
+
const metadata: ImageMetadata;
|
|
23
|
+
export default metadata;
|
|
24
|
+
}
|
|
25
|
+
declare module '*.heif' {
|
|
26
|
+
const metadata: ImageMetadata;
|
|
27
|
+
export default metadata;
|
|
28
|
+
}
|
|
29
|
+
declare module '*.jpeg' {
|
|
30
|
+
const metadata: ImageMetadata;
|
|
31
|
+
export default metadata;
|
|
32
|
+
}
|
|
33
|
+
declare module '*.jpg' {
|
|
34
|
+
const metadata: ImageMetadata;
|
|
35
|
+
export default metadata;
|
|
36
|
+
}
|
|
37
|
+
declare module '*.png' {
|
|
38
|
+
const metadata: ImageMetadata;
|
|
39
|
+
export default metadata;
|
|
40
|
+
}
|
|
41
|
+
declare module '*.tiff' {
|
|
42
|
+
const metadata: ImageMetadata;
|
|
43
|
+
export default metadata;
|
|
44
|
+
}
|
|
45
|
+
declare module '*.webp' {
|
|
46
|
+
const metadata: ImageMetadata;
|
|
47
|
+
export default metadata;
|
|
48
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getImage, type LocalImageProps, type RemoteImageProps } from 'astro:assets';
|
|
3
|
+
import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
|
|
4
|
+
|
|
5
|
+
// The TypeScript diagnostic for JSX props uses the last member of the union to suggest props, so it would be better for
|
|
6
|
+
// LocalImageProps to be last. Unfortunately, when we do this the error messages that remote images get are complete nonsense
|
|
7
|
+
// Not 100% sure how to fix this, seems to be a TypeScript issue. Unfortunate.
|
|
8
|
+
type Props = LocalImageProps | RemoteImageProps;
|
|
9
|
+
|
|
10
|
+
const props = Astro.props;
|
|
11
|
+
|
|
12
|
+
if (props.alt === undefined || props.alt === null) {
|
|
13
|
+
throw new AstroError(AstroErrorData.ImageMissingAlt);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// As a convenience, allow width and height to be string with a number in them, to match HTML's native `img`.
|
|
17
|
+
if (typeof props.width === 'string') {
|
|
18
|
+
props.width = parseInt(props.width);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof props.height === 'string') {
|
|
22
|
+
props.height = parseInt(props.height);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const image = await getImage(props);
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
<img src={image.src} {...image.attributes} />
|
package/dist/@types/astro.d.ts
CHANGED
|
@@ -13,9 +13,12 @@ import type { PageBuildData } from '../core/build/types';
|
|
|
13
13
|
import type { AstroConfigSchema } from '../core/config';
|
|
14
14
|
import type { AstroTimer } from '../core/config/timer';
|
|
15
15
|
import type { AstroCookies } from '../core/cookies';
|
|
16
|
+
import type { LogOptions } from '../core/logger/core';
|
|
16
17
|
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
|
|
17
18
|
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
|
|
18
19
|
export type { MarkdownHeading, MarkdownMetadata, MarkdownRenderingResult, RehypePlugins, RemarkPlugins, ShikiConfig, } from '@astrojs/markdown-remark';
|
|
20
|
+
export type { ExternalImageService, LocalImageService } from '../assets/services/service';
|
|
21
|
+
export type { ImageTransform } from '../assets/types';
|
|
19
22
|
export type { SSRManifest } from '../core/app/types';
|
|
20
23
|
export type { AstroCookies } from '../core/cookies';
|
|
21
24
|
export interface AstroBuiltinProps {
|
|
@@ -64,6 +67,7 @@ export interface CLIFlags {
|
|
|
64
67
|
port?: number;
|
|
65
68
|
config?: string;
|
|
66
69
|
drafts?: boolean;
|
|
70
|
+
experimentalAssets?: boolean;
|
|
67
71
|
}
|
|
68
72
|
export interface BuildConfig {
|
|
69
73
|
/**
|
|
@@ -648,6 +652,14 @@ export interface AstroUserConfig {
|
|
|
648
652
|
server?: ServerConfig | ((options: {
|
|
649
653
|
command: 'dev' | 'preview';
|
|
650
654
|
}) => ServerConfig);
|
|
655
|
+
/**
|
|
656
|
+
* @docs
|
|
657
|
+
* @kind heading
|
|
658
|
+
* @name Image options
|
|
659
|
+
*/
|
|
660
|
+
image?: {
|
|
661
|
+
service: 'astro/assets/services/sharp' | 'astro/assets/services/squoosh' | (string & {});
|
|
662
|
+
};
|
|
651
663
|
/**
|
|
652
664
|
* @docs
|
|
653
665
|
* @kind heading
|
|
@@ -861,7 +873,27 @@ export interface AstroUserConfig {
|
|
|
861
873
|
* Astro offers experimental flags to give users early access to new features.
|
|
862
874
|
* These flags are not guaranteed to be stable.
|
|
863
875
|
*/
|
|
864
|
-
experimental?:
|
|
876
|
+
experimental?: {
|
|
877
|
+
/**
|
|
878
|
+
* @docs
|
|
879
|
+
* @name experimental.assets
|
|
880
|
+
* @type {boolean}
|
|
881
|
+
* @default `false`
|
|
882
|
+
* @version 2.1.0
|
|
883
|
+
* @description
|
|
884
|
+
* Enable experimental support for optimizing and resizing images. With this enabled, a new `astro:assets` module will be exposed.
|
|
885
|
+
*
|
|
886
|
+
* To enable this feature, set `experimental.assets` to `true` in your Astro config:
|
|
887
|
+
*
|
|
888
|
+
* ```js
|
|
889
|
+
* {
|
|
890
|
+
* experimental: {
|
|
891
|
+
* assets: true,
|
|
892
|
+
* },
|
|
893
|
+
* }
|
|
894
|
+
*/
|
|
895
|
+
assets?: boolean;
|
|
896
|
+
};
|
|
865
897
|
/** @deprecated - Use "integrations" instead. Run Astro to learn more about migrating. */
|
|
866
898
|
renderers?: never;
|
|
867
899
|
/** @deprecated `projectRoot` has been renamed to `root` */
|
|
@@ -902,11 +934,31 @@ export interface InjectedRoute {
|
|
|
902
934
|
export interface AstroConfig extends z.output<typeof AstroConfigSchema> {
|
|
903
935
|
integrations: AstroIntegration[];
|
|
904
936
|
}
|
|
937
|
+
export interface ContentEntryType {
|
|
938
|
+
extensions: string[];
|
|
939
|
+
getEntryInfo(params: {
|
|
940
|
+
fileUrl: URL;
|
|
941
|
+
contents: string;
|
|
942
|
+
}): GetEntryInfoReturnType | Promise<GetEntryInfoReturnType>;
|
|
943
|
+
contentModuleTypes?: string;
|
|
944
|
+
}
|
|
945
|
+
type GetEntryInfoReturnType = {
|
|
946
|
+
data: Record<string, unknown>;
|
|
947
|
+
/**
|
|
948
|
+
* Used for error hints to point to correct line and location
|
|
949
|
+
* Should be the untouched data as read from the file,
|
|
950
|
+
* including newlines
|
|
951
|
+
*/
|
|
952
|
+
rawData: string;
|
|
953
|
+
body: string;
|
|
954
|
+
slug: string;
|
|
955
|
+
};
|
|
905
956
|
export interface AstroSettings {
|
|
906
957
|
config: AstroConfig;
|
|
907
958
|
adapter: AstroAdapter | undefined;
|
|
908
959
|
injectedRoutes: InjectedRoute[];
|
|
909
960
|
pageExtensions: string[];
|
|
961
|
+
contentEntryTypes: ContentEntryType[];
|
|
910
962
|
renderers: AstroRenderer[];
|
|
911
963
|
scripts: {
|
|
912
964
|
stage: InjectedScriptStage;
|
|
@@ -990,6 +1042,50 @@ export type GetStaticPathsResultKeyed = GetStaticPathsResult & {
|
|
|
990
1042
|
* [Astro Reference](https://docs.astro.build/en/reference/api-reference/#getstaticpaths)
|
|
991
1043
|
*/
|
|
992
1044
|
export type GetStaticPaths = (options: GetStaticPathsOptions) => Promise<GetStaticPathsResult | GetStaticPathsResult[]> | GetStaticPathsResult | GetStaticPathsResult[];
|
|
1045
|
+
/**
|
|
1046
|
+
* Infers the shape of the `params` property returned by `getStaticPaths()`.
|
|
1047
|
+
*
|
|
1048
|
+
* @example
|
|
1049
|
+
* ```ts
|
|
1050
|
+
* export async function getStaticPaths() {
|
|
1051
|
+
* return results.map((entry) => ({
|
|
1052
|
+
* params: { slug: entry.slug },
|
|
1053
|
+
* }));
|
|
1054
|
+
* }
|
|
1055
|
+
*
|
|
1056
|
+
* type Params = InferGetStaticParamsType<typeof getStaticPaths>;
|
|
1057
|
+
* // ^? { slug: string; }
|
|
1058
|
+
*
|
|
1059
|
+
* const { slug } = Astro.params as Params;
|
|
1060
|
+
* ```
|
|
1061
|
+
*/
|
|
1062
|
+
export type InferGetStaticParamsType<T> = T extends () => Promise<infer R> ? R extends Array<infer U> ? U extends {
|
|
1063
|
+
params: infer P;
|
|
1064
|
+
} ? P : never : never : never;
|
|
1065
|
+
/**
|
|
1066
|
+
* Infers the shape of the `props` property returned by `getStaticPaths()`.
|
|
1067
|
+
*
|
|
1068
|
+
* @example
|
|
1069
|
+
* ```ts
|
|
1070
|
+
* export async function getStaticPaths() {
|
|
1071
|
+
* return results.map((entry) => ({
|
|
1072
|
+
* params: { slug: entry.slug },
|
|
1073
|
+
* props: {
|
|
1074
|
+
* propA: true,
|
|
1075
|
+
* propB: 42
|
|
1076
|
+
* },
|
|
1077
|
+
* }));
|
|
1078
|
+
* }
|
|
1079
|
+
*
|
|
1080
|
+
* type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
|
1081
|
+
* // ^? { propA: boolean; propB: number; }
|
|
1082
|
+
*
|
|
1083
|
+
* const { propA, propB } = Astro.props as Props;
|
|
1084
|
+
* ```
|
|
1085
|
+
*/
|
|
1086
|
+
export type InferGetStaticPropsType<T> = T extends () => Promise<infer R> ? R extends Array<infer U> ? U extends {
|
|
1087
|
+
props: infer P;
|
|
1088
|
+
} ? P : never : never : never;
|
|
993
1089
|
export interface HydrateOptions {
|
|
994
1090
|
name: string;
|
|
995
1091
|
value?: string;
|
|
@@ -1248,6 +1344,10 @@ export interface AstroIntegration {
|
|
|
1248
1344
|
}) => void | Promise<void>;
|
|
1249
1345
|
};
|
|
1250
1346
|
}
|
|
1347
|
+
export interface AstroPluginOptions {
|
|
1348
|
+
settings: AstroSettings;
|
|
1349
|
+
logging: LogOptions;
|
|
1350
|
+
}
|
|
1251
1351
|
export type RouteType = 'page' | 'endpoint';
|
|
1252
1352
|
export interface RoutePart {
|
|
1253
1353
|
content: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const VIRTUAL_MODULE_ID = "astro:assets";
|
|
2
|
+
export declare const VIRTUAL_SERVICE_ID = "virtual:image-service";
|
|
3
|
+
export declare const VALID_INPUT_FORMATS: readonly ["heic", "heif", "avif", "jpeg", "jpg", "png", "tiff", "webp", "gif"];
|
|
4
|
+
export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg"];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const VIRTUAL_MODULE_ID = "astro:assets";
|
|
2
|
+
const VIRTUAL_SERVICE_ID = "virtual:image-service";
|
|
3
|
+
const VALID_INPUT_FORMATS = [
|
|
4
|
+
"heic",
|
|
5
|
+
"heif",
|
|
6
|
+
"avif",
|
|
7
|
+
"jpeg",
|
|
8
|
+
"jpg",
|
|
9
|
+
"png",
|
|
10
|
+
"tiff",
|
|
11
|
+
"webp",
|
|
12
|
+
"gif"
|
|
13
|
+
];
|
|
14
|
+
const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg"];
|
|
15
|
+
export {
|
|
16
|
+
VALID_INPUT_FORMATS,
|
|
17
|
+
VALID_OUTPUT_FORMATS,
|
|
18
|
+
VIRTUAL_MODULE_ID,
|
|
19
|
+
VIRTUAL_SERVICE_ID
|
|
20
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import mime from "mime";
|
|
2
|
+
import { isRemotePath } from "../core/path.js";
|
|
3
|
+
import { getConfiguredImageService } from "./internal.js";
|
|
4
|
+
import { isLocalService } from "./services/service.js";
|
|
5
|
+
import { etag } from "./utils/etag.js";
|
|
6
|
+
async function loadRemoteImage(src) {
|
|
7
|
+
try {
|
|
8
|
+
const res = await fetch(src);
|
|
9
|
+
if (!res.ok) {
|
|
10
|
+
return void 0;
|
|
11
|
+
}
|
|
12
|
+
return Buffer.from(await res.arrayBuffer());
|
|
13
|
+
} catch (err) {
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const get = async ({ request }) => {
|
|
18
|
+
try {
|
|
19
|
+
const imageService = await getConfiguredImageService();
|
|
20
|
+
if (!isLocalService(imageService)) {
|
|
21
|
+
throw new Error("Configured image service is not a local service");
|
|
22
|
+
}
|
|
23
|
+
const url = new URL(request.url);
|
|
24
|
+
const transform = await imageService.parseURL(url);
|
|
25
|
+
if (!transform || !transform.src) {
|
|
26
|
+
throw new Error("Incorrect transform returned by `parseURL`");
|
|
27
|
+
}
|
|
28
|
+
let inputBuffer = void 0;
|
|
29
|
+
const sourceUrl = isRemotePath(transform.src) ? new URL(transform.src) : new URL(transform.src, url.origin);
|
|
30
|
+
inputBuffer = await loadRemoteImage(sourceUrl);
|
|
31
|
+
if (!inputBuffer) {
|
|
32
|
+
return new Response("Not Found", { status: 404 });
|
|
33
|
+
}
|
|
34
|
+
const { data, format } = await imageService.transform(inputBuffer, transform);
|
|
35
|
+
return new Response(data, {
|
|
36
|
+
status: 200,
|
|
37
|
+
headers: {
|
|
38
|
+
"Content-Type": mime.getType(format) || "",
|
|
39
|
+
"Cache-Control": "public, max-age=31536000",
|
|
40
|
+
ETag: etag(data.toString()),
|
|
41
|
+
Date: new Date().toUTCString()
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
} catch (err) {
|
|
45
|
+
return new Response(`Server Error: ${err}`, { status: 500 });
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
get
|
|
50
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getConfiguredImageService, getImage } from "./internal.js";
|
|
2
|
+
import { baseService } from "./services/service.js";
|
|
3
|
+
import {} from "./types.js";
|
|
4
|
+
import { imageMetadata } from "./utils/metadata.js";
|
|
5
|
+
export {
|
|
6
|
+
baseService,
|
|
7
|
+
getConfiguredImageService,
|
|
8
|
+
getImage,
|
|
9
|
+
imageMetadata
|
|
10
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { StaticBuildOptions } from '../core/build/types.js';
|
|
2
|
+
import { ImageService } from './services/service.js';
|
|
3
|
+
import type { ImageMetadata, ImageTransform } from './types.js';
|
|
4
|
+
export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
|
|
5
|
+
export declare function getConfiguredImageService(): Promise<ImageService>;
|
|
6
|
+
interface GetImageResult {
|
|
7
|
+
options: ImageTransform;
|
|
8
|
+
src: string;
|
|
9
|
+
attributes: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get an optimized image and the necessary attributes to render it.
|
|
13
|
+
*
|
|
14
|
+
* **Example**
|
|
15
|
+
* ```astro
|
|
16
|
+
* ---
|
|
17
|
+
* import { getImage } from 'astro:assets';
|
|
18
|
+
* import originalImage from '../assets/image.png';
|
|
19
|
+
*
|
|
20
|
+
* const optimizedImage = await getImage({src: originalImage, width: 1280 })
|
|
21
|
+
* ---
|
|
22
|
+
* <img src={optimizedImage.src} {...optimizedImage.attributes} />
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* This is functionally equivalent to using the `<Image />` component, as the component calls this function internally.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getImage(options: ImageTransform): Promise<GetImageResult>;
|
|
28
|
+
export declare function getStaticImageList(): Iterable<[ImageTransform, string]>;
|
|
29
|
+
interface GenerationData {
|
|
30
|
+
weight: {
|
|
31
|
+
before: number;
|
|
32
|
+
after: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export declare function generateImage(buildOpts: StaticBuildOptions, options: ImageTransform, filepath: string): Promise<GenerationData | undefined>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
|
3
|
+
import { isLocalService } from "./services/service.js";
|
|
4
|
+
function isESMImportedImage(src) {
|
|
5
|
+
return typeof src === "object";
|
|
6
|
+
}
|
|
7
|
+
async function getConfiguredImageService() {
|
|
8
|
+
if (!globalThis.astroAsset.imageService) {
|
|
9
|
+
const { default: service } = await import("virtual:image-service").catch((e) => {
|
|
10
|
+
const error = new AstroError(AstroErrorData.InvalidImageService);
|
|
11
|
+
error.cause = e;
|
|
12
|
+
throw error;
|
|
13
|
+
});
|
|
14
|
+
globalThis.astroAsset.imageService = service;
|
|
15
|
+
return service;
|
|
16
|
+
}
|
|
17
|
+
return globalThis.astroAsset.imageService;
|
|
18
|
+
}
|
|
19
|
+
async function getImage(options) {
|
|
20
|
+
const service = await getConfiguredImageService();
|
|
21
|
+
let imageURL = service.getURL(options);
|
|
22
|
+
if (isLocalService(service) && globalThis.astroAsset.addStaticImage) {
|
|
23
|
+
imageURL = globalThis.astroAsset.addStaticImage(options);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
options,
|
|
27
|
+
src: imageURL,
|
|
28
|
+
attributes: service.getHTMLAttributes !== void 0 ? service.getHTMLAttributes(options) : {}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function getStaticImageList() {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
if (!((_a = globalThis == null ? void 0 : globalThis.astroAsset) == null ? void 0 : _a.staticImages)) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
return (_b = globalThis.astroAsset.staticImages) == null ? void 0 : _b.entries();
|
|
37
|
+
}
|
|
38
|
+
async function generateImage(buildOpts, options, filepath) {
|
|
39
|
+
if (!isESMImportedImage(options.src)) {
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
const imageService = await getConfiguredImageService();
|
|
43
|
+
let serverRoot, clientRoot;
|
|
44
|
+
if (buildOpts.settings.config.output === "server") {
|
|
45
|
+
serverRoot = buildOpts.settings.config.build.server;
|
|
46
|
+
clientRoot = buildOpts.settings.config.build.client;
|
|
47
|
+
} else {
|
|
48
|
+
serverRoot = buildOpts.settings.config.outDir;
|
|
49
|
+
clientRoot = buildOpts.settings.config.outDir;
|
|
50
|
+
}
|
|
51
|
+
const fileData = await fs.promises.readFile(new URL("." + options.src.src, serverRoot));
|
|
52
|
+
const resultData = await imageService.transform(fileData, { ...options, src: options.src.src });
|
|
53
|
+
const finalFileURL = new URL("." + filepath, clientRoot);
|
|
54
|
+
const finalFolderURL = new URL("./", finalFileURL);
|
|
55
|
+
await fs.promises.mkdir(finalFolderURL, { recursive: true });
|
|
56
|
+
await fs.promises.writeFile(finalFileURL, resultData.data);
|
|
57
|
+
return {
|
|
58
|
+
weight: {
|
|
59
|
+
before: Math.trunc(fileData.byteLength / 1024),
|
|
60
|
+
after: Math.trunc(resultData.data.byteLength / 1024)
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
generateImage,
|
|
66
|
+
getConfiguredImageService,
|
|
67
|
+
getImage,
|
|
68
|
+
getStaticImageList,
|
|
69
|
+
isESMImportedImage
|
|
70
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ImageTransform, OutputFormat } from '../types.js';
|
|
3
|
+
export type ImageService = LocalImageService | ExternalImageService;
|
|
4
|
+
export declare function isLocalService(service: ImageService | undefined): service is LocalImageService;
|
|
5
|
+
export declare function parseQuality(quality: string): string | number;
|
|
6
|
+
interface SharedServiceProps {
|
|
7
|
+
/**
|
|
8
|
+
* Return the URL to the endpoint or URL your images are generated from.
|
|
9
|
+
*
|
|
10
|
+
* For a local service, your service should expose an endpoint handling the image requests, or use Astro's at `/_image`.
|
|
11
|
+
*
|
|
12
|
+
* For external services, this should point to the URL your images are coming from, for instance, `/_vercel/image`
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
getURL: (options: ImageTransform) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Return any additional HTML attributes separate from `src` that your service requires to show the image properly.
|
|
18
|
+
*
|
|
19
|
+
* For example, you might want to return the `width` and `height` to avoid CLS, or a particular `class` or `style`.
|
|
20
|
+
* In most cases, you'll want to return directly what your user supplied you, minus the attributes that were used to generate the image.
|
|
21
|
+
*/
|
|
22
|
+
getHTMLAttributes?: (options: ImageTransform) => Record<string, any>;
|
|
23
|
+
}
|
|
24
|
+
export type ExternalImageService = SharedServiceProps;
|
|
25
|
+
type LocalImageTransform = {
|
|
26
|
+
src: string;
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
};
|
|
29
|
+
export interface LocalImageService extends SharedServiceProps {
|
|
30
|
+
/**
|
|
31
|
+
* Parse the requested parameters passed in the URL from `getURL` back into an object to be used later by `transform`
|
|
32
|
+
*
|
|
33
|
+
* In most cases, this will get query parameters using, for example, `params.get('width')` and return those.
|
|
34
|
+
*/
|
|
35
|
+
parseURL: (url: URL) => LocalImageTransform | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Performs the image transformations on the input image and returns both the binary data and
|
|
38
|
+
* final image format of the optimized image.
|
|
39
|
+
*/
|
|
40
|
+
transform: (inputBuffer: Buffer, transform: LocalImageTransform) => Promise<{
|
|
41
|
+
data: Buffer;
|
|
42
|
+
format: OutputFormat;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
export type BaseServiceTransform = {
|
|
46
|
+
src: string;
|
|
47
|
+
width?: number;
|
|
48
|
+
height?: number;
|
|
49
|
+
format?: string | null;
|
|
50
|
+
quality?: string | null;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Basic local service using the included `_image` endpoint.
|
|
54
|
+
* This service intentionally does not implement `transform`.
|
|
55
|
+
*
|
|
56
|
+
* Example usage:
|
|
57
|
+
* ```ts
|
|
58
|
+
* const service = {
|
|
59
|
+
* getURL: baseService.getURL,
|
|
60
|
+
* parseURL: baseService.parseURL,
|
|
61
|
+
* getHTMLAttributes: baseService.getHTMLAttributes,
|
|
62
|
+
* async transform(inputBuffer, transformOptions) {...}
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* This service only supports the following properties: `width`, `height`, `format` and `quality`.
|
|
67
|
+
* Additionally, remote URLs are passed as-is.
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
export declare const baseService: Omit<LocalImageService, 'transform'>;
|
|
71
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
|
|
2
|
+
import { isRemotePath } from "../../core/path.js";
|
|
3
|
+
import { isESMImportedImage } from "../internal.js";
|
|
4
|
+
function isLocalService(service) {
|
|
5
|
+
if (!service) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
return "transform" in service;
|
|
9
|
+
}
|
|
10
|
+
function parseQuality(quality) {
|
|
11
|
+
let result = parseInt(quality);
|
|
12
|
+
if (Number.isNaN(result)) {
|
|
13
|
+
return quality;
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
const baseService = {
|
|
18
|
+
getHTMLAttributes(options) {
|
|
19
|
+
let targetWidth = options.width;
|
|
20
|
+
let targetHeight = options.height;
|
|
21
|
+
if (isESMImportedImage(options.src)) {
|
|
22
|
+
const aspectRatio = options.src.width / options.src.height;
|
|
23
|
+
if (targetHeight && !targetWidth) {
|
|
24
|
+
targetWidth = Math.round(targetHeight * aspectRatio);
|
|
25
|
+
} else if (targetWidth && !targetHeight) {
|
|
26
|
+
targetHeight = Math.round(targetWidth / aspectRatio);
|
|
27
|
+
} else {
|
|
28
|
+
targetWidth = options.src.width;
|
|
29
|
+
targetHeight = options.src.height;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const { src, width, height, format, quality, ...attributes } = options;
|
|
33
|
+
return {
|
|
34
|
+
...attributes,
|
|
35
|
+
width: targetWidth,
|
|
36
|
+
height: targetHeight,
|
|
37
|
+
loading: attributes.loading ?? "lazy",
|
|
38
|
+
decoding: attributes.decoding ?? "async"
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
getURL(options) {
|
|
42
|
+
if (!isESMImportedImage(options.src)) {
|
|
43
|
+
let missingDimension;
|
|
44
|
+
if (!options.width && !options.height) {
|
|
45
|
+
missingDimension = "both";
|
|
46
|
+
} else if (!options.width && options.height) {
|
|
47
|
+
missingDimension = "width";
|
|
48
|
+
} else if (options.width && !options.height) {
|
|
49
|
+
missingDimension = "height";
|
|
50
|
+
}
|
|
51
|
+
if (missingDimension) {
|
|
52
|
+
throw new AstroError({
|
|
53
|
+
...AstroErrorData.MissingImageDimension,
|
|
54
|
+
message: AstroErrorData.MissingImageDimension.message(missingDimension)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!isESMImportedImage(options.src) && isRemotePath(options.src)) {
|
|
59
|
+
return options.src;
|
|
60
|
+
}
|
|
61
|
+
const searchParams = new URLSearchParams();
|
|
62
|
+
searchParams.append("href", isESMImportedImage(options.src) ? options.src.src : options.src);
|
|
63
|
+
options.width && searchParams.append("w", options.width.toString());
|
|
64
|
+
options.height && searchParams.append("h", options.height.toString());
|
|
65
|
+
options.quality && searchParams.append("q", options.quality.toString());
|
|
66
|
+
options.format && searchParams.append("f", options.format);
|
|
67
|
+
return "/_image?" + searchParams;
|
|
68
|
+
},
|
|
69
|
+
parseURL(url) {
|
|
70
|
+
const params = url.searchParams;
|
|
71
|
+
if (!params.has("href")) {
|
|
72
|
+
return void 0;
|
|
73
|
+
}
|
|
74
|
+
const transform = {
|
|
75
|
+
src: params.get("href"),
|
|
76
|
+
width: params.has("w") ? parseInt(params.get("w")) : void 0,
|
|
77
|
+
height: params.has("h") ? parseInt(params.get("h")) : void 0,
|
|
78
|
+
format: params.get("f"),
|
|
79
|
+
quality: params.get("q")
|
|
80
|
+
};
|
|
81
|
+
return transform;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
export {
|
|
85
|
+
baseService,
|
|
86
|
+
isLocalService,
|
|
87
|
+
parseQuality
|
|
88
|
+
};
|