astro 4.3.7 → 4.4.1
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/components/Image.astro +4 -0
- package/components/Picture.astro +4 -0
- package/dist/@types/astro.d.ts +42 -42
- package/dist/assets/build/generate.d.ts +1 -1
- package/dist/assets/build/generate.js +1 -2
- package/dist/assets/internal.js +14 -0
- package/dist/assets/types.d.ts +23 -2
- package/dist/assets/utils/metadata.js +3 -3
- package/dist/assets/utils/remoteProbe.d.ts +2 -0
- package/dist/assets/utils/remoteProbe.js +35 -0
- package/dist/assets/utils/vendor/image-size/detector.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/detector.js +24 -0
- package/dist/assets/utils/vendor/image-size/lookup.d.ts +10 -0
- package/dist/assets/utils/vendor/image-size/lookup.js +26 -0
- package/dist/assets/utils/vendor/image-size/types/bmp.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/bmp.js +11 -0
- package/dist/assets/utils/vendor/image-size/types/cur.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/cur.js +17 -0
- package/dist/assets/utils/vendor/image-size/types/dds.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/dds.js +11 -0
- package/dist/assets/utils/vendor/image-size/types/gif.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/gif.js +12 -0
- package/dist/assets/utils/vendor/image-size/types/heif.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/heif.js +53 -0
- package/dist/assets/utils/vendor/image-size/types/icns.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/icns.js +85 -0
- package/dist/assets/utils/vendor/image-size/types/ico.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/ico.js +43 -0
- package/dist/assets/utils/vendor/image-size/types/index.d.ts +3 -0
- package/dist/assets/utils/vendor/image-size/types/index.js +43 -0
- package/dist/assets/utils/vendor/image-size/types/interface.d.ts +13 -0
- package/dist/assets/utils/vendor/image-size/types/interface.js +0 -0
- package/dist/assets/utils/vendor/image-size/types/j2c.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/j2c.js +12 -0
- package/dist/assets/utils/vendor/image-size/types/jp2.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jp2.js +25 -0
- package/dist/assets/utils/vendor/image-size/types/jpg.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jpg.js +97 -0
- package/dist/assets/utils/vendor/image-size/types/ktx.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/ktx.js +19 -0
- package/dist/assets/utils/vendor/image-size/types/png.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/png.js +34 -0
- package/dist/assets/utils/vendor/image-size/types/pnm.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/pnm.js +69 -0
- package/dist/assets/utils/vendor/image-size/types/psd.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/psd.js +11 -0
- package/dist/assets/utils/vendor/image-size/types/svg.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/svg.js +94 -0
- package/dist/assets/utils/vendor/image-size/types/tga.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/tga.js +15 -0
- package/dist/assets/utils/vendor/image-size/types/tiff.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/tiff.js +66 -0
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +15 -0
- package/dist/assets/utils/vendor/image-size/types/utils.js +60 -0
- package/dist/assets/utils/vendor/image-size/types/webp.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/webp.js +52 -0
- package/dist/cli/add/babel.d.ts +1 -1
- package/dist/cli/add/index.js +10 -3
- package/dist/cli/db/index.js +2 -0
- package/dist/cli/info/index.js +2 -0
- package/dist/cli/preferences/index.js +2 -0
- package/dist/content/runtime.js +3 -1
- package/dist/content/types-generator.js +7 -27
- package/dist/core/app/index.js +39 -122
- package/dist/core/app/pipeline.d.ts +7 -0
- package/dist/core/app/pipeline.js +39 -0
- package/dist/core/base-pipeline.d.ts +59 -0
- package/dist/core/base-pipeline.js +27 -0
- package/dist/core/build/generate.d.ts +1 -1
- package/dist/core/build/generate.js +39 -109
- package/dist/core/build/index.js +0 -4
- package/dist/core/build/{buildPipeline.d.ts → pipeline.d.ts} +13 -13
- package/dist/core/build/pipeline.js +180 -0
- package/dist/core/build/plugins/plugin-css.js +6 -5
- package/dist/core/build/plugins/plugin-hoisted-scripts.js +6 -5
- package/dist/core/build/plugins/util.d.ts +2 -1
- package/dist/core/build/plugins/util.js +12 -1
- package/dist/core/build/types.d.ts +0 -2
- package/dist/core/constants.d.ts +10 -1
- package/dist/core/constants.js +14 -4
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +1 -1
- package/dist/core/endpoint/index.d.ts +5 -4
- package/dist/core/endpoint/index.js +7 -34
- package/dist/core/errors/errors-data.d.ts +16 -3
- package/dist/core/errors/errors-data.js +9 -2
- package/dist/core/messages.js +2 -2
- package/dist/core/middleware/callMiddleware.d.ts +1 -1
- package/dist/core/middleware/callMiddleware.js +2 -9
- package/dist/core/middleware/index.d.ts +2 -2
- package/dist/core/middleware/index.js +74 -9
- package/dist/core/module-loader/vite.js +4 -4
- package/dist/core/preview/index.js +2 -0
- package/dist/core/preview/static-preview-server.js +1 -7
- package/dist/core/redirects/helpers.d.ts +1 -3
- package/dist/core/redirects/helpers.js +0 -29
- package/dist/core/redirects/index.d.ts +2 -1
- package/dist/core/redirects/index.js +3 -3
- package/dist/core/redirects/render.d.ts +2 -0
- package/dist/core/redirects/render.js +33 -0
- package/dist/core/render/index.d.ts +7 -13
- package/dist/core/render/index.js +7 -7
- package/dist/core/render/params-and-props.d.ts +8 -3
- package/dist/core/render/params-and-props.js +24 -16
- package/dist/core/render/result.d.ts +6 -5
- package/dist/core/render/result.js +3 -4
- package/dist/core/render-context.d.ts +32 -0
- package/dist/core/render-context.js +219 -0
- package/dist/core/routing/index.d.ts +0 -1
- package/dist/core/routing/index.js +0 -2
- package/dist/core/routing/manifest/create.js +11 -27
- package/dist/core/routing/params.d.ts +1 -7
- package/dist/core/routing/params.js +0 -15
- package/dist/core/sync/index.js +3 -3
- package/dist/i18n/middleware.d.ts +0 -5
- package/dist/i18n/middleware.js +61 -69
- package/dist/i18n/utils.d.ts +25 -0
- package/dist/{core/render/context.js → i18n/utils.js} +3 -49
- package/dist/prerender/routing.d.ts +1 -1
- package/dist/prerender/routing.js +20 -21
- package/dist/runtime/client/dev-toolbar/apps/astro.js +14 -10
- package/dist/runtime/client/dev-toolbar/apps/audit/a11y.js +2 -2
- package/dist/runtime/client/dev-toolbar/apps/audit/index.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/audit/index.js +115 -6
- package/dist/runtime/client/dev-toolbar/apps/audit/perf.d.ts +2 -0
- package/dist/runtime/client/dev-toolbar/apps/audit/perf.js +110 -0
- package/dist/runtime/client/dev-toolbar/apps/utils/highlight.d.ts +1 -1
- package/dist/runtime/client/dev-toolbar/apps/utils/highlight.js +6 -1
- package/dist/runtime/client/dev-toolbar/ui-library/card.js +1 -1
- package/dist/runtime/server/astro-island.js +10 -1
- package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +7 -0
- package/dist/runtime/server/astro-island.prebuilt-dev.js +4 -0
- 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/endpoint.js +2 -2
- package/dist/runtime/server/render/astro/render.d.ts +1 -0
- package/dist/runtime/server/render/astro/render.js +81 -2
- package/dist/runtime/server/render/component.js +6 -0
- package/dist/runtime/server/render/page.js +15 -2
- package/dist/runtime/server/render/util.d.ts +7 -0
- package/dist/runtime/server/render/util.js +15 -0
- package/dist/runtime/server/scripts.js +2 -4
- package/dist/runtime/server/transition.js +14 -1
- package/dist/vite-plugin-astro/hmr.d.ts +1 -0
- package/dist/vite-plugin-astro/hmr.js +7 -4
- package/dist/vite-plugin-astro-server/error.d.ts +2 -2
- package/dist/vite-plugin-astro-server/error.js +2 -5
- package/dist/vite-plugin-astro-server/index.d.ts +0 -6
- package/dist/vite-plugin-astro-server/index.js +0 -19
- package/dist/vite-plugin-astro-server/pipeline.d.ts +19 -0
- package/dist/vite-plugin-astro-server/pipeline.js +117 -0
- package/dist/vite-plugin-astro-server/plugin.js +3 -4
- package/dist/vite-plugin-astro-server/request.d.ts +3 -4
- package/dist/vite-plugin-astro-server/request.js +6 -9
- package/dist/vite-plugin-astro-server/route.d.ts +3 -4
- package/dist/vite-plugin-astro-server/route.js +34 -162
- package/dist/vite-plugin-dev-toolbar/vite-plugin-dev-toolbar.js +3 -3
- package/package.json +7 -12
- package/dist/core/app/ssrPipeline.d.ts +0 -3
- package/dist/core/app/ssrPipeline.js +0 -6
- package/dist/core/build/buildPipeline.js +0 -150
- package/dist/core/pipeline.d.ts +0 -39
- package/dist/core/pipeline.js +0 -107
- package/dist/core/render/context.d.ts +0 -52
- package/dist/core/render/core.d.ts +0 -10
- package/dist/core/render/core.js +0 -65
- package/dist/core/render/environment.d.ts +0 -34
- package/dist/core/render/environment.js +0 -6
- package/dist/runtime/server/consts.d.ts +0 -1
- package/dist/runtime/server/consts.js +0 -4
- package/dist/vite-plugin-astro-server/devPipeline.d.ts +0 -22
- package/dist/vite-plugin-astro-server/devPipeline.js +0 -65
package/components/Image.astro
CHANGED
|
@@ -29,6 +29,10 @@ const additionalAttributes: HTMLAttributes<'img'> = {};
|
|
|
29
29
|
if (image.srcSet.values.length > 0) {
|
|
30
30
|
additionalAttributes.srcset = image.srcSet.attribute;
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
if (import.meta.env.DEV) {
|
|
34
|
+
additionalAttributes['data-image-component'] = 'true';
|
|
35
|
+
}
|
|
32
36
|
---
|
|
33
37
|
|
|
34
38
|
<img src={image.src} {...additionalAttributes} {...image.attributes} />
|
package/components/Picture.astro
CHANGED
|
@@ -61,6 +61,10 @@ if (props.sizes) {
|
|
|
61
61
|
if (fallbackImage.srcSet.values.length > 0) {
|
|
62
62
|
imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
if (import.meta.env.DEV) {
|
|
66
|
+
imgAdditionalAttributes['data-image-component'] = 'true';
|
|
67
|
+
}
|
|
64
68
|
---
|
|
65
69
|
|
|
66
70
|
<picture {...pictureAttributes}>
|
package/dist/@types/astro.d.ts
CHANGED
|
@@ -1374,7 +1374,7 @@ export interface AstroUserConfig {
|
|
|
1374
1374
|
* URLs will be of the form `example.com/[locale]/content/` for every route, including the default language.
|
|
1375
1375
|
* Localized folders are used for every language, including the default.
|
|
1376
1376
|
*/
|
|
1377
|
-
prefixDefaultLocale
|
|
1377
|
+
prefixDefaultLocale?: boolean;
|
|
1378
1378
|
/**
|
|
1379
1379
|
* @docs
|
|
1380
1380
|
* @name i18n.routing.redirectToDefaultLocale
|
|
@@ -1402,7 +1402,7 @@ export interface AstroUserConfig {
|
|
|
1402
1402
|
* })
|
|
1403
1403
|
*```
|
|
1404
1404
|
* */
|
|
1405
|
-
redirectToDefaultLocale
|
|
1405
|
+
redirectToDefaultLocale?: boolean;
|
|
1406
1406
|
/**
|
|
1407
1407
|
* @name i18n.routing.strategy
|
|
1408
1408
|
* @type {"pathname"}
|
|
@@ -1412,47 +1412,47 @@ export interface AstroUserConfig {
|
|
|
1412
1412
|
*
|
|
1413
1413
|
* - `"pathname": The strategy is applied to the pathname of the URLs
|
|
1414
1414
|
*/
|
|
1415
|
-
strategy
|
|
1416
|
-
/**
|
|
1417
|
-
* @name i18n.domains
|
|
1418
|
-
* @type {Record<string, string> }
|
|
1419
|
-
* @default '{}'
|
|
1420
|
-
* @version 4.3.0
|
|
1421
|
-
* @description
|
|
1422
|
-
*
|
|
1423
|
-
* Configures the URL pattern of one or more supported languages to use a custom domain (or sub-domain).
|
|
1424
|
-
*
|
|
1425
|
-
* When a locale is mapped to a domain, a `/[locale]/` path prefix will not be used.
|
|
1426
|
-
* However, localized folders within `src/pages/` are still required, including for your configured `defaultLocale`.
|
|
1427
|
-
*
|
|
1428
|
-
* 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`).
|
|
1429
|
-
*
|
|
1430
|
-
* ```js
|
|
1431
|
-
* //astro.config.mjs
|
|
1432
|
-
* export default defineConfig({
|
|
1433
|
-
* site: "https://example.com",
|
|
1434
|
-
* output: "server", // required, with no prerendered pages
|
|
1435
|
-
* adapter: node({
|
|
1436
|
-
* mode: 'standalone',
|
|
1437
|
-
* }),
|
|
1438
|
-
* i18n: {
|
|
1439
|
-
* defaultLocale: "en",
|
|
1440
|
-
* locales: ["en", "fr", "pt-br", "es"],
|
|
1441
|
-
* prefixDefaultLocale: false,
|
|
1442
|
-
* domains: {
|
|
1443
|
-
* fr: "https://fr.example.com",
|
|
1444
|
-
* es: "https://example.es"
|
|
1445
|
-
* }
|
|
1446
|
-
* },
|
|
1447
|
-
* })
|
|
1448
|
-
* ```
|
|
1449
|
-
*
|
|
1450
|
-
* Both page routes built and URLs returned by the `astro:i18n` helper functions [`getAbsoluteLocaleUrl()`](https://docs.astro.build/en/guides/internationalization/#getabsolutelocaleurl) and [`getAbsoluteLocaleUrlList()`](https://docs.astro.build/en/guides/internationalization/#getabsolutelocaleurllist) will use the options set in `i18n.domains`.
|
|
1451
|
-
*
|
|
1452
|
-
* See the [Internationalization Guide](https://docs.astro.build/en/guides/internationalization/#domains) for more details, including the limitations of this feature.
|
|
1453
|
-
*/
|
|
1454
|
-
domains?: Record<string, string>;
|
|
1415
|
+
strategy?: 'pathname';
|
|
1455
1416
|
};
|
|
1417
|
+
/**
|
|
1418
|
+
* @name i18n.domains
|
|
1419
|
+
* @type {Record<string, string> }
|
|
1420
|
+
* @default '{}'
|
|
1421
|
+
* @version 4.3.0
|
|
1422
|
+
* @description
|
|
1423
|
+
*
|
|
1424
|
+
* Configures the URL pattern of one or more supported languages to use a custom domain (or sub-domain).
|
|
1425
|
+
*
|
|
1426
|
+
* When a locale is mapped to a domain, a `/[locale]/` path prefix will not be used.
|
|
1427
|
+
* However, localized folders within `src/pages/` are still required, including for your configured `defaultLocale`.
|
|
1428
|
+
*
|
|
1429
|
+
* 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`).
|
|
1430
|
+
*
|
|
1431
|
+
* ```js
|
|
1432
|
+
* //astro.config.mjs
|
|
1433
|
+
* export default defineConfig({
|
|
1434
|
+
* site: "https://example.com",
|
|
1435
|
+
* output: "server", // required, with no prerendered pages
|
|
1436
|
+
* adapter: node({
|
|
1437
|
+
* mode: 'standalone',
|
|
1438
|
+
* }),
|
|
1439
|
+
* i18n: {
|
|
1440
|
+
* defaultLocale: "en",
|
|
1441
|
+
* locales: ["en", "fr", "pt-br", "es"],
|
|
1442
|
+
* prefixDefaultLocale: false,
|
|
1443
|
+
* domains: {
|
|
1444
|
+
* fr: "https://fr.example.com",
|
|
1445
|
+
* es: "https://example.es"
|
|
1446
|
+
* }
|
|
1447
|
+
* },
|
|
1448
|
+
* })
|
|
1449
|
+
* ```
|
|
1450
|
+
*
|
|
1451
|
+
* Both page routes built and URLs returned by the `astro:i18n` helper functions [`getAbsoluteLocaleUrl()`](https://docs.astro.build/en/guides/internationalization/#getabsolutelocaleurl) and [`getAbsoluteLocaleUrlList()`](https://docs.astro.build/en/guides/internationalization/#getabsolutelocaleurllist) will use the options set in `i18n.domains`.
|
|
1452
|
+
*
|
|
1453
|
+
* See the [Internationalization Guide](https://docs.astro.build/en/guides/internationalization/#domains) for more details, including the limitations of this feature.
|
|
1454
|
+
*/
|
|
1455
|
+
domains?: Record<string, string>;
|
|
1456
1456
|
};
|
|
1457
1457
|
/** ⚠️ WARNING: SUBJECT TO CHANGE */
|
|
1458
1458
|
db?: Config.Database;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type PQueue from 'p-queue';
|
|
2
2
|
import type { AstroConfig } from '../../@types/astro.js';
|
|
3
|
-
import type { BuildPipeline } from '../../core/build/
|
|
3
|
+
import type { BuildPipeline } from '../../core/build/pipeline.js';
|
|
4
4
|
import type { Logger } from '../../core/logger/core.js';
|
|
5
5
|
import type { MapValue } from '../../type-utils.js';
|
|
6
6
|
import type { AssetsGlobalStaticImagesList } from '../types.js';
|
|
@@ -11,8 +11,7 @@ import { getConfiguredImageService } from "../internal.js";
|
|
|
11
11
|
import { isESMImportedImage } from "../utils/imageKind.js";
|
|
12
12
|
import { loadRemoteImage } from "./remote.js";
|
|
13
13
|
async function prepareAssetsGenerationEnv(pipeline, totalCount) {
|
|
14
|
-
const config = pipeline
|
|
15
|
-
const logger = pipeline.getLogger();
|
|
14
|
+
const { config, logger } = pipeline;
|
|
16
15
|
let useCache = true;
|
|
17
16
|
const assetsCacheDir = new URL("assets/", config.cacheDir);
|
|
18
17
|
const count = { total: totalCount, current: 1 };
|
package/dist/assets/internal.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
|
|
2
2
|
import { DEFAULT_HASH_PROPS } from "./consts.js";
|
|
3
3
|
import { isLocalService } from "./services/service.js";
|
|
4
4
|
import { isESMImportedImage, isRemoteImage } from "./utils/imageKind.js";
|
|
5
|
+
import { probe } from "./utils/remoteProbe.js";
|
|
5
6
|
async function getConfiguredImageService() {
|
|
6
7
|
if (!globalThis?.astroAsset?.imageService) {
|
|
7
8
|
const { default: service } = await import(
|
|
@@ -41,6 +42,19 @@ async function getImage(options, imageConfig) {
|
|
|
41
42
|
...options,
|
|
42
43
|
src: typeof options.src === "object" && "then" in options.src ? (await options.src).default ?? await options.src : options.src
|
|
43
44
|
};
|
|
45
|
+
if (options.inferSize && isRemoteImage(resolvedOptions.src)) {
|
|
46
|
+
try {
|
|
47
|
+
const result = await probe(resolvedOptions.src);
|
|
48
|
+
resolvedOptions.width ??= result.width;
|
|
49
|
+
resolvedOptions.height ??= result.height;
|
|
50
|
+
delete resolvedOptions.inferSize;
|
|
51
|
+
} catch {
|
|
52
|
+
throw new AstroError({
|
|
53
|
+
...AstroErrorData.FailedToFetchRemoteImageDimensions,
|
|
54
|
+
message: AstroErrorData.FailedToFetchRemoteImageDimensions.message(resolvedOptions.src)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
44
58
|
const originalPath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : resolvedOptions.src;
|
|
45
59
|
const clonedSrc = isESMImportedImage(resolvedOptions.src) ? (
|
|
46
60
|
// @ts-expect-error - clone is a private, hidden prop
|
package/dist/assets/types.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export type UnresolvedImageTransform = Omit<ImageTransform, 'src'> & {
|
|
|
48
48
|
src: ImageMetadata | string | Promise<{
|
|
49
49
|
default: ImageMetadata;
|
|
50
50
|
}>;
|
|
51
|
+
inferSize?: boolean;
|
|
51
52
|
};
|
|
52
53
|
/**
|
|
53
54
|
* Options accepted by the image transformation service.
|
|
@@ -159,7 +160,7 @@ export type LocalImageProps<T> = ImageSharedProps<T> & {
|
|
|
159
160
|
*/
|
|
160
161
|
quality?: ImageQuality;
|
|
161
162
|
};
|
|
162
|
-
export type RemoteImageProps<T> =
|
|
163
|
+
export type RemoteImageProps<T> = (ImageSharedProps<T> & {
|
|
163
164
|
/**
|
|
164
165
|
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
|
|
165
166
|
*
|
|
@@ -171,5 +172,25 @@ export type RemoteImageProps<T> = WithRequired<ImageSharedProps<T>, 'width' | 'h
|
|
|
171
172
|
* ```
|
|
172
173
|
*/
|
|
173
174
|
src: string;
|
|
174
|
-
|
|
175
|
+
/**
|
|
176
|
+
* When inferSize is true width and height are not required
|
|
177
|
+
*/
|
|
178
|
+
inferSize: true;
|
|
179
|
+
}) | (WithRequired<ImageSharedProps<T>, 'width' | 'height'> & {
|
|
180
|
+
/**
|
|
181
|
+
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
|
|
182
|
+
*
|
|
183
|
+
* Remote images are not optimized, and require both `width` and `height` to be set.
|
|
184
|
+
*
|
|
185
|
+
* **Example**:
|
|
186
|
+
* ```
|
|
187
|
+
* <Image src="https://example.com/image.png" width={450} height={300} alt="..." />
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
src: string;
|
|
191
|
+
/**
|
|
192
|
+
* When inferSize is false or undefined width and height are required
|
|
193
|
+
*/
|
|
194
|
+
inferSize?: false | undefined;
|
|
195
|
+
});
|
|
175
196
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import probe from "
|
|
1
|
+
import { lookup as probe } from "../utils/vendor/image-size/lookup.js";
|
|
2
2
|
import { AstroError, AstroErrorData } from "../../core/errors/index.js";
|
|
3
3
|
async function imageMetadata(data, src) {
|
|
4
|
-
const result = probe
|
|
5
|
-
if (result
|
|
4
|
+
const result = probe(data);
|
|
5
|
+
if (!result.height || !result.width || !result.type) {
|
|
6
6
|
throw new AstroError({
|
|
7
7
|
...AstroErrorData.NoImageMetadata,
|
|
8
8
|
message: AstroErrorData.NoImageMetadata.message(src)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { lookup } from "./vendor/image-size/lookup.js";
|
|
2
|
+
async function probe(url) {
|
|
3
|
+
const response = await fetch(url);
|
|
4
|
+
if (!response.body || !response.ok) {
|
|
5
|
+
throw new Error("Failed to fetch image");
|
|
6
|
+
}
|
|
7
|
+
const reader = response.body.getReader();
|
|
8
|
+
let done, value;
|
|
9
|
+
let accumulatedChunks = new Uint8Array();
|
|
10
|
+
while (!done) {
|
|
11
|
+
const readResult = await reader.read();
|
|
12
|
+
done = readResult.done;
|
|
13
|
+
if (done)
|
|
14
|
+
break;
|
|
15
|
+
if (readResult.value) {
|
|
16
|
+
value = readResult.value;
|
|
17
|
+
let tmp = new Uint8Array(accumulatedChunks.length + value.length);
|
|
18
|
+
tmp.set(accumulatedChunks, 0);
|
|
19
|
+
tmp.set(value, accumulatedChunks.length);
|
|
20
|
+
accumulatedChunks = tmp;
|
|
21
|
+
try {
|
|
22
|
+
const dimensions = lookup(accumulatedChunks);
|
|
23
|
+
if (dimensions) {
|
|
24
|
+
await reader.cancel();
|
|
25
|
+
return dimensions;
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new Error("Failed to parse the size");
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
probe
|
|
35
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { typeHandlers, types } from "./types/index.js";
|
|
2
|
+
const firstBytes = /* @__PURE__ */ new Map([
|
|
3
|
+
[56, "psd"],
|
|
4
|
+
[66, "bmp"],
|
|
5
|
+
[68, "dds"],
|
|
6
|
+
[71, "gif"],
|
|
7
|
+
[73, "tiff"],
|
|
8
|
+
[77, "tiff"],
|
|
9
|
+
[82, "webp"],
|
|
10
|
+
[105, "icns"],
|
|
11
|
+
[137, "png"],
|
|
12
|
+
[255, "jpg"]
|
|
13
|
+
]);
|
|
14
|
+
function detector(input) {
|
|
15
|
+
const byte = input[0];
|
|
16
|
+
const type = firstBytes.get(byte);
|
|
17
|
+
if (type && typeHandlers.get(type).validate(input)) {
|
|
18
|
+
return type;
|
|
19
|
+
}
|
|
20
|
+
return types.find((fileType) => typeHandlers.get(fileType).validate(input));
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
detector
|
|
24
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { imageType } from './types/index.js';
|
|
2
|
+
import type { ISizeCalculationResult } from './types/interface.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Return size information based on an Uint8Array
|
|
5
|
+
*
|
|
6
|
+
* @param {Uint8Array} input
|
|
7
|
+
* @returns {ISizeCalculationResult}
|
|
8
|
+
*/
|
|
9
|
+
export declare function lookup(input: Uint8Array): ISizeCalculationResult;
|
|
10
|
+
export declare const disableTypes: (types: imageType[]) => void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { typeHandlers } from "./types/index.js";
|
|
2
|
+
import { detector } from "./detector.js";
|
|
3
|
+
const globalOptions = {
|
|
4
|
+
disabledTypes: []
|
|
5
|
+
};
|
|
6
|
+
function lookup(input) {
|
|
7
|
+
const type = detector(input);
|
|
8
|
+
if (typeof type !== "undefined") {
|
|
9
|
+
if (globalOptions.disabledTypes.indexOf(type) > -1) {
|
|
10
|
+
throw new TypeError("disabled file type: " + type);
|
|
11
|
+
}
|
|
12
|
+
const size = typeHandlers.get(type).calculate(input);
|
|
13
|
+
if (size !== void 0) {
|
|
14
|
+
size.type = size.type ?? type;
|
|
15
|
+
return size;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
throw new TypeError("unsupported file type: " + type);
|
|
19
|
+
}
|
|
20
|
+
const disableTypes = (types) => {
|
|
21
|
+
globalOptions.disabledTypes = types;
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
disableTypes,
|
|
25
|
+
lookup
|
|
26
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { toUTF8String, readInt32LE, readUInt32LE } from "./utils.js";
|
|
2
|
+
const BMP = {
|
|
3
|
+
validate: (input) => toUTF8String(input, 0, 2) === "BM",
|
|
4
|
+
calculate: (input) => ({
|
|
5
|
+
height: Math.abs(readInt32LE(input, 22)),
|
|
6
|
+
width: readUInt32LE(input, 18)
|
|
7
|
+
})
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
BMP
|
|
11
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ICO } from "./ico.js";
|
|
2
|
+
import { readUInt16LE } from "./utils.js";
|
|
3
|
+
const TYPE_CURSOR = 2;
|
|
4
|
+
const CUR = {
|
|
5
|
+
validate(input) {
|
|
6
|
+
const reserved = readUInt16LE(input, 0);
|
|
7
|
+
const imageCount = readUInt16LE(input, 4);
|
|
8
|
+
if (reserved !== 0 || imageCount === 0)
|
|
9
|
+
return false;
|
|
10
|
+
const imageType = readUInt16LE(input, 2);
|
|
11
|
+
return imageType === TYPE_CURSOR;
|
|
12
|
+
},
|
|
13
|
+
calculate: (input) => ICO.calculate(input)
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
CUR
|
|
17
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { toUTF8String, readUInt16LE } from "./utils.js";
|
|
2
|
+
const gifRegexp = /^GIF8[79]a/;
|
|
3
|
+
const GIF = {
|
|
4
|
+
validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)),
|
|
5
|
+
calculate: (input) => ({
|
|
6
|
+
height: readUInt16LE(input, 8),
|
|
7
|
+
width: readUInt16LE(input, 6)
|
|
8
|
+
})
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
GIF
|
|
12
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { findBox, readUInt32BE, toUTF8String } from "./utils.js";
|
|
2
|
+
const brandMap = {
|
|
3
|
+
avif: "avif",
|
|
4
|
+
mif1: "heif",
|
|
5
|
+
msf1: "heif",
|
|
6
|
+
// hief-sequence
|
|
7
|
+
heic: "heic",
|
|
8
|
+
heix: "heic",
|
|
9
|
+
hevc: "heic",
|
|
10
|
+
// heic-sequence
|
|
11
|
+
hevx: "heic"
|
|
12
|
+
// heic-sequence
|
|
13
|
+
};
|
|
14
|
+
function detectBrands(buffer, start, end) {
|
|
15
|
+
let brandsDetected = {};
|
|
16
|
+
for (let i = start; i <= end; i += 4) {
|
|
17
|
+
const brand = toUTF8String(buffer, i, i + 4);
|
|
18
|
+
if (brand in brandMap) {
|
|
19
|
+
brandsDetected[brand] = 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if ("avif" in brandsDetected) {
|
|
23
|
+
return "avif";
|
|
24
|
+
} else if ("heic" in brandsDetected || "heix" in brandsDetected || "hevc" in brandsDetected || "hevx" in brandsDetected) {
|
|
25
|
+
return "heic";
|
|
26
|
+
} else if ("mif1" in brandsDetected || "msf1" in brandsDetected) {
|
|
27
|
+
return "heif";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const HEIF = {
|
|
31
|
+
validate(buffer) {
|
|
32
|
+
const ftype = toUTF8String(buffer, 4, 8);
|
|
33
|
+
const brand = toUTF8String(buffer, 8, 12);
|
|
34
|
+
return "ftyp" === ftype && brand in brandMap;
|
|
35
|
+
},
|
|
36
|
+
calculate(buffer) {
|
|
37
|
+
const metaBox = findBox(buffer, "meta", 0);
|
|
38
|
+
const iprpBox = metaBox && findBox(buffer, "iprp", metaBox.offset + 12);
|
|
39
|
+
const ipcoBox = iprpBox && findBox(buffer, "ipco", iprpBox.offset + 8);
|
|
40
|
+
const ispeBox = ipcoBox && findBox(buffer, "ispe", ipcoBox.offset + 8);
|
|
41
|
+
if (ispeBox) {
|
|
42
|
+
return {
|
|
43
|
+
height: readUInt32BE(buffer, ispeBox.offset + 16),
|
|
44
|
+
width: readUInt32BE(buffer, ispeBox.offset + 12),
|
|
45
|
+
type: detectBrands(buffer, 8, metaBox.offset)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
throw new TypeError("Invalid HEIF, no size found");
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
HEIF
|
|
53
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { toUTF8String, readUInt32BE } from "./utils.js";
|
|
2
|
+
const SIZE_HEADER = 4 + 4;
|
|
3
|
+
const FILE_LENGTH_OFFSET = 4;
|
|
4
|
+
const ENTRY_LENGTH_OFFSET = 4;
|
|
5
|
+
const ICON_TYPE_SIZE = {
|
|
6
|
+
ICON: 32,
|
|
7
|
+
"ICN#": 32,
|
|
8
|
+
// m => 16 x 16
|
|
9
|
+
"icm#": 16,
|
|
10
|
+
icm4: 16,
|
|
11
|
+
icm8: 16,
|
|
12
|
+
// s => 16 x 16
|
|
13
|
+
"ics#": 16,
|
|
14
|
+
ics4: 16,
|
|
15
|
+
ics8: 16,
|
|
16
|
+
is32: 16,
|
|
17
|
+
s8mk: 16,
|
|
18
|
+
icp4: 16,
|
|
19
|
+
// l => 32 x 32
|
|
20
|
+
icl4: 32,
|
|
21
|
+
icl8: 32,
|
|
22
|
+
il32: 32,
|
|
23
|
+
l8mk: 32,
|
|
24
|
+
icp5: 32,
|
|
25
|
+
ic11: 32,
|
|
26
|
+
// h => 48 x 48
|
|
27
|
+
ich4: 48,
|
|
28
|
+
ich8: 48,
|
|
29
|
+
ih32: 48,
|
|
30
|
+
h8mk: 48,
|
|
31
|
+
// . => 64 x 64
|
|
32
|
+
icp6: 64,
|
|
33
|
+
ic12: 32,
|
|
34
|
+
// t => 128 x 128
|
|
35
|
+
it32: 128,
|
|
36
|
+
t8mk: 128,
|
|
37
|
+
ic07: 128,
|
|
38
|
+
// . => 256 x 256
|
|
39
|
+
ic08: 256,
|
|
40
|
+
ic13: 256,
|
|
41
|
+
// . => 512 x 512
|
|
42
|
+
ic09: 512,
|
|
43
|
+
ic14: 512,
|
|
44
|
+
// . => 1024 x 1024
|
|
45
|
+
ic10: 1024
|
|
46
|
+
};
|
|
47
|
+
function readImageHeader(input, imageOffset) {
|
|
48
|
+
const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
|
|
49
|
+
return [
|
|
50
|
+
toUTF8String(input, imageOffset, imageLengthOffset),
|
|
51
|
+
readUInt32BE(input, imageLengthOffset)
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
function getImageSize(type) {
|
|
55
|
+
const size = ICON_TYPE_SIZE[type];
|
|
56
|
+
return { width: size, height: size, type };
|
|
57
|
+
}
|
|
58
|
+
const ICNS = {
|
|
59
|
+
validate: (input) => toUTF8String(input, 0, 4) === "icns",
|
|
60
|
+
calculate(input) {
|
|
61
|
+
const inputLength = input.length;
|
|
62
|
+
const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET);
|
|
63
|
+
let imageOffset = SIZE_HEADER;
|
|
64
|
+
let imageHeader = readImageHeader(input, imageOffset);
|
|
65
|
+
let imageSize = getImageSize(imageHeader[0]);
|
|
66
|
+
imageOffset += imageHeader[1];
|
|
67
|
+
if (imageOffset === fileLength)
|
|
68
|
+
return imageSize;
|
|
69
|
+
const result = {
|
|
70
|
+
height: imageSize.height,
|
|
71
|
+
images: [imageSize],
|
|
72
|
+
width: imageSize.width
|
|
73
|
+
};
|
|
74
|
+
while (imageOffset < fileLength && imageOffset < inputLength) {
|
|
75
|
+
imageHeader = readImageHeader(input, imageOffset);
|
|
76
|
+
imageSize = getImageSize(imageHeader[0]);
|
|
77
|
+
imageOffset += imageHeader[1];
|
|
78
|
+
result.images.push(imageSize);
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
export {
|
|
84
|
+
ICNS
|
|
85
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readUInt16LE } from "./utils.js";
|
|
2
|
+
const TYPE_ICON = 1;
|
|
3
|
+
const SIZE_HEADER = 2 + 2 + 2;
|
|
4
|
+
const SIZE_IMAGE_ENTRY = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4;
|
|
5
|
+
function getSizeFromOffset(input, offset) {
|
|
6
|
+
const value = input[offset];
|
|
7
|
+
return value === 0 ? 256 : value;
|
|
8
|
+
}
|
|
9
|
+
function getImageSize(input, imageIndex) {
|
|
10
|
+
const offset = SIZE_HEADER + imageIndex * SIZE_IMAGE_ENTRY;
|
|
11
|
+
return {
|
|
12
|
+
height: getSizeFromOffset(input, offset + 1),
|
|
13
|
+
width: getSizeFromOffset(input, offset)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const ICO = {
|
|
17
|
+
validate(input) {
|
|
18
|
+
const reserved = readUInt16LE(input, 0);
|
|
19
|
+
const imageCount = readUInt16LE(input, 4);
|
|
20
|
+
if (reserved !== 0 || imageCount === 0)
|
|
21
|
+
return false;
|
|
22
|
+
const imageType = readUInt16LE(input, 2);
|
|
23
|
+
return imageType === TYPE_ICON;
|
|
24
|
+
},
|
|
25
|
+
calculate(input) {
|
|
26
|
+
const nbImages = readUInt16LE(input, 4);
|
|
27
|
+
const imageSize = getImageSize(input, 0);
|
|
28
|
+
if (nbImages === 1)
|
|
29
|
+
return imageSize;
|
|
30
|
+
const imgs = [imageSize];
|
|
31
|
+
for (let imageIndex = 1; imageIndex < nbImages; imageIndex += 1) {
|
|
32
|
+
imgs.push(getImageSize(input, imageIndex));
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
height: imageSize.height,
|
|
36
|
+
images: imgs,
|
|
37
|
+
width: imageSize.width
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
export {
|
|
42
|
+
ICO
|
|
43
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const typeHandlers: Map<"jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga", import("./interface.js").IImage>;
|
|
2
|
+
export declare const types: ("jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "heif" | "icns" | "ktx" | "bmp" | "cur" | "dds" | "ico" | "j2c" | "jp2" | "pnm" | "psd" | "tga")[];
|
|
3
|
+
export type imageType = typeof types[number];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BMP } from "./bmp.js";
|
|
2
|
+
import { CUR } from "./cur.js";
|
|
3
|
+
import { DDS } from "./dds.js";
|
|
4
|
+
import { GIF } from "./gif.js";
|
|
5
|
+
import { HEIF } from "./heif.js";
|
|
6
|
+
import { ICNS } from "./icns.js";
|
|
7
|
+
import { ICO } from "./ico.js";
|
|
8
|
+
import { J2C } from "./j2c.js";
|
|
9
|
+
import { JP2 } from "./jp2.js";
|
|
10
|
+
import { JPG } from "./jpg.js";
|
|
11
|
+
import { KTX } from "./ktx.js";
|
|
12
|
+
import { PNG } from "./png.js";
|
|
13
|
+
import { PNM } from "./pnm.js";
|
|
14
|
+
import { PSD } from "./psd.js";
|
|
15
|
+
import { SVG } from "./svg.js";
|
|
16
|
+
import { TGA } from "./tga.js";
|
|
17
|
+
import { TIFF } from "./tiff.js";
|
|
18
|
+
import { WEBP } from "./webp.js";
|
|
19
|
+
const typeHandlers = /* @__PURE__ */ new Map([
|
|
20
|
+
["bmp", BMP],
|
|
21
|
+
["cur", CUR],
|
|
22
|
+
["dds", DDS],
|
|
23
|
+
["gif", GIF],
|
|
24
|
+
["heif", HEIF],
|
|
25
|
+
["icns", ICNS],
|
|
26
|
+
["ico", ICO],
|
|
27
|
+
["j2c", J2C],
|
|
28
|
+
["jp2", JP2],
|
|
29
|
+
["jpg", JPG],
|
|
30
|
+
["ktx", KTX],
|
|
31
|
+
["png", PNG],
|
|
32
|
+
["pnm", PNM],
|
|
33
|
+
["psd", PSD],
|
|
34
|
+
["svg", SVG],
|
|
35
|
+
["tga", TGA],
|
|
36
|
+
["tiff", TIFF],
|
|
37
|
+
["webp", WEBP]
|
|
38
|
+
]);
|
|
39
|
+
const types = Array.from(typeHandlers.keys());
|
|
40
|
+
export {
|
|
41
|
+
typeHandlers,
|
|
42
|
+
types
|
|
43
|
+
};
|