next-imagetools 0.0.0-stage → 0.0.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.
@@ -0,0 +1,38 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_shared = require("./shared-DNQObFGr.cjs");
6
+ let node_fs_promises = require("node:fs/promises");
7
+ let node_fs = require("node:fs");
8
+ // src/asset-loader.ts
9
+ function imagetoolsAssetLoader() {
10
+ return require_shared.withContext(this, () => load.call(this));
11
+ }
12
+ async function load() {
13
+ const options = this.getOptions?.() ?? {};
14
+ const params = new URLSearchParams(this.resourceQuery);
15
+ const ext = params.get(`nit_ext`);
16
+ params.delete("nit");
17
+ params.delete(`nit_ext`);
18
+ const config = Object.fromEntries(params);
19
+ let sourcePath = this.resourcePath;
20
+ if (ext && sourcePath.endsWith(`.${ext}`) && !(0, node_fs.existsSync)(sourcePath)) sourcePath = sourcePath.slice(0, -ext.length - 1);
21
+ this.addDependency?.(sourcePath);
22
+ const source = await (0, node_fs_promises.readFile)(sourcePath);
23
+ const { factories, hash: configHash } = await require_shared.loadConfig(this, options);
24
+ return (await require_shared.processImage({
25
+ source,
26
+ factories,
27
+ configHash,
28
+ sourceHash: require_shared.hash([source]),
29
+ config,
30
+ searchParams: params,
31
+ cacheDir: await require_shared.prepareCache(this, options),
32
+ logger: console,
33
+ removeMetadata: options.removeMetadata !== false
34
+ })).data;
35
+ }
36
+ const raw = true;
37
+ exports.default = imagetoolsAssetLoader;
38
+ exports.raw = raw;
@@ -0,0 +1,27 @@
1
+ import { ImageConfig, OutputFormat, TransformFactory } from "imagetools-core";
2
+ import { Metadata } from "sharp";
3
+ /**
4
+ * Options that take functions. Turbopack passes loader options to worker processes as JSON, so
5
+ * these live in a module of their own — referenced by `configFile` — that each worker imports.
6
+ */
7
+ interface ImagetoolsConfig {
8
+ /** Add or replace transforms; receives the built-in transform factories. */
9
+ extendTransforms?: (builtins: TransformFactory[]) => TransformFactory[];
10
+ /**
11
+ * Add or replace output formats (`as=<name>`); receives the built-in ones. A format's result is
12
+ * serialized into the importing module, so it must be JSON-serializable.
13
+ */
14
+ extendOutputFormats?: (builtins: Record<string, OutputFormat>) => Record<string, OutputFormat>;
15
+ /** Replace how directives expand into the list of images to generate. */
16
+ resolveConfigs?: (entries: [string, string[]][], outputFormats: Record<string, OutputFormat>) => ImageConfig[] | undefined;
17
+ /**
18
+ * Directives that depend on the image. Applied beneath the preset and the query, above the
19
+ * `defaultDirectives` option. `url` is the source path with its query; `metadata` reads the
20
+ * source's sharp metadata on first call.
21
+ */
22
+ defaultDirectives?: (url: URL, metadata: () => Promise<Metadata>) => URLSearchParams | Promise<URLSearchParams>;
23
+ }
24
+ /** Identity helper that types an imagetools config file. */
25
+ declare function defineConfig(config: ImagetoolsConfig): ImagetoolsConfig;
26
+ export { defineConfig as n, ImagetoolsConfig as t };
27
+ //# sourceMappingURL=config-MI8A5KvL.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-MI8A5KvL.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;UAOiB;;EAEf,oBAAoB,UAAU,uBAAuB;;;;;EAKrD,uBAAuB,UAAU,eAAe,kBAAkB,eAAe;;EAEjF,kBACE,+BACA,eAAe,eAAe,kBAC3B;;;;;;EAML,qBACE,KAAK,KACL,gBAAgB,QAAQ,cACrB,kBAAkB,QAAQ;;;iBAIjB,aAAa,QAAQ,mBAAmB"}
@@ -0,0 +1,7 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ // src/config.ts
3
+ /** Identity helper that types an imagetools config file. */
4
+ function defineConfig(config) {
5
+ return config;
6
+ }
7
+ exports.defineConfig = defineConfig;
@@ -0,0 +1,26 @@
1
+ import { ImageConfig, OutputFormat, TransformFactory } from "imagetools-core";
2
+ import { Metadata } from "sharp";
3
+ /**
4
+ * Options that take functions. Turbopack passes loader options to worker processes as JSON, so
5
+ * these live in a module of their own — referenced by `configFile` — that each worker imports.
6
+ */
7
+ export interface ImagetoolsConfig {
8
+ /** Add or replace transforms; receives the built-in transform factories. */
9
+ extendTransforms?: (builtins: TransformFactory[]) => TransformFactory[];
10
+ /**
11
+ * Add or replace output formats (`as=<name>`); receives the built-in ones. A format's result is
12
+ * serialized into the importing module, so it must be JSON-serializable.
13
+ */
14
+ extendOutputFormats?: (builtins: Record<string, OutputFormat>) => Record<string, OutputFormat>;
15
+ /** Replace how directives expand into the list of images to generate. */
16
+ resolveConfigs?: (entries: [string, string[]][], outputFormats: Record<string, OutputFormat>) => ImageConfig[] | undefined;
17
+ /**
18
+ * Directives that depend on the image. Applied beneath the preset and the query, above the
19
+ * `defaultDirectives` option. `url` is the source path with its query; `metadata` reads the
20
+ * source's sharp metadata on first call.
21
+ */
22
+ defaultDirectives?: (url: URL, metadata: () => Promise<Metadata>) => URLSearchParams | Promise<URLSearchParams>;
23
+ }
24
+ /** Identity helper that types an imagetools config file. */
25
+ export declare function defineConfig(config: ImagetoolsConfig): ImagetoolsConfig;
26
+ //# sourceMappingURL=config.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;iBAOiB;;EAEf,oBAAoB,UAAU,uBAAuB;;;;;EAKrD,uBAAuB,UAAU,eAAe,kBAAkB,eAAe;;EAEjF,kBACE,+BACA,eAAe,eAAe,kBAC3B;;;;;;EAML,qBACE,KAAK,KACL,gBAAgB,QAAQ,cACrB,kBAAkB,QAAQ;;;wBAIjB,aAAa,QAAQ,mBAAmB"}
@@ -0,0 +1,2 @@
1
+ import { n as defineConfig, t as ImagetoolsConfig } from "./config-MI8A5KvL.mjs";
2
+ export { ImagetoolsConfig, defineConfig };
@@ -0,0 +1,8 @@
1
+ // src/config.ts
2
+ /** Identity helper that types an imagetools config file. */
3
+ function defineConfig(config) {
4
+ return config;
5
+ }
6
+ export { defineConfig };
7
+
8
+ //# sourceMappingURL=config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import type { ImageConfig, OutputFormat, TransformFactory } from 'imagetools-core';\nimport type { Metadata } from 'sharp';\n\n/**\n * Options that take functions. Turbopack passes loader options to worker processes as JSON, so\n * these live in a module of their own — referenced by `configFile` — that each worker imports.\n */\nexport interface ImagetoolsConfig {\n /** Add or replace transforms; receives the built-in transform factories. */\n extendTransforms?: (builtins: TransformFactory[]) => TransformFactory[];\n /**\n * Add or replace output formats (`as=<name>`); receives the built-in ones. A format's result is\n * serialized into the importing module, so it must be JSON-serializable.\n */\n extendOutputFormats?: (builtins: Record<string, OutputFormat>) => Record<string, OutputFormat>;\n /** Replace how directives expand into the list of images to generate. */\n resolveConfigs?: (\n entries: [string, string[]][],\n outputFormats: Record<string, OutputFormat>,\n ) => ImageConfig[] | undefined;\n /**\n * Directives that depend on the image. Applied beneath the preset and the query, above the\n * `defaultDirectives` option. `url` is the source path with its query; `metadata` reads the\n * source's sharp metadata on first call.\n */\n defaultDirectives?: (\n url: URL,\n metadata: () => Promise<Metadata>,\n ) => URLSearchParams | Promise<URLSearchParams>;\n}\n\n/** Identity helper that types an imagetools config file. */\nexport function defineConfig(config: ImagetoolsConfig): ImagetoolsConfig {\n return config;\n}\n"],"mappings":";;AAgCA,SAAgB,aAAa,QAA4C;CACvE,OAAO;AACT"}
package/dist/core.cjs ADDED
@@ -0,0 +1,9 @@
1
+ var imagetools_core = require("imagetools-core");
2
+ Object.keys(imagetools_core).forEach(function(k) {
3
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
4
+ enumerable: true,
5
+ get: function() {
6
+ return imagetools_core[k];
7
+ }
8
+ });
9
+ });
@@ -0,0 +1 @@
1
+ export * from "imagetools-core";
@@ -0,0 +1 @@
1
+ export * from "imagetools-core";
package/dist/core.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export * from "imagetools-core";
2
+ export {};
package/dist/index.cjs ADDED
@@ -0,0 +1,87 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ // src/index.ts
3
+ const DEFAULT_EXTENSIONS = [
4
+ "jpg",
5
+ "jpeg",
6
+ "png",
7
+ "webp",
8
+ "avif",
9
+ "gif",
10
+ "tiff",
11
+ "heif"
12
+ ];
13
+ const OUTPUT_EXTENSIONS = [
14
+ "jpg",
15
+ "png",
16
+ "webp",
17
+ "avif",
18
+ "gif",
19
+ "tiff",
20
+ "heif"
21
+ ];
22
+ function imagetoolsRules(options, sourceExt) {
23
+ return [...OUTPUT_EXTENSIONS.map((ext) => {
24
+ const rule = {
25
+ condition: { query: new RegExp(`[?&]nit_ext=${ext}(?=&|$)`) },
26
+ loaders: [{
27
+ loader: "next-imagetools/asset-loader",
28
+ options: { ...options }
29
+ }],
30
+ type: "asset"
31
+ };
32
+ if (ext !== sourceExt) rule.as = `*.${ext}`;
33
+ return rule;
34
+ }), {
35
+ condition: { all: [{ query: /^\?.+/ }, { not: { query: /[?&]nit=/ } }] },
36
+ loaders: [{
37
+ loader: "next-imagetools/loader",
38
+ options: { ...options }
39
+ }],
40
+ as: "*.js"
41
+ }];
42
+ }
43
+ const isLoaderItem = (e) => typeof e === "string" || "loader" in e;
44
+ /**
45
+ * A collection is one rule, a list of rules, or (the older shorthand) a bare list of loaders.
46
+ * Normalize to a list of rules so ours can be appended without turning into extra loaders.
47
+ */
48
+ function toRules(collection) {
49
+ if (!Array.isArray(collection)) return [collection];
50
+ if (collection.length > 0 && collection.every(isLoaderItem)) return [{ loaders: collection }];
51
+ return collection.filter((e) => !isLoaderItem(e));
52
+ }
53
+ /**
54
+ * Several values in a default (`format=avif;webp`) multiply the images of every import, which turns
55
+ * single values into arrays across the whole app and silently invalidates the `&imagetools` type
56
+ * markers. Allowed, but worth saying once when the config loads.
57
+ */
58
+ function warnOnMultiValueDefaults(defaults) {
59
+ if (defaults === void 0) return;
60
+ const multi = [...new URLSearchParams(defaults)].filter(([, v]) => v.includes(";"));
61
+ if (multi.length === 0) return;
62
+ console.warn(`[next-imagetools] defaultDirectives sets several values for ${multi.map(([k, v]) => `${k}=${v}`).join(", ")}. Every import then produces several images, so imports that would give a single value give an array instead, and \`&imagetools\` type markers no longer match.`);
63
+ }
64
+ /**
65
+ * Adds the imagetools rules to `turbopack.rules`. Rules the config already has for the same
66
+ * extension are kept and run first.
67
+ */
68
+ function withImagetools(nextConfig = {}, options = {}) {
69
+ const { extensions = DEFAULT_EXTENSIONS, ...userOptions } = options;
70
+ const loaderOptions = { ...userOptions };
71
+ warnOnMultiValueDefaults(loaderOptions.defaultDirectives);
72
+ const rules = { ...nextConfig.turbopack?.rules };
73
+ for (const ext of extensions) {
74
+ const key = `*.${ext}`;
75
+ const existing = rules[key];
76
+ const ours = toRules(imagetoolsRules(loaderOptions, ext));
77
+ rules[key] = existing === void 0 ? ours : [...toRules(existing), ...ours];
78
+ }
79
+ return {
80
+ ...nextConfig,
81
+ turbopack: {
82
+ ...nextConfig.turbopack,
83
+ rules
84
+ }
85
+ };
86
+ }
87
+ exports.withImagetools = withImagetools;
@@ -0,0 +1,46 @@
1
+ import "./config.cjs";
2
+ import { NextConfig } from "next";
3
+ /** Options shared by both loaders; must stay JSON-serializable (Turbopack loader options). */
4
+ /** A set of directives, as a query string (`'w=400&format=webp'`) or an object. */
5
+ type Directives = string | Record<string, string>;
6
+ type CacheOptions = {
7
+ /** Cache processed images on disk between builds (default: true). */
8
+ enabled?: boolean;
9
+ /** Relative to the Next.js app (default: `node_modules/.cache/next-imagetools`). */
10
+ dir?: string;
11
+ /** Remove entries that haven't been used for this many seconds (default: keep everything). */
12
+ retention?: number;
13
+ };
14
+ interface LoaderOptions {
15
+ cache?: CacheOptions;
16
+ removeMetadata?: boolean;
17
+ /** Also export the keys of object results by name (default: true). */
18
+ namedExports?: boolean;
19
+ /** Applied to every import with a query, beneath the directives the import sets itself. */
20
+ defaultDirectives?: Directives;
21
+ /** Named directive sets, applied with `preset=<name>` in an import's query. */
22
+ presets?: Record<string, Directives>;
23
+ /**
24
+ * Only handle imports whose path, relative to the Next.js app, matches one of these globs (e.g.
25
+ * `src/assets/**`). Default: every path.
26
+ */
27
+ include?: string[];
28
+ /** Never handle imports whose path, relative to the Next.js app, matches one of these globs. */
29
+ exclude?: string[];
30
+ /**
31
+ * A module (relative to the Next.js app) whose default export holds the options that take
32
+ * functions; see `ImagetoolsConfig` in `next-imagetools/config`.
33
+ */
34
+ configFile?: string;
35
+ }
36
+ export interface ImagetoolsOptions extends LoaderOptions {
37
+ /** Source extensions handled by imagetools. Imports without a query are left to Next.js. */
38
+ extensions?: string[];
39
+ }
40
+ /**
41
+ * Adds the imagetools rules to `turbopack.rules`. Rules the config already has for the same
42
+ * extension are kept and run first.
43
+ */
44
+ export declare function withImagetools(nextConfig?: NextConfig, options?: ImagetoolsOptions): NextConfig;
45
+ export {};
46
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/shared.ts","../src/index.ts"],"mappings":";;;;KAuBY,sBAAsB;KAGtB;;EAEV;;EAEA;;EAEA;;UAGe;EACf,QAAQ;EACR;;EAEA;;EAEA,oBAAoB;;EAEpB,UAAU,eAAe;;;;;EAKzB;;EAEA;;;;;EAKA;;iBCnDe,0BAA0B;;EAEzC;;;;;;wBAuEc,eACd,aAAY,YACZ,UAAS,oBACR"}
@@ -0,0 +1,48 @@
1
+ import "./config-MI8A5KvL.mjs";
2
+ import "imagetools-core";
3
+ import "sharp";
4
+ import { NextConfig } from "next";
5
+ /** Options shared by both loaders; must stay JSON-serializable (Turbopack loader options). */
6
+ /** A set of directives, as a query string (`'w=400&format=webp'`) or an object. */
7
+ type Directives = string | Record<string, string>;
8
+ type CacheOptions = {
9
+ /** Cache processed images on disk between builds (default: true). */
10
+ enabled?: boolean;
11
+ /** Relative to the Next.js app (default: `node_modules/.cache/next-imagetools`). */
12
+ dir?: string;
13
+ /** Remove entries that haven't been used for this many seconds (default: keep everything). */
14
+ retention?: number;
15
+ };
16
+ interface LoaderOptions {
17
+ cache?: CacheOptions;
18
+ removeMetadata?: boolean;
19
+ /** Also export the keys of object results by name (default: true). */
20
+ namedExports?: boolean;
21
+ /** Applied to every import with a query, beneath the directives the import sets itself. */
22
+ defaultDirectives?: Directives;
23
+ /** Named directive sets, applied with `preset=<name>` in an import's query. */
24
+ presets?: Record<string, Directives>;
25
+ /**
26
+ * Only handle imports whose path, relative to the Next.js app, matches one of these globs (e.g.
27
+ * `src/assets/**`). Default: every path.
28
+ */
29
+ include?: string[];
30
+ /** Never handle imports whose path, relative to the Next.js app, matches one of these globs. */
31
+ exclude?: string[];
32
+ /**
33
+ * A module (relative to the Next.js app) whose default export holds the options that take
34
+ * functions; see `ImagetoolsConfig` in `next-imagetools/config`.
35
+ */
36
+ configFile?: string;
37
+ }
38
+ export interface ImagetoolsOptions extends LoaderOptions {
39
+ /** Source extensions handled by imagetools. Imports without a query are left to Next.js. */
40
+ extensions?: string[];
41
+ }
42
+ /**
43
+ * Adds the imagetools rules to `turbopack.rules`. Rules the config already has for the same
44
+ * extension are kept and run first.
45
+ */
46
+ export declare function withImagetools(nextConfig?: NextConfig, options?: ImagetoolsOptions): NextConfig;
47
+ export {};
48
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/shared.ts","../src/index.ts"],"mappings":";;;;;;KAuBY,sBAAsB;KAGtB;;EAEV;;EAEA;;EAEA;;UAGe;EACf,QAAQ;EACR;;EAEA;;EAEA,oBAAoB;;EAEpB,UAAU,eAAe;;;;;EAKzB;;EAEA;;;;;EAKA;;iBCnDe,0BAA0B;;EAEzC;;;;;;wBAuEc,eACd,aAAY,YACZ,UAAS,oBACR"}
package/dist/index.mjs ADDED
@@ -0,0 +1,88 @@
1
+ // src/index.ts
2
+ const DEFAULT_EXTENSIONS = [
3
+ "jpg",
4
+ "jpeg",
5
+ "png",
6
+ "webp",
7
+ "avif",
8
+ "gif",
9
+ "tiff",
10
+ "heif"
11
+ ];
12
+ const OUTPUT_EXTENSIONS = [
13
+ "jpg",
14
+ "png",
15
+ "webp",
16
+ "avif",
17
+ "gif",
18
+ "tiff",
19
+ "heif"
20
+ ];
21
+ function imagetoolsRules(options, sourceExt) {
22
+ return [...OUTPUT_EXTENSIONS.map((ext) => {
23
+ const rule = {
24
+ condition: { query: new RegExp(`[?&]nit_ext=${ext}(?=&|$)`) },
25
+ loaders: [{
26
+ loader: "next-imagetools/asset-loader",
27
+ options: { ...options }
28
+ }],
29
+ type: "asset"
30
+ };
31
+ if (ext !== sourceExt) rule.as = `*.${ext}`;
32
+ return rule;
33
+ }), {
34
+ condition: { all: [{ query: /^\?.+/ }, { not: { query: /[?&]nit=/ } }] },
35
+ loaders: [{
36
+ loader: "next-imagetools/loader",
37
+ options: { ...options }
38
+ }],
39
+ as: "*.js"
40
+ }];
41
+ }
42
+ const isLoaderItem = (e) => typeof e === "string" || "loader" in e;
43
+ /**
44
+ * A collection is one rule, a list of rules, or (the older shorthand) a bare list of loaders.
45
+ * Normalize to a list of rules so ours can be appended without turning into extra loaders.
46
+ */
47
+ function toRules(collection) {
48
+ if (!Array.isArray(collection)) return [collection];
49
+ if (collection.length > 0 && collection.every(isLoaderItem)) return [{ loaders: collection }];
50
+ return collection.filter((e) => !isLoaderItem(e));
51
+ }
52
+ /**
53
+ * Several values in a default (`format=avif;webp`) multiply the images of every import, which turns
54
+ * single values into arrays across the whole app and silently invalidates the `&imagetools` type
55
+ * markers. Allowed, but worth saying once when the config loads.
56
+ */
57
+ function warnOnMultiValueDefaults(defaults) {
58
+ if (defaults === void 0) return;
59
+ const multi = [...new URLSearchParams(defaults)].filter(([, v]) => v.includes(";"));
60
+ if (multi.length === 0) return;
61
+ console.warn(`[next-imagetools] defaultDirectives sets several values for ${multi.map(([k, v]) => `${k}=${v}`).join(", ")}. Every import then produces several images, so imports that would give a single value give an array instead, and \`&imagetools\` type markers no longer match.`);
62
+ }
63
+ /**
64
+ * Adds the imagetools rules to `turbopack.rules`. Rules the config already has for the same
65
+ * extension are kept and run first.
66
+ */
67
+ function withImagetools(nextConfig = {}, options = {}) {
68
+ const { extensions = DEFAULT_EXTENSIONS, ...userOptions } = options;
69
+ const loaderOptions = { ...userOptions };
70
+ warnOnMultiValueDefaults(loaderOptions.defaultDirectives);
71
+ const rules = { ...nextConfig.turbopack?.rules };
72
+ for (const ext of extensions) {
73
+ const key = `*.${ext}`;
74
+ const existing = rules[key];
75
+ const ours = toRules(imagetoolsRules(loaderOptions, ext));
76
+ rules[key] = existing === void 0 ? ours : [...toRules(existing), ...ours];
77
+ }
78
+ return {
79
+ ...nextConfig,
80
+ turbopack: {
81
+ ...nextConfig.turbopack,
82
+ rules
83
+ }
84
+ };
85
+ }
86
+ export { withImagetools };
87
+
88
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { NextConfig } from 'next';\n\nimport type { LoaderOptions } from './shared';\n\nexport interface ImagetoolsOptions extends LoaderOptions {\n /** Source extensions handled by imagetools. Imports without a query are left to Next.js. */\n extensions?: string[];\n}\n\ntype TurbopackRules = NonNullable<NonNullable<NextConfig['turbopack']>['rules']>;\ntype RuleCollection = TurbopackRules[string];\n\nconst DEFAULT_EXTENSIONS = ['jpg', 'jpeg', 'png', 'webp', 'avif', 'gif', 'tiff', 'heif'];\nconst OUTPUT_EXTENSIONS = ['jpg', 'png', 'webp', 'avif', 'gif', 'tiff', 'heif'];\n\nfunction imagetoolsRules(options: LoaderOptions, sourceExt: string): RuleCollection {\n return [\n // internal per-image import emitted by the module loader → encoded bytes as an asset.\n // When the output format differs from the source's, the module is renamed so the emitted\n // file carries the right extension. Turbopack's `as` replaces `*` with the whole file name,\n // so that gives `hero.jpg.webp`; a same-format output skips the rename and stays `hero.jpg`.\n ...OUTPUT_EXTENSIONS.map(ext => {\n const rule: RuleItem = {\n condition: { query: new RegExp(`[?&]nit_ext=${ext}(?=&|$)`) },\n loaders: [{ loader: 'next-imagetools/asset-loader', options: { ...options } }],\n type: 'asset',\n };\n if (ext !== sourceExt) rule.as = `*.${ext}`;\n return rule;\n }),\n // any other import with a query goes through imagetools\n {\n condition: { all: [{ query: /^\\?.+/ }, { not: { query: /[?&]nit=/ } }] },\n loaders: [{ loader: 'next-imagetools/loader', options: { ...options } }],\n as: '*.js',\n },\n ];\n}\n\ntype RuleEntry = Extract<RuleCollection, unknown[]>[number];\ntype RuleItem = Exclude<RuleEntry, string | { loader: string }>;\n\nconst isLoaderItem = (e: RuleEntry): boolean => typeof e === 'string' || 'loader' in e;\n\n/**\n * A collection is one rule, a list of rules, or (the older shorthand) a bare list of loaders.\n * Normalize to a list of rules so ours can be appended without turning into extra loaders.\n */\nfunction toRules(collection: RuleCollection): RuleItem[] {\n if (!Array.isArray(collection)) return [collection];\n if (collection.length > 0 && collection.every(isLoaderItem)) {\n return [{ loaders: collection as Extract<RuleEntry, string | { loader: string }>[] }];\n }\n return collection.filter((e): e is RuleItem => !isLoaderItem(e));\n}\n\n/**\n * Several values in a default (`format=avif;webp`) multiply the images of every import, which turns\n * single values into arrays across the whole app and silently invalidates the `&imagetools` type\n * markers. Allowed, but worth saying once when the config loads.\n */\nfunction warnOnMultiValueDefaults(defaults: ImagetoolsOptions['defaultDirectives']) {\n if (defaults === undefined) return;\n const multi = [...new URLSearchParams(defaults)].filter(([, v]) => v.includes(';'));\n if (multi.length === 0) return;\n console.warn(\n `[next-imagetools] defaultDirectives sets several values for ${multi\n .map(([k, v]) => `${k}=${v}`)\n .join(', ')}. Every import then produces several images, so imports that would give a ` +\n `single value give an array instead, and \\`&imagetools\\` type markers no longer match.`,\n );\n}\n\n/**\n * Adds the imagetools rules to `turbopack.rules`. Rules the config already has for the same\n * extension are kept and run first.\n */\nexport function withImagetools(\n nextConfig: NextConfig = {},\n options: ImagetoolsOptions = {},\n): NextConfig {\n const { extensions = DEFAULT_EXTENSIONS, ...userOptions } = options;\n const loaderOptions: LoaderOptions = { ...userOptions };\n warnOnMultiValueDefaults(loaderOptions.defaultDirectives);\n const rules: TurbopackRules = { ...nextConfig.turbopack?.rules };\n for (const ext of extensions) {\n const key = `*.${ext}`;\n const existing = rules[key];\n const ours = toRules(imagetoolsRules(loaderOptions, ext));\n rules[key] = existing === undefined ? ours : [...toRules(existing), ...ours];\n }\n return { ...nextConfig, turbopack: { ...nextConfig.turbopack, rules } };\n}\n"],"mappings":";AAYA,MAAM,qBAAqB;CAAC;CAAO;CAAQ;CAAO;CAAQ;CAAQ;CAAO;CAAQ;AAAM;AACvF,MAAM,oBAAoB;CAAC;CAAO;CAAO;CAAQ;CAAQ;CAAO;CAAQ;AAAM;AAE9E,SAAS,gBAAgB,SAAwB,WAAmC;CAClF,OAAO,CAKL,GAAG,kBAAkB,KAAI,QAAO;EAC9B,MAAM,OAAiB;GACrB,WAAW,EAAE,OAAO,IAAI,OAAO,eAAe,IAAI,QAAQ,EAAE;GAC5D,SAAS,CAAC;IAAE,QAAQ;IAAgC,SAAS,EAAE,GAAG,QAAQ;GAAE,CAAC;GAC7E,MAAM;EACR;EACA,IAAI,QAAQ,WAAW,KAAK,KAAK,KAAK;EACtC,OAAO;CACT,CAAC,GAED;EACE,WAAW,EAAE,KAAK,CAAC,EAAE,OAAO,QAAQ,GAAG,EAAE,KAAK,EAAE,OAAO,WAAW,EAAE,CAAC,EAAE;EACvE,SAAS,CAAC;GAAE,QAAQ;GAA0B,SAAS,EAAE,GAAG,QAAQ;EAAE,CAAC;EACvE,IAAI;CACN,CACF;AACF;AAKA,MAAM,gBAAgB,MAA0B,OAAO,MAAM,YAAY,YAAY;;;;;AAMrF,SAAS,QAAQ,YAAwC;CACvD,IAAI,CAAC,MAAM,QAAQ,UAAU,GAAG,OAAO,CAAC,UAAU;CAClD,IAAI,WAAW,SAAS,KAAK,WAAW,MAAM,YAAY,GACxD,OAAO,CAAC,EAAE,SAAS,WAAgE,CAAC;CAEtF,OAAO,WAAW,QAAQ,MAAqB,CAAC,aAAa,CAAC,CAAC;AACjE;;;;;;AAOA,SAAS,yBAAyB,UAAkD;CAClF,IAAI,aAAa,KAAA,GAAW;CAC5B,MAAM,QAAQ,CAAC,GAAG,IAAI,gBAAgB,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,OAAO,EAAE,SAAS,GAAG,CAAC;CAClF,IAAI,MAAM,WAAW,GAAG;CACxB,QAAQ,KACN,+DAA+D,MAC5D,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,CAC5B,KAAK,IAAI,EAAE,gKAEhB;AACF;;;;;AAMA,SAAgB,eACd,aAAyB,CAAC,GAC1B,UAA6B,CAAC,GAClB;CACZ,MAAM,EAAE,aAAa,oBAAoB,GAAG,gBAAgB;CAC5D,MAAM,gBAA+B,EAAE,GAAG,YAAY;CACtD,yBAAyB,cAAc,iBAAiB;CACxD,MAAM,QAAwB,EAAE,GAAG,WAAW,WAAW,MAAM;CAC/D,KAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,MAAM,KAAK;EACjB,MAAM,WAAW,MAAM;EACvB,MAAM,OAAO,QAAQ,gBAAgB,eAAe,GAAG,CAAC;EACxD,MAAM,OAAO,aAAa,KAAA,IAAY,OAAO,CAAC,GAAG,QAAQ,QAAQ,GAAG,GAAG,IAAI;CAC7E;CACA,OAAO;EAAE,GAAG;EAAY,WAAW;GAAE,GAAG,WAAW;GAAW;EAAM;CAAE;AACxE"}