astro 2.1.3 → 2.1.5

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.
Files changed (154) hide show
  1. package/dist/@types/astro.d.ts +15 -0
  2. package/dist/@types/typed-emitter.d.ts +1 -2
  3. package/dist/assets/consts.js +8 -0
  4. package/dist/assets/image-endpoint.js +1 -1
  5. package/dist/assets/internal.d.ts +2 -1
  6. package/dist/assets/internal.js +10 -5
  7. package/dist/assets/services/service.d.ts +10 -1
  8. package/dist/assets/services/service.js +35 -29
  9. package/dist/assets/services/sharp.d.ts +1 -1
  10. package/dist/assets/services/sharp.js +5 -4
  11. package/dist/assets/services/squoosh.d.ts +1 -1
  12. package/dist/assets/services/squoosh.js +7 -4
  13. package/dist/assets/services/vendor/squoosh/codecs.js +2 -0
  14. package/dist/assets/services/vendor/squoosh/image-pool.js +2 -0
  15. package/dist/assets/services/vendor/squoosh/impl.js +2 -0
  16. package/dist/assets/utils/metadata.js +2 -5
  17. package/dist/assets/vendor/image-size/detector.d.ts +3 -0
  18. package/dist/assets/vendor/image-size/detector.js +28 -0
  19. package/dist/assets/vendor/image-size/index.d.ts +11 -0
  20. package/dist/assets/vendor/image-size/index.js +93 -0
  21. package/dist/assets/vendor/image-size/readUInt.d.ts +4 -0
  22. package/dist/assets/vendor/image-size/readUInt.js +9 -0
  23. package/dist/assets/vendor/image-size/types/bmp.d.ts +2 -0
  24. package/dist/assets/vendor/image-size/types/bmp.js +14 -0
  25. package/dist/assets/vendor/image-size/types/cur.d.ts +2 -0
  26. package/dist/assets/vendor/image-size/types/cur.js +16 -0
  27. package/dist/assets/vendor/image-size/types/dds.d.ts +2 -0
  28. package/dist/assets/vendor/image-size/types/dds.js +14 -0
  29. package/dist/assets/vendor/image-size/types/gif.d.ts +2 -0
  30. package/dist/assets/vendor/image-size/types/gif.js +16 -0
  31. package/dist/assets/vendor/image-size/types/icns.d.ts +2 -0
  32. package/dist/assets/vendor/image-size/types/icns.js +87 -0
  33. package/dist/assets/vendor/image-size/types/ico.d.ts +2 -0
  34. package/dist/assets/vendor/image-size/types/ico.js +42 -0
  35. package/dist/assets/vendor/image-size/types/interface.d.ts +14 -0
  36. package/dist/assets/vendor/image-size/types/interface.js +0 -0
  37. package/dist/assets/vendor/image-size/types/j2c.d.ts +2 -0
  38. package/dist/assets/vendor/image-size/types/j2c.js +14 -0
  39. package/dist/assets/vendor/image-size/types/jp2.d.ts +2 -0
  40. package/dist/assets/vendor/image-size/types/jp2.js +56 -0
  41. package/dist/assets/vendor/image-size/types/jpg.d.ts +2 -0
  42. package/dist/assets/vendor/image-size/types/jpg.js +95 -0
  43. package/dist/assets/vendor/image-size/types/ktx.d.ts +2 -0
  44. package/dist/assets/vendor/image-size/types/ktx.js +15 -0
  45. package/dist/assets/vendor/image-size/types/png.d.ts +2 -0
  46. package/dist/assets/vendor/image-size/types/png.js +33 -0
  47. package/dist/assets/vendor/image-size/types/pnm.d.ts +2 -0
  48. package/dist/assets/vendor/image-size/types/pnm.js +72 -0
  49. package/dist/assets/vendor/image-size/types/psd.d.ts +2 -0
  50. package/dist/assets/vendor/image-size/types/psd.js +14 -0
  51. package/dist/assets/vendor/image-size/types/svg.d.ts +2 -0
  52. package/dist/assets/vendor/image-size/types/svg.js +91 -0
  53. package/dist/assets/vendor/image-size/types/tiff.d.ts +2 -0
  54. package/dist/assets/vendor/image-size/types/tiff.js +81 -0
  55. package/dist/assets/vendor/image-size/types/webp.d.ts +2 -0
  56. package/dist/assets/vendor/image-size/types/webp.js +51 -0
  57. package/dist/assets/vendor/image-size/types.d.ts +19 -0
  58. package/dist/assets/vendor/image-size/types.js +37 -0
  59. package/dist/assets/vendor/queue/queue.d.ts +39 -0
  60. package/dist/assets/vendor/queue/queue.js +187 -0
  61. package/dist/assets/vite-plugin-assets.js +4 -0
  62. package/dist/cli/check/index.js +43 -2
  63. package/dist/cli/check/print.d.ts +1 -1
  64. package/dist/content/error-map.js +4 -1
  65. package/dist/content/server-listeners.d.ts +1 -1
  66. package/dist/content/types-generator.d.ts +3 -3
  67. package/dist/content/types-generator.js +3 -0
  68. package/dist/content/utils.d.ts +2 -2
  69. package/dist/content/utils.js +2 -0
  70. package/dist/content/vite-plugin-content-assets.d.ts +1 -1
  71. package/dist/content/vite-plugin-content-imports.d.ts +1 -1
  72. package/dist/content/vite-plugin-content-imports.js +163 -77
  73. package/dist/content/vite-plugin-content-virtual-mod.js +4 -1
  74. package/dist/core/add/index.d.ts +1 -1
  75. package/dist/core/add/index.js +11 -9
  76. package/dist/core/app/index.js +4 -1
  77. package/dist/core/app/node.d.ts +1 -1
  78. package/dist/core/build/generate.d.ts +1 -1
  79. package/dist/core/build/generate.js +5 -1
  80. package/dist/core/build/index.js +4 -0
  81. package/dist/core/build/plugin.js +1 -0
  82. package/dist/core/build/plugins/plugin-css.d.ts +1 -1
  83. package/dist/core/build/plugins/plugin-pages.d.ts +1 -1
  84. package/dist/core/build/static-build.d.ts +1 -1
  85. package/dist/core/build/static-build.js +4 -1
  86. package/dist/core/compile/cache.d.ts +1 -1
  87. package/dist/core/compile/style.d.ts +1 -1
  88. package/dist/core/config/schema.d.ts +36 -36
  89. package/dist/core/config/schema.js +9 -1
  90. package/dist/core/config/timer.js +9 -0
  91. package/dist/core/config/tsconfig.js +4 -0
  92. package/dist/core/config/vite-load.js +3 -0
  93. package/dist/core/constants.js +1 -1
  94. package/dist/core/cookies/cookies.js +35 -1
  95. package/dist/core/create-vite.js +30 -3
  96. package/dist/core/dev/container.js +1 -0
  97. package/dist/core/dev/dev.d.ts +1 -1
  98. package/dist/core/dev/dev.js +2 -1
  99. package/dist/core/endpoint/index.d.ts +1 -1
  100. package/dist/core/endpoint/index.js +1 -0
  101. package/dist/core/errors/dev/utils.d.ts +1 -1
  102. package/dist/core/errors/dev/utils.js +2 -1
  103. package/dist/core/errors/dev/vite.d.ts +1 -1
  104. package/dist/core/errors/dev/vite.js +5 -0
  105. package/dist/core/errors/errors-data.js +486 -3
  106. package/dist/core/errors/errors.js +2 -0
  107. package/dist/core/errors/overlay.js +16 -5
  108. package/dist/core/errors/utils.d.ts +1 -1
  109. package/dist/core/logger/console.js +1 -1
  110. package/dist/core/logger/node.js +1 -1
  111. package/dist/core/messages.d.ts +1 -1
  112. package/dist/core/messages.js +2 -2
  113. package/dist/core/module-loader/loader.d.ts +3 -3
  114. package/dist/core/render/dev/css.js +2 -1
  115. package/dist/core/render/dev/environment.js +1 -0
  116. package/dist/core/render/dev/index.js +1 -0
  117. package/dist/core/render/dev/resolve.js +1 -6
  118. package/dist/core/render/dev/vite.js +13 -1
  119. package/dist/core/render/index.d.ts +1 -1
  120. package/dist/core/render/result.d.ts +1 -1
  121. package/dist/core/render/result.js +4 -0
  122. package/dist/core/render/route-cache.d.ts +1 -1
  123. package/dist/core/render/route-cache.js +1 -0
  124. package/dist/core/routing/manifest/create.js +4 -1
  125. package/dist/core/sync/index.d.ts +1 -1
  126. package/dist/core/sync/index.js +1 -1
  127. package/dist/events/error.d.ts +1 -1
  128. package/dist/integrations/index.d.ts +1 -1
  129. package/dist/jsx/renderer.js +1 -0
  130. package/dist/runtime/client/visible.prebuilt.d.ts +1 -1
  131. package/dist/runtime/client/visible.prebuilt.js +1 -1
  132. package/dist/runtime/server/hydration.js +1 -0
  133. package/dist/runtime/server/render/scope.js +5 -0
  134. package/dist/runtime/server/scripts.js +2 -2
  135. package/dist/vite-plugin-astro/compile.d.ts +2 -2
  136. package/dist/vite-plugin-astro/compile.js +1 -0
  137. package/dist/vite-plugin-astro/index.js +7 -1
  138. package/dist/vite-plugin-astro-server/base.d.ts +1 -1
  139. package/dist/vite-plugin-astro-server/common.d.ts +1 -1
  140. package/dist/vite-plugin-astro-server/response.js +2 -2
  141. package/dist/vite-plugin-config-alias/index.d.ts +2 -7
  142. package/dist/vite-plugin-config-alias/index.js +32 -41
  143. package/dist/vite-plugin-env/index.js +1 -0
  144. package/dist/vite-plugin-inject-env-ts/index.d.ts +2 -2
  145. package/dist/vite-plugin-inject-env-ts/index.js +2 -0
  146. package/dist/vite-plugin-jsx/index.d.ts +1 -1
  147. package/dist/vite-plugin-jsx/index.js +7 -1
  148. package/dist/vite-plugin-jsx/tag.js +7 -0
  149. package/dist/vite-plugin-markdown/index.js +27 -58
  150. package/dist/vite-plugin-scanner/index.d.ts +1 -1
  151. package/dist/vite-plugin-scripts/page-ssr.d.ts +1 -1
  152. package/package.json +5 -6
  153. package/src/content/template/types.d.ts +12 -1
  154. package/tsconfigs/base.json +4 -1
