defuss-astro 1.4.8 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.cjs CHANGED
@@ -1,121 +1,9 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var client$1 = require('defuss/client');
6
4
  var render = require('./render-DkMOLcUd.cjs');
7
- var jsxRuntime = require('defuss/jsx-runtime');
8
5
  require('defuss');
9
6
 
10
- const Img = ({
11
- id,
12
- src,
13
- alt,
14
- height = 100,
15
- width = 100,
16
- previewQuality = 5,
17
- quality = 90,
18
- className = "",
19
- class: _class = "",
20
- style = {},
21
- format = "webp",
22
- astroAssetsPath = "_defuss/image"
23
- }) => {
24
- const placeholderWidth = Math.round(width / 7);
25
- const placeholderHeight = Math.round(height / 7);
26
- const imgRef = client$1.createRef();
27
- const getTransformOptionsPath = ({
28
- src: src2,
29
- height: height2,
30
- width: width2,
31
- quality: quality2 = previewQuality,
32
- format: format2 = "webp"
33
- }) => {
34
- const transformOptions = new URLSearchParams({
35
- href: src2,
36
- h: height2.toString(),
37
- w: width2.toString(),
38
- q: quality2.toString(),
39
- f: format2
40
- });
41
- return `/${astroAssetsPath}?${transformOptions.toString()}`;
42
- };
43
- const transformedSrc = getTransformOptionsPath({
44
- src,
45
- height: placeholderHeight,
46
- width: placeholderWidth,
47
- format
48
- });
49
- const whenImageMounts = () => {
50
- const img = imgRef.current;
51
- if (!img) return;
52
- let loaded = false;
53
- const getTransformOptionsPath2 = ({
54
- src: src2,
55
- height: height2,
56
- width: width2,
57
- quality: quality2,
58
- format: format2
59
- }) => {
60
- const transformOptions = new URLSearchParams({
61
- href: src2,
62
- h: height2.toString(),
63
- w: width2.toString(),
64
- q: quality2.toString(),
65
- f: format2
66
- });
67
- return `/${astroAssetsPath}?${transformOptions.toString()}`;
68
- };
69
- const lazyLoad = () => {
70
- if (loaded) return;
71
- const transformedSrc2 = getTransformOptionsPath2({
72
- src,
73
- height,
74
- width,
75
- quality,
76
- format
77
- });
78
- img.src = transformedSrc2;
79
- img.onload = () => {
80
- img.classList.remove("blur");
81
- img.classList.add("loaded");
82
- img.style.filter = "blur(0px)";
83
- loaded = true;
84
- };
85
- };
86
- const observer = new window.IntersectionObserver(
87
- (entries, observer2) => {
88
- entries.forEach((entry) => {
89
- if (entry.isIntersecting) {
90
- lazyLoad();
91
- observer2.unobserve(entry.target);
92
- }
93
- });
94
- },
95
- { threshold: 0.1 }
96
- );
97
- observer.observe(imgRef.current);
98
- };
99
- return /* @__PURE__ */ jsxRuntime.jsx(
100
- "img",
101
- {
102
- id,
103
- ref: imgRef,
104
- onMount: whenImageMounts,
105
- alt,
106
- class: `${className || _class} blur`,
107
- src: transformedSrc,
108
- style: {
109
- filter: "blur(40px)",
110
- transition: "0.125s filter linear",
111
- ...style
112
- },
113
- width,
114
- height
115
- }
116
- );
117
- };
118
-
119
7
  var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
120
8
  const isHydrate = element.hasAttribute("ssr") && (client === "visible" || client === "idle" || client === "load" || client === "media");
121
9
  if (!element.hasAttribute("ssr")) return;
@@ -190,5 +78,4 @@ var client = (element) => async (Component, props, { default: children, ...slott
190
78
  );
191
79
  };
192
80
 
