next-image-transformer 1.0.0 → 1.0.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { c as r } from "./createImageUrlCodec-Cpmqn0AP.js";
2
- const a = (...e) => r(...e).encode;
3
- export {
4
- a as createImageUrlBuilder
5
- };
1
+ import { t as e } from "./createImageUrlCodec-CIiY-UWp.js";
2
+ //#region src/createImageUrlBuilder.ts
3
+ var t = (...t) => e(...t).encode;
4
+ //#endregion
5
+ export { t as createImageUrlBuilder };
package/dist/server.js CHANGED
@@ -1,198 +1,136 @@
1
- import h from "node:path";
2
- import { z as T, c as B } from "./createImageUrlCodec-Cpmqn0AP.js";
3
- import { createHash as U } from "node:crypto";
4
- import m from "node:fs/promises";
5
- import b from "sharp";
6
- function j({
7
- canonicalUrl: r
8
- }) {
9
- return U("sha256").update(r).digest("hex");
1
+ import { n as e, t } from "./createImageUrlCodec-CIiY-UWp.js";
2
+ import n from "node:path";
3
+ import { createHash as r } from "node:crypto";
4
+ import i from "node:fs/promises";
5
+ import a from "sharp";
6
+ //#region src/getTransformCacheKey.ts
7
+ function o({ canonicalUrl: e }) {
8
+ return r("sha256").update(e).digest("hex");
10
9
  }
11
- function P({
12
- cacheKey: r,
13
- cacheDir: n
14
- }) {
15
- const s = r.slice(0, 2), a = r.slice(2), t = h.join(n, s);
16
- return {
17
- dir: t,
18
- bodyPath: h.join(t, `${a}.bin`),
19
- metaPath: h.join(t, `${a}.json`)
20
- };
10
+ //#endregion
11
+ //#region src/getTransformCachePaths.ts
12
+ function s({ cacheKey: e, cacheDir: t }) {
13
+ let r = e.slice(0, 2), i = e.slice(2), a = n.join(t, r);
14
+ return {
15
+ dir: a,
16
+ bodyPath: n.join(a, `${i}.bin`),
17
+ metaPath: n.join(a, `${i}.json`)
18
+ };
21
19
  }
22
- async function q({
23
- cacheKey: r,
24
- cacheDir: n
25
- }) {
26
- const { bodyPath: s, metaPath: a } = P({ cacheKey: r, cacheDir: n });
27
- try {
28
- const [t, u] = await Promise.all([
29
- m.readFile(s),
30
- m.readFile(a, "utf8")
31
- ]), o = (() => {
32
- try {
33
- const i = JSON.parse(u), e = T.object({
34
- contentType: T.string()
35
- }).loose().safeParse(i);
36
- return e.success ? e.data : null;
37
- } catch {
38
- return null;
39
- }
40
- })();
41
- return o ? { body: new Uint8Array(t), contentType: o.contentType } : null;
42
- } catch (t) {
43
- if (t instanceof Error && "code" in t && t.code === "ENOENT")
44
- return null;
45
- throw t;
46
- }
20
+ //#endregion
21
+ //#region src/readTransformCache.ts
22
+ async function c({ cacheKey: t, cacheDir: n }) {
23
+ let { bodyPath: r, metaPath: a } = s({
24
+ cacheKey: t,
25
+ cacheDir: n
26
+ });
27
+ try {
28
+ let [t, n] = await Promise.all([i.readFile(r), i.readFile(a, "utf8")]), o = (() => {
29
+ try {
30
+ let t = JSON.parse(n), r = e.object({ contentType: e.string() }).loose().safeParse(t);
31
+ return r.success ? r.data : null;
32
+ } catch {
33
+ return null;
34
+ }
35
+ })();
36
+ return o ? {
37
+ body: new Uint8Array(t),
38
+ contentType: o.contentType
39
+ } : null;
40
+ } catch (e) {
41
+ if (e instanceof Error && "code" in e && e.code === "ENOENT") return null;
42
+ throw e;
43
+ }
47
44
  }
48
- function x(r, n, s, a, t, u, o, i, e) {
49
- switch (arguments.length) {
50
- case 1:
51
- return r;
52
- case 2:
53
- return n(r);
54
- case 3:
55
- return s(n(r));
56
- case 4:
57
- return a(s(n(r)));
58
- case 5:
59
- return t(a(s(n(r))));
60
- case 6:
61
- return u(t(a(s(n(r)))));
62
- case 7:
63
- return o(u(t(a(s(n(r))))));
64
- case 8:
65
- return i(o(u(t(a(s(n(r)))))));
66
- case 9:
67
- return e(i(o(u(t(a(s(n(r))))))));
68
- default: {
69
- for (var c = arguments[0], f = 1; f < arguments.length; f++)
70
- c = arguments[f](c);
71
- return c;
72
- }
73
- }
45
+ function l(e, t, n, r, i, a, o, s, c) {
46
+ switch (arguments.length) {
47
+ case 1: return e;
48
+ case 2: return t(e);
49
+ case 3: return n(t(e));
50
+ case 4: return r(n(t(e)));
51
+ case 5: return i(r(n(t(e))));
52
+ case 6: return a(i(r(n(t(e)))));
53
+ case 7: return o(a(i(r(n(t(e))))));
54
+ case 8: return s(o(a(i(r(n(t(e)))))));
55
+ case 9: return c(s(o(a(i(r(n(t(e))))))));
56
+ default:
57
+ for (var l = arguments[0], u = 1; u < arguments.length; u++) l = arguments[u](l);
58
+ return l;
59
+ }
74
60
  }
75
- async function A({
76
- cacheKey: r,
77
- body: n,
78
- meta: s,
79
- cacheDir: a
80
- }) {
81
- const { dir: t, bodyPath: u, metaPath: o } = P({
82
- cacheKey: r,
83
- cacheDir: a
84
- });
85
- await m.mkdir(t, { recursive: !0 });
86
- const i = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`, e = `${u}.${i}.tmp`, c = `${o}.${i}.tmp`;
87
- await Promise.all([
88
- m.writeFile(e, n),
89
- m.writeFile(c, JSON.stringify(s), "utf8")
90
- ]), await Promise.all([
91
- m.rename(e, u),
92
- m.rename(c, o)
93
- ]);
61
+ //#endregion
62
+ //#region src/writeTransformCache.ts
63
+ async function u({ cacheKey: e, body: t, meta: n, cacheDir: r }) {
64
+ let { dir: a, bodyPath: o, metaPath: c } = s({
65
+ cacheKey: e,
66
+ cacheDir: r
67
+ });
68
+ await i.mkdir(a, { recursive: !0 });
69
+ let l = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`, u = `${o}.${l}.tmp`, d = `${c}.${l}.tmp`;
70
+ await Promise.all([i.writeFile(u, t), i.writeFile(d, JSON.stringify(n), "utf8")]), await Promise.all([i.rename(u, o), i.rename(d, c)]);
94
71
  }
95
- const O = ({
96
- apiRouteUrl: r,
97
- cacheDir: n = h.join(process.cwd(), ".transform-cache"),
98
- cacheControl: s = "public, max-age=31536000, immutable",
99
- allowedHosts: a
100
- }) => {
101
- const t = B({ apiRouteUrl: r }), u = (o) => {
102
- if (!a) return !0;
103
- const i = o.hostname.toLowerCase(), e = o.host.toLowerCase();
104
- return a.some((c) => {
105
- if (c instanceof RegExp)
106
- return c.test(i) || c.test(e);
107
- const f = c.toLowerCase();
108
- return f.includes(":") ? e === f : i === f;
109
- });
110
- };
111
- return async function(i) {
112
- const { data: e, error: c } = t.safeDecode(i.url);
113
- if (c)
114
- return new Response("Bad Request", { status: 400 });
115
- const f = t.encode(
116
- // encode() accepts the decoded transform config shape; we only call this
117
- // after decoding has succeeded.
118
- e
119
- ), y = e.q ?? 100, g = j({ canonicalUrl: f }), d = await q({ cacheKey: g, cacheDir: n });
120
- if (d)
121
- return new Response(d.body, {
122
- headers: {
123
- "Content-Type": d.contentType,
124
- "Cache-Control": s
125
- }
126
- });
127
- let l;
128
- try {
129
- l = new URL(e.source);
130
- } catch {
131
- return new Response("Bad Request", { status: 400 });
132
- }
133
- if (l.protocol !== "http:" && l.protocol !== "https:")
134
- return new Response("Bad Request", { status: 400 });
135
- if (l.username || l.password)
136
- return new Response("Bad Request", { status: 400 });
137
- if (!u(l))
138
- return new Response("Forbidden", { status: 403 });
139
- const w = await fetch(l);
140
- if (!w.ok)
141
- return new Response("Upstream fetch failed", { status: 502 });
142
- const v = b(Buffer.from(await w.arrayBuffer())), R = await x(
143
- v,
144
- /**
145
- * auto-orient: read's the image's EXIF data and rotates it to the correct
146
- * orientation.
147
- */
148
- (p) => p.rotate(),
149
- /**
150
- * Resize
151
- */
152
- (p) => e.w || e.h ? p.resize({
153
- width: e.w,
154
- height: e.h,
155
- fit: e.fit ?? "inside",
156
- withoutEnlargement: !0
157
- }) : p,
158
- /**
159
- * Change format
160
- */
161
- (p) => {
162
- switch (e.fmt) {
163
- case "preserve":
164
- return p;
165
- case "avif":
166
- return p.avif({ quality: y });
167
- case "webp":
168
- return p.webp({ quality: y });
169
- default:
170
- throw new Error(`Unreachable case: ${e.fmt}`);
171
- }
172
- }
173
- ).toBuffer(), $ = new Uint8Array(R), C = (() => {
174
- switch (e.fmt) {
175
- case "avif":
176
- return "image/avif";
177
- case "webp":
178
- return "image/webp";
179
- default:
180
- return w.headers.get("content-type") ?? "application/octet-stream";
181
- }
182
- })();
183
- return await A({
184
- cacheKey: g,
185
- body: R,
186
- meta: { contentType: C },
187
- cacheDir: n
188
- }), new Response($, {
189
- headers: {
190
- "Content-Type": C,
191
- "Cache-Control": s
192
- }
193
- });
194
- };
195
- };
196
- export {
197
- O as createImageTransformRouteHandler
72
+ //#endregion
73
+ //#region src/createImageTransformRouteHandler.ts
74
+ var d = ({ apiRouteUrl: e, cacheDir: r = n.join(process.cwd(), ".transform-cache"), cacheControl: i = "public, max-age=31536000, immutable", allowedHosts: s }) => {
75
+ let d = t({ apiRouteUrl: e }), f = (e) => {
76
+ if (!s) return !0;
77
+ let t = e.hostname.toLowerCase(), n = e.host.toLowerCase();
78
+ return s.some((e) => {
79
+ if (e instanceof RegExp) return e.test(t) || e.test(n);
80
+ let r = e.toLowerCase();
81
+ return r.includes(":") ? n === r : t === r;
82
+ });
83
+ };
84
+ return async function(e) {
85
+ let { data: t, error: n } = d.safeDecode(e.url);
86
+ if (n) return new Response("Bad Request", { status: 400 });
87
+ let s = d.encode(t), p = t.q ?? 100, m = o({ canonicalUrl: s }), h = await c({
88
+ cacheKey: m,
89
+ cacheDir: r
90
+ });
91
+ if (h) return new Response(h.body, { headers: {
92
+ "Content-Type": h.contentType,
93
+ "Cache-Control": i
94
+ } });
95
+ let g;
96
+ try {
97
+ g = new URL(t.source);
98
+ } catch {
99
+ return new Response("Bad Request", { status: 400 });
100
+ }
101
+ if (g.protocol !== "http:" && g.protocol !== "https:" || g.username || g.password) return new Response("Bad Request", { status: 400 });
102
+ if (!f(g)) return new Response("Forbidden", { status: 403 });
103
+ let _ = await fetch(g);
104
+ if (!_.ok) return new Response("Upstream fetch failed", { status: 502 });
105
+ let v = await l(a(Buffer.from(await _.arrayBuffer())), (e) => e.rotate(), (e) => t.w || t.h ? e.resize({
106
+ width: t.w,
107
+ height: t.h,
108
+ fit: t.fit ?? "inside",
109
+ withoutEnlargement: !0
110
+ }) : e, (e) => {
111
+ switch (t.fmt) {
112
+ case "preserve": return e;
113
+ case "avif": return e.avif({ quality: p });
114
+ case "webp": return e.webp({ quality: p });
115
+ default: throw Error(`Unreachable case: ${t.fmt}`);
116
+ }
117
+ }).toBuffer(), y = new Uint8Array(v), b = (() => {
118
+ switch (t.fmt) {
119
+ case "avif": return "image/avif";
120
+ case "webp": return "image/webp";
121
+ default: return _.headers.get("content-type") ?? "application/octet-stream";
122
+ }
123
+ })();
124
+ return await u({
125
+ cacheKey: m,
126
+ body: v,
127
+ meta: { contentType: b },
128
+ cacheDir: r
129
+ }), new Response(y, { headers: {
130
+ "Content-Type": b,
131
+ "Cache-Control": i
132
+ } });
133
+ };
198
134
  };
135
+ //#endregion
136
+ export { d as createImageTransformRouteHandler };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-image-transformer",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -24,18 +24,18 @@
24
24
  "README.md",
25
25
  "LICENSE*"
26
26
  ],
27
- "packageManager": "yarn@4.12.0",
27
+ "packageManager": "yarn@4.17.0",
28
28
  "devDependencies": {
29
- "@types/node": "24",
30
- "prettier": "^3.7.4",
31
- "release-it": "^19.2.3",
32
- "sharp": "^0.34.5",
33
- "typescript": "^5.9.3",
34
- "vite": "^7.3.0"
29
+ "@types/node": "24.13.2",
30
+ "prettier": "^3.8.4",
31
+ "release-it": "^20.2.0",
32
+ "sharp": "^0.35.1",
33
+ "typescript": "^6.0.3",
34
+ "vite": "^8.0.16"
35
35
  },
36
36
  "dependencies": {
37
37
  "fp-ts": "^2.16.11",
38
- "zod": "^4.3.5"
38
+ "zod": "^4.4.3"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "next": ">=13.4 <17",