@@ -5,6 +5,7 @@ import type { MarkdownHeading, MarkdownMetadata, MarkdownRenderingResult, Rehype
5
5
  import type * as babel from '@babel/core';
6
6
  import type { OutgoingHttpHeaders } from 'http';
7
7
  import type { AddressInfo } from 'net';
8
+ import type * as rollup from 'rollup';
8
9
  import type { TsConfigJson } from 'tsconfig-resolver';
9
10
  import type * as vite from 'vite';
10
11
  import type { z } from 'zod';
@@ -956,12 +957,26 @@ export interface InjectedRoute {
956
957
  export interface AstroConfig extends z.output<typeof AstroConfigSchema> {
957
958
  integrations: AstroIntegration[];
958
959
  }
960
+ export type ContentEntryModule = {
961
+ id: string;
962
+ collection: string;
963
+ slug: string;
964
+ body: string;
965
+ data: Record<string, unknown>;
966
+ _internal: {
967
+ rawData: string;
968
+ filePath: string;
969
+ };
970
+ };
959
971
  export interface ContentEntryType {
960
972
  extensions: string[];
961
973
  getEntryInfo(params: {
962
974
  fileUrl: URL;
963
975
  contents: string;
964
976
  }): GetEntryInfoReturnType | Promise<GetEntryInfoReturnType>;
977
+ getRenderModule?(params: {
978
+ entry: ContentEntryModule;
979
+ }): rollup.LoadResult | Promise<rollup.LoadResult>;
965
980
  contentModuleTypes?: string;
966
981
  }
967
982
  type GetEntryInfoReturnType = {
@@ -22,7 +22,7 @@ export type EventMap = {
22
22
  * myEmitter.emit("error", "x") // <- Will catch this type error;
23
23
  * ```
24
24
  */
25
- interface TypedEventEmitter<Events extends EventMap> {
25
+ export interface TypedEventEmitter<Events extends EventMap> {
26
26
  addListener<E extends keyof Events>(event: E, listener: Events[E]): this;
27
27
  on<E extends keyof Events>(event: E, listener: Events[E]): this;
28
28
  once<E extends keyof Events>(event: E, listener: Events[E]): this;
@@ -39,4 +39,3 @@ interface TypedEventEmitter<Events extends EventMap> {
39
39
  getMaxListeners(): number;
40
40
  setMaxListeners(maxListeners: number): this;
41
41
  }
42
- export default TypedEventEmitter;
@@ -1,6 +1,14 @@
1
1
  const VIRTUAL_MODULE_ID = "astro:assets";
2
2
  const VIRTUAL_SERVICE_ID = "virtual:image-service";
3
3
  const VALID_INPUT_FORMATS = [
4
+ // TODO: `image-size` does not support the following formats, so users can't import them.
5
+ // However, it would be immensely useful to add, for three reasons:
6
+ // - `heic` and `heif` are common formats, especially among Apple users.
7
+ // - AVIF is a common format on the web that's bound to become more and more common.
8
+ // - It's totally reasonable for an user's provided image service to want to support more image types.
9
+ //'heic',
10
+ //'heif',
11
+ //'avif',
4
12
  "jpeg",
5
13
  "jpg",
6
14
  "png",
@@ -38,7 +38,7 @@ const get = async ({ request }) => {
38
38
  "Content-Type": mime.getType(format) || "",
39
39
  "Cache-Control": "public, max-age=31536000",
40
40
  ETag: etag(data.toString()),
41
- Date: new Date().toUTCString()
41
+ Date: (/* @__PURE__ */ new Date()).toUTCString()
42
42
  }
43
43
  });
44
44
  } catch (err) {
@@ -1,9 +1,10 @@
1
1
  import type { StaticBuildOptions } from '../core/build/types.js';
2
- import { ImageService } from './services/service.js';
2
+ import { type ImageService } from './services/service.js';
3
3
  import type { ImageMetadata, ImageTransform } from './types.js';
4
4
  export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
5
5
  export declare function getConfiguredImageService(): Promise<ImageService>;
6
6
  interface GetImageResult {
7
+ rawOptions: ImageTransform;
7
8
  options: ImageTransform;
8
9
  src: string;
9
10
  attributes: Record<string, any>;
@@ -6,7 +6,10 @@ function isESMImportedImage(src) {
6
6
  }
7
7
  async function getConfiguredImageService() {
8
8
  if (!globalThis.astroAsset.imageService) {
9
- const { default: service } = await import("virtual:image-service").catch((e) => {
9
+ const { default: service } = await import(
10
+ // @ts-expect-error
11
+ "virtual:image-service"
12
+ ).catch((e) => {
10
13
  const error = new AstroError(AstroErrorData.InvalidImageService);
11
14
  error.cause = e;
12
15
  throw error;
@@ -18,14 +21,16 @@ async function getConfiguredImageService() {
18
21
  }
19
22
  async function getImage(options) {
20
23
  const service = await getConfiguredImageService();
21
- let imageURL = service.getURL(options);
24
+ const validatedOptions = service.validateOptions ? service.validateOptions(options) : options;
25
+ let imageURL = service.getURL(validatedOptions);
22
26
  if (isLocalService(service) && globalThis.astroAsset.addStaticImage) {
23
- imageURL = globalThis.astroAsset.addStaticImage(options);
27
+ imageURL = globalThis.astroAsset.addStaticImage(validatedOptions);
24
28
  }
25
29
  return {
26
- options,
30
+ rawOptions: options,
31
+ options: validatedOptions,
27
32
  src: imageURL,
28
- attributes: service.getHTMLAttributes !== void 0 ? service.getHTMLAttributes(options) : {}
33
+ attributes: service.getHTMLAttributes !== void 0 ? service.getHTMLAttributes(validatedOptions) : {}
29
34
  };
30
35
  }
31
36
  function getStaticImageList() {
@@ -20,6 +20,15 @@ interface SharedServiceProps {
20
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
21
  */
22
22
  getHTMLAttributes?: (options: ImageTransform) => Record<string, any>;
23
+ /**
24
+ * Validate and return the options passed by the user.
25
+ *
26
+ * This method is useful to present errors to users who have entered invalid options.
27
+ * For instance, if they are missing a required property or have entered an invalid image format.
28
+ *
29
+ * This method should returns options, and can be used to set defaults (ex: a default output format to be used if the user didn't specify one.)
30
+ */
31
+ validateOptions?: (options: ImageTransform) => ImageTransform;
23
32
  }
24
33
  export type ExternalImageService = SharedServiceProps;
25
34
  type LocalImageTransform = {
@@ -46,7 +55,7 @@ export type BaseServiceTransform = {
46
55
  src: string;
47
56
  width?: number;
48
57
  height?: number;
49
- format?: string | null;
58
+ format: string;
50
59
  quality?: string | null;
51
60
  };
52
61
  /**
@@ -1,5 +1,4 @@
1
1
  import { AstroError, AstroErrorData } from "../../core/errors/index.js";
2
- import { isRemotePath } from "../../core/path.js";
3
2
  import { VALID_INPUT_FORMATS } from "../consts.js";
4
3
  import { isESMImportedImage } from "../internal.js";
5
4
  function isLocalService(service) {
@@ -16,6 +15,39 @@ function parseQuality(quality) {
16
15
  return result;
17
16
  }
18
17
  const baseService = {
18
+ validateOptions(options) {
19
+ if (!isESMImportedImage(options.src)) {
20
+ let missingDimension;
21
+ if (!options.width && !options.height) {
22
+ missingDimension = "both";
23
+ } else if (!options.width && options.height) {
24
+ missingDimension = "width";
25
+ } else if (options.width && !options.height) {
26
+ missingDimension = "height";
27
+ }
28
+ if (missingDimension) {
29
+ throw new AstroError({
30
+ ...AstroErrorData.MissingImageDimension,
31
+ message: AstroErrorData.MissingImageDimension.message(missingDimension, options.src)
32
+ });
33
+ }
34
+ } else {
35
+ if (!VALID_INPUT_FORMATS.includes(options.src.format)) {
36
+ throw new AstroError({
37
+ ...AstroErrorData.UnsupportedImageFormat,
38
+ message: AstroErrorData.UnsupportedImageFormat.message(
39
+ options.src.format,
40
+ options.src.src,
41
+ VALID_INPUT_FORMATS
42
+ )
43
+ });
44
+ }
45
+ }
46
+ if (!options.format) {
47
+ options.format = "webp";
48
+ }
49
+ return options;
50
+ },
19
51
  getHTMLAttributes(options) {
20
52
  let targetWidth = options.width;
21
53
  let targetHeight = options.height;
@@ -25,7 +57,7 @@ const baseService = {
25
57
  targetWidth = Math.round(targetHeight * aspectRatio);
26
58
  } else if (targetWidth && !targetHeight) {
27
59
  targetHeight = Math.round(targetWidth / aspectRatio);
28
- } else {
60
+ } else if (!targetWidth && !targetHeight) {
29
61
  targetWidth = options.src.width;
30
62
  targetHeight = options.src.height;
31
63
  }
@@ -41,36 +73,10 @@ const baseService = {
41
73
  },
42
74
  getURL(options) {
43
75
  if (!isESMImportedImage(options.src)) {
44
- let missingDimension;
45
- if (!options.width && !options.height) {
46
- missingDimension = "both";
47
- } else if (!options.width && options.height) {
48
- missingDimension = "width";
49
- } else if (options.width && !options.height) {
50
- missingDimension = "height";
51
- }
52
- if (missingDimension) {
53
- throw new AstroError({
54
- ...AstroErrorData.MissingImageDimension,
55
- message: AstroErrorData.MissingImageDimension.message(missingDimension, options.src)
56
- });
57
- }
58
- }
59
- if (!isESMImportedImage(options.src) && isRemotePath(options.src)) {
60
76
  return options.src;
61
77
  }
62
- if (isESMImportedImage(options.src) && !VALID_INPUT_FORMATS.includes(options.src.format)) {
63
- throw new AstroError({
64
- ...AstroErrorData.UnsupportedImageFormat,
65
- message: AstroErrorData.UnsupportedImageFormat.message(
66
- options.src.format,
67
- options.src.src,
68
- VALID_INPUT_FORMATS
69
- )
70
- });
71
- }
72
78
  const searchParams = new URLSearchParams();
73
- searchParams.append("href", isESMImportedImage(options.src) ? options.src.src : options.src);
79
+ searchParams.append("href", options.src.src);
74
80
  options.width && searchParams.append("w", options.width.toString());
75
81
  options.height && searchParams.append("h", options.height.toString());
76
82
  options.quality && searchParams.append("q", options.quality.toString());
@@ -1,3 +1,3 @@
1
- import { LocalImageService } from './service.js';
1
+ import { type LocalImageService } from './service.js';
2
2
  declare const sharpService: LocalImageService;
3
3
  export default sharpService;
@@ -1,4 +1,7 @@
1
- import { baseService, parseQuality } from "./service.js";
1
+ import {
2
+ baseService,
3
+ parseQuality
4
+ } from "./service.js";
2
5
  let sharp;
3
6
  const qualityTable = {
4
7
  low: 25,
@@ -16,6 +19,7 @@ async function loadSharp() {
16
19
  return sharpImport;
17
20
  }
18
21
  const sharpService = {
22
+ validateOptions: baseService.validateOptions,
19
23
  getURL: baseService.getURL,
20
24
  parseURL: baseService.parseURL,
21
25
  getHTMLAttributes: baseService.getHTMLAttributes,
@@ -23,9 +27,6 @@ const sharpService = {
23
27
  if (!sharp)
24
28
  sharp = await loadSharp();
25
29
  const transform = transformOptions;
26
- if (!transform.format) {
27
- transform.format = "webp";
28
- }
29
30
  let result = sharp(inputBuffer, { failOnError: false, pages: -1 });
30
31
  if (transform.height && !transform.width) {
31
32
  result.resize({ height: transform.height });
@@ -1,3 +1,3 @@
1
- import { LocalImageService } from './service.js';
1
+ import { type LocalImageService } from './service.js';
2
2
  declare const service: LocalImageService;
3
3
  export default service;
@@ -1,8 +1,12 @@
1
- import { baseService, parseQuality } from "./service.js";
1
+ import {
2
+ baseService,
3
+ parseQuality
4
+ } from "./service.js";
2
5
  import { processBuffer } from "./vendor/squoosh/image-pool.js";
3
6
  const baseQuality = { low: 25, mid: 50, high: 80, max: 100 };
4
7
  const qualityTable = {
5
8
  avif: {
9
+ // Squoosh's AVIF encoder has a bit of a weird behavior where `62` is technically the maximum, and anything over is overkill
6
10
  max: 62,
7
11
  high: 45,
8
12
  mid: 35,
@@ -11,17 +15,16 @@ const qualityTable = {
11
15
  jpeg: baseQuality,
12
16
  jpg: baseQuality,
13
17
  webp: baseQuality
18
+ // Squoosh's PNG encoder does not support a quality setting, so we can skip that here
14
19
  };
15
20
  const service = {
21
+ validateOptions: baseService.validateOptions,
16
22
  getURL: baseService.getURL,
17
23
  parseURL: baseService.parseURL,
18
24
  getHTMLAttributes: baseService.getHTMLAttributes,
19
25
  async transform(inputBuffer, transformOptions) {
20
26
  const transform = transformOptions;
21
27
  let format = transform.format;
22
- if (!format) {
23
- format = "webp";
24
- }
25
28
  const operations = [];
26
29
  if (transform.height && !transform.width) {
27
30
  operations.push({
@@ -212,6 +212,7 @@ const codecs = {
212
212
  avif: {
213
213
  name: "AVIF",
214
214
  extension: "avif",
215
+ // eslint-disable-next-line no-control-regex
215
216
  detectors: [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/],
216
217
  dec: () => instantiateEmscriptenWasm(avifDec, avifDecWasm.toString()),
217
218
  enc: async () => {
@@ -241,6 +242,7 @@ const codecs = {
241
242
  oxipng: {
242
243
  name: "OxiPNG",
243
244
  extension: "png",
245
+ // eslint-disable-next-line no-control-regex
244
246
  detectors: [/^\x89PNG\x0D\x0A\x1A\x0A/],
245
247
  dec: async () => {
246
248
  await pngEncDecInit();
@@ -7,6 +7,8 @@ import execOnce from "./utils/execOnce.js";
7
7
  import WorkerPool from "./utils/workerPool.js";
8
8
  const getWorker = execOnce(() => {
9
9
  return new WorkerPool(
10
+ // There will be at most 7 workers needed since each worker will take
11
+ // at least 1 operation type.
10
12
  Math.max(1, Math.min(cpus().length - 1, 7)),
11
13
  fileURLToPath(getModuleURL(import.meta.url))
12
14
  );
@@ -85,6 +85,8 @@ async function encodeAvif(image, opts) {
85
85
  const quality = opts.quality || 75;
86
86
  const r = await m.encode(image.data, image.width, image.height, {
87
87
  ...e.defaultEncoderOptions,
88
+ // Think of cqLevel as the "amount" of quantization (0 to 62),
89
+ // so a lower value yields higher quality (0 to 100).
88
90
  cqLevel: quality === 0 ? val : Math.round(val - quality / 100 * val)
89
91
  });
90
92
  return r;
@@ -1,10 +1,7 @@
1
1
  import fs from "node:fs/promises";
2
2
  import { fileURLToPath } from "node:url";
3
- let sizeOf;
3
+ import imageSize from "../vendor/image-size/index.js";
4
4
  async function imageMetadata(src, data) {
5
- if (!sizeOf) {
6
- sizeOf = await import("image-size").then((mod) => mod.default);
7
- }
8
5
  let file = data;
9
6
  if (!file) {
10
7
  try {
@@ -13,7 +10,7 @@ async function imageMetadata(src, data) {
13
10
  return void 0;
14
11
  }
15
12
  }
16
- const { width, height, type, orientation } = await sizeOf(file);
13
+ const { width, height, type, orientation } = imageSize(file);
17
14
  const isPortrait = (orientation || 0) >= 5;
18
15
  if (!width || !height || !type) {
19
16
  return void 0;
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import { type imageType } from './types.js';
3
+ export declare function detector(buffer: Buffer): imageType | undefined;
@@ -0,0 +1,28 @@
1
+ import { typeHandlers } from "./types.js";
2
+ const keys = Object.keys(typeHandlers);
3
+ const firstBytes = {
4
+ 56: "psd",
5
+ 66: "bmp",
6
+ 68: "dds",
7
+ 71: "gif",
8
+ 73: "tiff",
9
+ 77: "tiff",
10
+ 82: "webp",
11
+ 105: "icns",
12
+ 137: "png",
13
+ 255: "jpg"
14
+ };
15
+ function detector(buffer) {
16
+ const byte = buffer[0];
17
+ if (byte in firstBytes) {
18
+ const type = firstBytes[byte];
19
+ if (type && typeHandlers[type].validate(buffer)) {
20
+ return type;
21
+ }
22
+ }
23
+ const finder = (key) => typeHandlers[key].validate(buffer);
24
+ return keys.find(finder);
25
+ }
26
+ export {
27
+ detector
28
+ };
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import { type imageType } from "./types.js";
3
+ import type { ISizeCalculationResult } from "./types/interface.js";
4
+ type CallbackFn = (e: Error | null, r?: ISizeCalculationResult) => void;
5
+ export default imageSize;
6
+ export declare function imageSize(input: Buffer | string): ISizeCalculationResult;
7
+ export declare function imageSize(input: string, callback: CallbackFn): void;
8
+ export declare const disableFS: (v: boolean) => void;
9
+ export declare const disableTypes: (types: imageType[]) => void;
10
+ export declare const setConcurrency: (c: number) => void;
11
+ export declare const types: string[];
@@ -0,0 +1,93 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import Queue from "../queue/queue.js";
4
+ import { detector } from "./detector.js";
5
+ import { typeHandlers } from "./types.js";
6
+ const MaxBufferSize = 512 * 1024;
7
+ const queue = new Queue({ concurrency: 100, autostart: true });
8
+ const globalOptions = {
9
+ disabledFS: false,
10
+ disabledTypes: []
11
+ };
12
+ function lookup(buffer, filepath) {
13
+ const type = detector(buffer);
14
+ if (typeof type !== "undefined") {
15
+ if (globalOptions.disabledTypes.indexOf(type) > -1) {
16
+ throw new TypeError("disabled file type: " + type);
17
+ }
18
+ if (type in typeHandlers) {
19
+ const size = typeHandlers[type].calculate(buffer, filepath);
20
+ if (size !== void 0) {
21
+ size.type = type;
22
+ return size;
23
+ }
24
+ }
25
+ }
26
+ throw new TypeError(
27
+ "unsupported file type: " + type + " (file: " + filepath + ")"
28
+ );
29
+ }
30
+ async function asyncFileToBuffer(filepath) {
31
+ const handle = await fs.promises.open(filepath, "r");
32
+ const { size } = await handle.stat();
33
+ if (size <= 0) {
34
+ await handle.close();
35
+ throw new Error("Empty file");
36
+ }
37
+ const bufferSize = Math.min(size, MaxBufferSize);
38
+ const buffer = Buffer.alloc(bufferSize);
39
+ await handle.read(buffer, 0, bufferSize, 0);
40
+ await handle.close();
41
+ return buffer;
42
+ }
43
+ function syncFileToBuffer(filepath) {
44
+ const descriptor = fs.openSync(filepath, "r");
45
+ const { size } = fs.fstatSync(descriptor);
46
+ if (size <= 0) {
47
+ fs.closeSync(descriptor);
48
+ throw new Error("Empty file");
49
+ }
50
+ const bufferSize = Math.min(size, MaxBufferSize);
51
+ const buffer = Buffer.alloc(bufferSize);
52
+ fs.readSync(descriptor, buffer, 0, bufferSize, 0);
53
+ fs.closeSync(descriptor);
54
+ return buffer;
55
+ }
56
+ var image_size_default = imageSize;
57
+ function imageSize(input, callback) {
58
+ if (Buffer.isBuffer(input)) {
59
+ return lookup(input);
60
+ }
61
+ if (typeof input !== "string" || globalOptions.disabledFS) {
62
+ throw new TypeError("invalid invocation. input should be a Buffer");
63
+ }
64
+ const filepath = path.resolve(input);
65
+ if (typeof callback === "function") {
66
+ queue.push(
67
+ () => asyncFileToBuffer(filepath).then(
68
+ (buffer) => process.nextTick(callback, null, lookup(buffer, filepath))
69
+ ).catch(callback)
70
+ );
71
+ } else {
72
+ const buffer = syncFileToBuffer(filepath);
73
+ return lookup(buffer, filepath);
74
+ }
75
+ }
76
+ const disableFS = (v) => {
77
+ globalOptions.disabledFS = v;
78
+ };
79
+ const disableTypes = (types2) => {
80
+ globalOptions.disabledTypes = types2;
81
+ };
82
+ const setConcurrency = (c) => {
83
+ queue.concurrency = c;
84
+ };
85
+ const types = Object.keys(typeHandlers);
86
+ export {
87
+ image_size_default as default,
88
+ disableFS,
89
+ disableTypes,
90
+ imageSize,
91
+ setConcurrency,
92
+ types
93
+ };
@@ -0,0 +1,4 @@
1
+ /// <reference types="node" />
2
+ type Bits = 16 | 32;
3
+ export declare function readUInt(buffer: Buffer, bits: Bits, offset: number, isBigEndian: boolean): number;
4
+ export {};
@@ -0,0 +1,9 @@
1
+ function readUInt(buffer, bits, offset, isBigEndian) {
2
+ offset = offset || 0;
3
+ const endian = isBigEndian ? "BE" : "LE";
4
+ const methodName = "readUInt" + bits + endian;
5
+ return buffer[methodName].call(buffer, offset);
6
+ }
7
+ export {
8
+ readUInt
9
+ };
@@ -0,0 +1,2 @@
1
+ import type { IImage } from './interface';
2
+ export declare const BMP: IImage;
@@ -0,0 +1,14 @@
1
+ const BMP = {
2
+ validate(buffer) {
3
+ return "BM" === buffer.toString("ascii", 0, 2);
4
+ },
5
+ calculate(buffer) {
6
+ return {
7
+ height: Math.abs(buffer.readInt32LE(22)),
8
+ width: buffer.readUInt32LE(18)
9
+ };
10
+ }
11
+ };
12
+ export {
13
+ BMP
14
+ };
@@ -0,0 +1,2 @@
1
+ import type { IImage } from './interface';
2
+ export declare const CUR: IImage;
@@ -0,0 +1,16 @@
1
+ import { ICO } from "./ico.js";
2
+ const TYPE_CURSOR = 2;
3
+ const CUR = {
4
+ validate(buffer) {
5
+ if (buffer.readUInt16LE(0) !== 0) {
6
+ return false;
7
+ }
8
+ return buffer.readUInt16LE(2) === TYPE_CURSOR;
9
+ },
10
+ calculate(buffer) {
11
+ return ICO.calculate(buffer);
12
+ }
13
+ };
14
+ export {
15
+ CUR
16
+ };
@@ -0,0 +1,2 @@
1
+ import type { IImage } from './interface';
2
+ export declare const DDS: IImage;
@@ -0,0 +1,14 @@
1
+ const DDS = {
2
+ validate(buffer) {
3
+ return buffer.readUInt32LE(0) === 542327876;
4
+ },
5
+ calculate(buffer) {
6
+ return {
7
+ height: buffer.readUInt32LE(12),
8
+ width: buffer.readUInt32LE(16)
9
+ };
10
+ }
11
+ };
12
+ export {
13
+ DDS
14
+ };
@@ -0,0 +1,2 @@
1
+ import type { IImage } from './interface';
2
+ export declare const GIF: IImage;
@@ -0,0 +1,16 @@
1
+ const gifRegexp = /^GIF8[79]a/;
2
+ const GIF = {
3
+ validate(buffer) {
4
+ const signature = buffer.toString("ascii", 0, 6);
5
+ return gifRegexp.test(signature);
6
+ },
7
+ calculate(buffer) {
8
+ return {
9
+ height: buffer.readUInt16LE(8),
10
+ width: buffer.readUInt16LE(6)
11
+ };
12
+ }
13
+ };
14
+ export {
15
+ GIF
16
+ };
@@ -0,0 +1,2 @@
1
+ import type { IImage } from './interface';
2
+ export declare const ICNS: IImage;