193
- exports.Img = Img;
194
- exports.default = client;
81
+ module.exports = client;
package/dist/client.d.cts CHANGED
@@ -1,29 +1,3 @@
1
- import { Props, CSSProperties } from 'defuss/client';
2
-
3
- interface ImgProps extends Props {
4
- id?: string;
5
- src: string;
6
- width?: number;
7
- height?: number;
8
- alt: string;
9
- style?: CSSProperties;
10
- class?: string;
11
- className?: string;
12
- format?: string;
13
- astroAssetsPath?: string;
14
- previewQuality?: number;
15
- quality?: number;
16
- }
17
- /**
18
- * Image component for displaying responsive images with automatic format conversion.
19
- *
20
- * Default style: {
21
- * filter: "blur(40px)",
22
- * transition: "0.125s filter linear",
23
- * }
24
- */
25
- declare const Img: ({ id, src, alt, height, width, previewQuality, quality, className, class: _class, style, format, astroAssetsPath, }: ImgProps) => any;
26
-
27
1
  declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
28
2
 
29
- export { Img, type ImgProps, _default as default };
3
+ export { _default as default };
package/dist/client.d.mts CHANGED
@@ -1,29 +1,3 @@
1
- import { Props, CSSProperties } from 'defuss/client';
2
-
3
- interface ImgProps extends Props {
4
- id?: string;
5
- src: string;
6
- width?: number;
7
- height?: number;
8
- alt: string;
9
- style?: CSSProperties;
10
- class?: string;
11
- className?: string;
12
- format?: string;
13
- astroAssetsPath?: string;
14
- previewQuality?: number;
15
- quality?: number;
16
- }
17
- /**
18
- * Image component for displaying responsive images with automatic format conversion.
19
- *
20
- * Default style: {
21
- * filter: "blur(40px)",
22
- * transition: "0.125s filter linear",
23
- * }
24
- */
25
- declare const Img: ({ id, src, alt, height, width, previewQuality, quality, className, class: _class, style, format, astroAssetsPath, }: ImgProps) => any;
26
-
27
1
  declare const _default: (element: HTMLElement) => (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>, { client }: Record<string, string>) => Promise<void>;
28
2
 
29
- export { Img, type ImgProps, _default as default };
3
+ export { _default as default };
package/dist/client.mjs CHANGED
@@ -1,117 +1,7 @@
1
- import { createRef, hydrate, renderSync, DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE, REF_ATTRIBUTE_NAME } from 'defuss/client';
1
+ import { hydrate, renderSync, DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE, REF_ATTRIBUTE_NAME } from 'defuss/client';
2
2
  import { S as StaticHtml } from './render-viAgneG-.mjs';
3
- import { jsx } from 'defuss/jsx-runtime';
4
3
  import 'defuss';
5
4
 
6
- const Img = ({
7
- id,
8
- src,
9
- alt,
10
- height = 100,
11
- width = 100,
12
- previewQuality = 5,
13
- quality = 90,
14
- className = "",
15
- class: _class = "",
16
- style = {},
17
- format = "webp",
18
- astroAssetsPath = "_defuss/image"
19
- }) => {
20
- const placeholderWidth = Math.round(width / 7);
21
- const placeholderHeight = Math.round(height / 7);
22
- const imgRef = createRef();
23
- const getTransformOptionsPath = ({
24
- src: src2,
25
- height: height2,
26
- width: width2,
27
- quality: quality2 = previewQuality,
28
- format: format2 = "webp"
29
- }) => {
30
- const transformOptions = new URLSearchParams({
31
- href: src2,
32
- h: height2.toString(),
33
- w: width2.toString(),
34
- q: quality2.toString(),
35
- f: format2
36
- });
37
- return `/${astroAssetsPath}?${transformOptions.toString()}`;
38
- };
39
- const transformedSrc = getTransformOptionsPath({
40
- src,
41
- height: placeholderHeight,
42
- width: placeholderWidth,
43
- format
44
- });
45
- const whenImageMounts = () => {
46
- const img = imgRef.current;
47
- if (!img) return;
48
- let loaded = false;
49
- const getTransformOptionsPath2 = ({
50
- src: src2,
51
- height: height2,
52
- width: width2,
53
- quality: quality2,
54
- format: format2
55
- }) => {
56
- const transformOptions = new URLSearchParams({
57
- href: src2,
58
- h: height2.toString(),
59
- w: width2.toString(),
60
- q: quality2.toString(),
61
- f: format2
62
- });
63
- return `/${astroAssetsPath}?${transformOptions.toString()}`;
64
- };
65
- const lazyLoad = () => {
66
- if (loaded) return;
67
- const transformedSrc2 = getTransformOptionsPath2({
68
- src,
69
- height,
70
- width,
71
- quality,
72
- format
73
- });
74
- img.src = transformedSrc2;
75
- img.onload = () => {
76
- img.classList.remove("blur");
77
- img.classList.add("loaded");
78
- img.style.filter = "blur(0px)";
79
- loaded = true;
80
- };
81
- };
82
- const observer = new window.IntersectionObserver(
83
- (entries, observer2) => {
84
- entries.forEach((entry) => {
85
- if (entry.isIntersecting) {
86
- lazyLoad();
87
- observer2.unobserve(entry.target);
88
- }
89
- });
90
- },
91
- { threshold: 0.1 }
92
- );
93
- observer.observe(imgRef.current);
94
- };
95
- return /* @__PURE__ */ jsx(
96
- "img",
97
- {
98
- id,
99
- ref: imgRef,
100
- onMount: whenImageMounts,
101
- alt,
102
- class: `${className || _class} blur`,
103
- src: transformedSrc,
104
- style: {
105
- filter: "blur(40px)",
106
- transition: "0.125s filter linear",
107
- ...style
108
- },
109
- width,
110
- height
111
- }
112
- );
113
- };
114
-
115
5
  var client = (element) => async (Component, props, { default: children, ...slotted }, { client }) => {
116
6
  const isHydrate = element.hasAttribute("ssr") && (client === "visible" || client === "idle" || client === "load" || client === "media");
117
7
  if (!element.hasAttribute("ssr")) return;
@@ -186,4 +76,4 @@ var client = (element) => async (Component, props, { default: children, ...slott
186
76
  );
187
77
  };
188
78
 
189
- export { Img, client as default };
79
+ export { client as default };
package/dist/index.cjs CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var defussPlugin = require('defuss-vite');
5
+ var vite = require('vite');
6
+ var core = require('@swc/core');
6
7
  var node_url = require('node:url');
7
8
  var glob = require('fast-glob');
8
9
  var node_perf_hooks = require('node:perf_hooks');
@@ -12,6 +13,90 @@ var promises = require('node:fs/promises');
12
13
  var purgecss = require('purgecss');
13
14
  var node_fs = require('node:fs');
14
15
 
16
+ function parseId(url) {
17
+ return { id: url.split("?", 2)[0] };
18
+ }
19
+ function defussVitePlugin({
20
+ include,
21
+ exclude
22
+ } = {}) {
23
+ let config;
24
+ const shouldTransform = vite.createFilter(
25
+ include || [/\.[cm]?[tj]sx?$/],
26
+ exclude || [/node_modules/]
27
+ );
28
+ const jsxPlugin = {
29
+ name: "vite:defuss-jsx",
30
+ enforce: "pre",
31
+ config() {
32
+ return {
33
+ esbuild: {
34
+ // we want Vite to handle JSX transformations
35
+ jsxImportSource: "defuss",
36
+ jsxFactory: "jsx",
37
+ jsxFragment: "Fragment"
38
+ },
39
+ optimizeDeps: {
40
+ // we want Vite to optimize the runtime code
41
+ include: ["defuss"],
42
+ // we don't want Vite to optimize this plugin code
43
+ exclude: ["defuss-vite"]
44
+ },
45
+ ssr: {
46
+ // LinkeDOM (used by defuss/render) imports perf_hooks
47
+ // which is actually just an empty placeholder package,
48
+ // therefore, we externalize it
49
+ external: ["perf_hooks"]
50
+ }
51
+ };
52
+ },
53
+ configResolved(resolvedConfig) {
54
+ config = resolvedConfig;
55
+ },
56
+ async transform(code, url) {
57
+ const { id } = parseId(url);
58
+ if (!shouldTransform(id)) {
59
+ return null;
60
+ }
61
+ const prevSourceMap = this.getCombinedSourcemap?.();
62
+ const inputSourceMap = prevSourceMap ? JSON.stringify({ code, map: prevSourceMap }) : void 0;
63
+ const result = await core.transform(code, {
64
+ jsc: {
65
+ parser: {
66
+ syntax: "typescript",
67
+ tsx: true,
68
+ dynamicImport: true,
69
+ decorators: true
70
+ },
71
+ transform: {
72
+ react: {
73
+ development: true,
74
+ useBuiltins: false,
75
+ throwIfNamespace: false,
76
+ pragma: "jsx",
77
+ pragmaFrag: "Fragment",
78
+ runtime: "automatic",
79
+ importSource: "defuss"
80
+ }
81
+ },
82
+ target: "es2024"
83
+ },
84
+ sourceMaps: true,
85
+ sourceFileName: id,
86
+ filename: id,
87
+ sourceRoot: config.root,
88
+ inputSourceMap
89
+ });
90
+ if (!result) return null;
91
+ return {
92
+ code: result.code || code,
93
+ map: result.map
94
+ };
95
+ }
96
+ };
97
+ return jsxPlugin;
98
+ }
99
+
15
100
  const logMessage = (message) => {
16
101
  const date = (/* @__PURE__ */ new Date()).toLocaleTimeString();
17
102
  console.log(`${date} \x1B[32mdefuss-astro:\x1B[0m ${message}`);
@@ -76,16 +161,8 @@ function index({
76
161
  config,
77
162
  addRenderer,
78
163
  updateConfig,
79
- command,
80
- injectScript,
81
- injectRoute
164
+ command
82
165
  }) => {
83
- injectRoute({
84
- pattern: "/_defuss/image",
85
- prerender: false,
86
- entrypoint: "defuss-astro/image-endpoint.js"
87
- });
88
- node_url.fileURLToPath(config.publicDir);
89
166
  config.compressHTML = true;
90
167
  config.scopedStyleStrategy = "class";
91
168
  if (!config.vite.build) {
@@ -98,10 +175,7 @@ function index({
98
175
  optimizeDeps: {
99
176
  include: ["defuss-astro/client.js", "defuss-astro/server.js"]
100
177
  },
101
- ssr: {
102
- noExternal: ["lightningimg-node"]
103
- },
104
- plugins: [defussPlugin()]
178
+ plugins: [defussVitePlugin()]
105
179
  }
106
180
  });
107
181
  },
package/dist/index.d.cts CHANGED
@@ -1,5 +1,16 @@
1
1
  import { AstroIntegration, ContainerRenderer } from 'astro';
2
- import { DefussVitePluginOptions } from 'defuss-vite';
2
+ import { FilterPattern } from 'vite';
3
+
4
+ interface DefussVitePluginOptions {
5
+ /**
6
+ * RegExp or glob to match files to be transformed
7
+ */
8
+ include?: FilterPattern;
9
+ /**
10
+ * RegExp or glob to match files to NOT be transformed
11
+ */
12
+ exclude?: FilterPattern;
13
+ }
3
14
 
4
15
  interface Options extends Pick<DefussVitePluginOptions, "exclude" | "include"> {
5
16
  devtools?: boolean;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,16 @@
1
1
  import { AstroIntegration, ContainerRenderer } from 'astro';
2
- import { DefussVitePluginOptions } from 'defuss-vite';
2
+ import { FilterPattern } from 'vite';
3
+
4
+ interface DefussVitePluginOptions {
5
+ /**
6
+ * RegExp or glob to match files to be transformed
7
+ */
8
+ include?: FilterPattern;
9
+ /**
10
+ * RegExp or glob to match files to NOT be transformed
11
+ */
12
+ exclude?: FilterPattern;
13
+ }
3
14
 
4
15
  interface Options extends Pick<DefussVitePluginOptions, "exclude" | "include"> {
5
16
  devtools?: boolean;
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import defussPlugin from 'defuss-vite';
1
+ import { createFilter } from 'vite';
2
+ import { transform } from '@swc/core';
2
3
  import { fileURLToPath } from 'node:url';
3
4
  import glob from 'fast-glob';
4
5
  import { performance } from 'node:perf_hooks';
@@ -8,6 +9,90 @@ import { readFile, writeFile } from 'node:fs/promises';
8
9
  import { PurgeCSS } from 'purgecss';
9
10
  import { existsSync } from 'node:fs';
10
11
 
12
+ function parseId(url) {
13
+ return { id: url.split("?", 2)[0] };
14
+ }
15
+ function defussVitePlugin({
16
+ include,
17
+ exclude
18
+ } = {}) {
19
+ let config;
20
+ const shouldTransform = createFilter(
21
+ include || [/\.[cm]?[tj]sx?$/],
22
+ exclude || [/node_modules/]
23
+ );
24
+ const jsxPlugin = {
25
+ name: "vite:defuss-jsx",
26
+ enforce: "pre",
27
+ config() {
28
+ return {
29
+ esbuild: {
30
+ // we want Vite to handle JSX transformations
31
+ jsxImportSource: "defuss",
32
+ jsxFactory: "jsx",
33
+ jsxFragment: "Fragment"
34
+ },
35
+ optimizeDeps: {
36
+ // we want Vite to optimize the runtime code
37
+ include: ["defuss"],
38
+ // we don't want Vite to optimize this plugin code
39
+ exclude: ["defuss-vite"]
40
+ },
41
+ ssr: {
42
+ // LinkeDOM (used by defuss/render) imports perf_hooks
43
+ // which is actually just an empty placeholder package,
44
+ // therefore, we externalize it
45
+ external: ["perf_hooks"]
46
+ }
47
+ };
48
+ },
49
+ configResolved(resolvedConfig) {
50
+ config = resolvedConfig;
51
+ },
52
+ async transform(code, url) {
53
+ const { id } = parseId(url);
54
+ if (!shouldTransform(id)) {
55
+ return null;
56
+ }
57
+ const prevSourceMap = this.getCombinedSourcemap?.();
58
+ const inputSourceMap = prevSourceMap ? JSON.stringify({ code, map: prevSourceMap }) : void 0;
59
+ const result = await transform(code, {
60
+ jsc: {
61
+ parser: {
62
+ syntax: "typescript",
63
+ tsx: true,
64
+ dynamicImport: true,
65
+ decorators: true
66
+ },
67
+ transform: {
68
+ react: {
69
+ development: true,
70
+ useBuiltins: false,
71
+ throwIfNamespace: false,
72
+ pragma: "jsx",
73
+ pragmaFrag: "Fragment",
74
+ runtime: "automatic",
75
+ importSource: "defuss"
76
+ }
77
+ },
78
+ target: "es2024"
79
+ },
80
+ sourceMaps: true,
81
+ sourceFileName: id,
82
+ filename: id,
83
+ sourceRoot: config.root,
84
+ inputSourceMap
85
+ });
86
+ if (!result) return null;
87
+ return {
88
+ code: result.code || code,
89
+ map: result.map
90
+ };
91
+ }
92
+ };
93
+ return jsxPlugin;
94
+ }
95
+
11
96
  const logMessage = (message) => {
12
97
  const date = (/* @__PURE__ */ new Date()).toLocaleTimeString();
13
98
  console.log(`${date} \x1B[32mdefuss-astro:\x1B[0m ${message}`);
@@ -72,16 +157,8 @@ function index({
72
157
  config,
73
158
  addRenderer,
74
159
  updateConfig,
75
- command,
76
- injectScript,
77
- injectRoute
160
+ command
78
161
  }) => {
79
- injectRoute({
80
- pattern: "/_defuss/image",
81
- prerender: false,
82
- entrypoint: "defuss-astro/image-endpoint.js"
83
- });
84
- fileURLToPath(config.publicDir);
85
162
  config.compressHTML = true;
86
163
  config.scopedStyleStrategy = "class";
87
164
  if (!config.vite.build) {
@@ -94,10 +171,7 @@ function index({
94
171
  optimizeDeps: {
95
172
  include: ["defuss-astro/client.js", "defuss-astro/server.js"]
96
173
  },
97
- ssr: {
98
- noExternal: ["lightningimg-node"]
99
- },
100
- plugins: [defussPlugin()]
174
+ plugins: [defussVitePlugin()]
101
175
  }
102
176
  });
103
177
  },
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "defuss-astro",
3
- "version": "1.4.8",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
8
  "license": "MIT",
9
- "description": "Defuss Integration for Astro with WASM-based built-in image conversion support.",
9
+ "description": "defuss integration for Astro",
10
10
  "keywords": [
11
11
  "jsx",
12
12
  "render",
@@ -56,10 +56,6 @@
56
56
  "types": "./dist/server.d.mts",
57
57
  "default": "./dist/server.mjs"
58
58
  }
59
- },
60
- "./image-endpoint.js": {
61
- "types": "./dist/endpoint/image-endpoint.d.mts",
62
- "default": "./dist/endpoint/image-endpoint.mjs"
63
59
  }
64
60
  },
65
61
  "main": "./dist/index.cjs",
@@ -78,12 +74,11 @@
78
74
  },
79
75
  "dependencies": {
80
76
  "defuss": "^2.1.10",
81
- "defuss-vite": "^1.1.3",
77
+ "@swc/core": "^1.10.2",
82
78
  "astro": "^5.16.11",
83
79
  "vite": "^6.4.1",
84
80
  "fast-glob": "^3.3.3",
85
81
  "svgo": "^4.0.0",
86
- "lightningimg": "^1.0.3",
87
82
  "purgecss": "^7.0.2",
88
83
  "file-type": "^21.3.0"
89
84
  }
@@ -1,67 +0,0 @@
1
- 'use strict';
2
-
3
- var fileType = require('file-type');
4
- var lightningimg = require('lightningimg');
5
-
6
- const GET = async ({ url }) => {
7
- try {
8
- const imgHrefRelative = url.searchParams.get("href");
9
- const height = url.searchParams.get("h");
10
- const width = url.searchParams.get("w");
11
- const quality = url.searchParams.get("q");
12
- if (!imgHrefRelative) {
13
- return new Response("Image URL is required", { status: 400 });
14
- }
15
- const imgHrefAbsolute = `${url.protocol}//${url.host}${imgHrefRelative}`;
16
- console.log("GET /_defuss/image (transforming: ", imgHrefAbsolute, ")");
17
- const response = await fetch(imgHrefAbsolute);
18
- if (!response.ok) {
19
- console.log("Error fetching image", { imgHrefAbsolute, response });
20
- return new Response("Error fetching image", { status: 500 });
21
- }
22
- const imageBuffer = Buffer.from(await response.arrayBuffer());
23
- const imageDimensions = await lightningimg.getImageInfo(imageBuffer);
24
- const fileExtension = (await fileType.fileTypeFromBuffer(imageBuffer))?.ext;
25
- if (!fileExtension) {
26
- console.log("Error fetching fileExtension", { fileExtension, response });
27
- return new Response("Error getting file extension", { status: 500 });
28
- }
29
- if (fileExtension === "webp") {
30
- return new Response(imageBuffer, {
31
- headers: {
32
- "Content-Type": "image/webp",
33
- "Content-Length": imageBuffer.byteLength.toString()
34
- }
35
- });
36
- }
37
- let convertedImageBuffer;
38
- try {
39
- convertedImageBuffer = await lightningimg.convertImageBuffer(
40
- imageBuffer,
41
- width ? Number.parseInt(width) : imageDimensions.width,
42
- height ? Number.parseInt(height) : imageDimensions.height
43
- );
44
- if (!convertedImageBuffer) {
45
- throw new Error("Error converting image: no buffer returned");
46
- }
47
- } catch (error) {
48
- console.log("Error converting image", {
49
- fileExtension,
50
- bufferLength: imageBuffer.byteLength,
51
- error
52
- });
53
- return new Response("Error converting image", { status: 500 });
54
- }
55
- const mimeType = `image/${fileExtension}`;
56
- return new Response(convertedImageBuffer, {
57
- headers: {
58
- "Content-Type": mimeType,
59
- "Content-Length": convertedImageBuffer.length.toString()
60
- }
61
- });
62
- } catch (error) {
63
- return new Response(`Error fetching image: ${error}`, { status: 500 });
64
- }
65
- };
66
-
67
- exports.GET = GET;
@@ -1,5 +0,0 @@
1
- import { APIRoute } from 'astro';
2
-
3
- declare const GET: APIRoute;
4
-
5
- export { GET };
@@ -1,5 +0,0 @@
1
- import { APIRoute } from 'astro';
2
-
3
- declare const GET: APIRoute;
4
-
5
- export { GET };
@@ -1,65 +0,0 @@
1
- import { fileTypeFromBuffer } from 'file-type';
2
- import { getImageInfo, convertImageBuffer } from 'lightningimg';
3
-
4
- const GET = async ({ url }) => {
5
- try {
6
- const imgHrefRelative = url.searchParams.get("href");
7
- const height = url.searchParams.get("h");
8
- const width = url.searchParams.get("w");
9
- const quality = url.searchParams.get("q");
10
- if (!imgHrefRelative) {
11
- return new Response("Image URL is required", { status: 400 });
12
- }
13
- const imgHrefAbsolute = `${url.protocol}//${url.host}${imgHrefRelative}`;
14
- console.log("GET /_defuss/image (transforming: ", imgHrefAbsolute, ")");
15
- const response = await fetch(imgHrefAbsolute);
16
- if (!response.ok) {
17
- console.log("Error fetching image", { imgHrefAbsolute, response });
18
- return new Response("Error fetching image", { status: 500 });
19
- }
20
- const imageBuffer = Buffer.from(await response.arrayBuffer());
21
- const imageDimensions = await getImageInfo(imageBuffer);
22
- const fileExtension = (await fileTypeFromBuffer(imageBuffer))?.ext;
23
- if (!fileExtension) {
24
- console.log("Error fetching fileExtension", { fileExtension, response });
25
- return new Response("Error getting file extension", { status: 500 });
26
- }
27
- if (fileExtension === "webp") {
28
- return new Response(imageBuffer, {
29
- headers: {
30
- "Content-Type": "image/webp",
31
- "Content-Length": imageBuffer.byteLength.toString()
32
- }
33
- });
34
- }
35
- let convertedImageBuffer;
36
- try {
37
- convertedImageBuffer = await convertImageBuffer(
38
- imageBuffer,
39
- width ? Number.parseInt(width) : imageDimensions.width,
40
- height ? Number.parseInt(height) : imageDimensions.height
41
- );
42
- if (!convertedImageBuffer) {
43
- throw new Error("Error converting image: no buffer returned");
44
- }
45
- } catch (error) {
46
- console.log("Error converting image", {
47
- fileExtension,
48
- bufferLength: imageBuffer.byteLength,
49
- error
50
- });
51
- return new Response("Error converting image", { status: 500 });
52
- }
53
- const mimeType = `image/${fileExtension}`;
54
- return new Response(convertedImageBuffer, {
55
- headers: {
56
- "Content-Type": mimeType,
57
- "Content-Length": convertedImageBuffer.length.toString()
58
- }
59
- });
60
- } catch (error) {
61
- return new Response(`Error fetching image: ${error}`, { status: 500 });
62
- }
63
- };
64
-
65
- export { GET };