@ubean/image 0.1.2 → 0.1.4

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/vite.js ADDED
@@ -0,0 +1,175 @@
1
+ import { t as configureImageRuntime } from "./runtime-3aSOG0e9.js";
2
+ import { defu } from "defu";
3
+ //#region src/vite.ts
4
+ const defaultOptions = {
5
+ injectScript: true,
6
+ staticDir: "public",
7
+ ipxMiddleware: true,
8
+ devtools: true
9
+ };
10
+ const VIRTUAL_IMAGE = "virtual:ubean-image-config";
11
+ const RESOLVED_VIRTUAL_IMAGE = `\0${VIRTUAL_IMAGE}`;
12
+ function ubeanImagePlugin(userOptions = {}) {
13
+ const options = defu(userOptions, defaultOptions);
14
+ let isDev = false;
15
+ return {
16
+ name: "ubean:image",
17
+ enforce: "pre",
18
+ configResolved(resolvedConfig) {
19
+ isDev = resolvedConfig.command === "serve";
20
+ },
21
+ resolveId(id) {
22
+ if (id === VIRTUAL_IMAGE) return RESOLVED_VIRTUAL_IMAGE;
23
+ return null;
24
+ },
25
+ load(id) {
26
+ if (id === RESOLVED_VIRTUAL_IMAGE) return `
27
+ export const imageConfig = ${JSON.stringify({
28
+ provider: options.provider || "ipx",
29
+ presets: options.presets || {},
30
+ screens: options.screens || {},
31
+ densities: options.densities || [1, 2],
32
+ format: options.format || ["webp", "avif"],
33
+ quality: options.quality || 80,
34
+ domains: options.domains || [],
35
+ alias: options.alias || {},
36
+ ipx: options.ipx || { baseURL: "/_ipx" },
37
+ static: options.static || { baseURL: "/_image" }
38
+ })};
39
+ export default imageConfig;
40
+ `;
41
+ return null;
42
+ },
43
+ configureServer(server) {
44
+ if (options.ipxMiddleware) {
45
+ const ipxHandler = async (req, res, next) => {
46
+ if (!req.url) return next();
47
+ const url = new URL(req.url, "http://localhost");
48
+ const parts = decodeURIComponent(url.pathname).split("/").filter(Boolean);
49
+ if (parts.length < 2) {
50
+ res.statusCode = 400;
51
+ res.end("Invalid IPX request");
52
+ return;
53
+ }
54
+ const modifiers = parts[0] === "_" ? {} : parseModifiers(parts[0]);
55
+ const src = parts.slice(1).join("/");
56
+ try {
57
+ res.setHeader("Content-Type", getContentType(src, modifiers.format));
58
+ res.setHeader("Cache-Control", isDev ? "no-cache" : "public, max-age=31536000, immutable");
59
+ res.statusCode = 302;
60
+ res.setHeader("Location", src.startsWith("http") ? src : `/${src}`);
61
+ res.end();
62
+ } catch (err) {
63
+ next(err);
64
+ }
65
+ };
66
+ server.middlewares.use("/_ipx", (req, res, next) => {
67
+ ipxHandler(req, res, next).catch(next);
68
+ });
69
+ }
70
+ },
71
+ buildStart() {
72
+ configureImageRuntime({
73
+ provider: options.provider,
74
+ providers: options.providers,
75
+ presets: options.presets,
76
+ screens: options.screens,
77
+ densities: options.densities,
78
+ format: options.format,
79
+ quality: options.quality,
80
+ domains: options.domains,
81
+ alias: options.alias,
82
+ ipx: options.ipx,
83
+ static: options.static
84
+ });
85
+ }
86
+ };
87
+ }
88
+ function parseModifiers(str) {
89
+ const mods = {};
90
+ const parts = str.split(",");
91
+ for (const part of parts) {
92
+ if (part === "_") continue;
93
+ if (part === "fh") {
94
+ mods.flip = mods.flip === "v" ? "hv" : "h";
95
+ continue;
96
+ }
97
+ if (part === "fv") {
98
+ mods.flip = mods.flip === "h" ? "hv" : "v";
99
+ continue;
100
+ }
101
+ if (part === "grayscale") {
102
+ mods.grayscale = true;
103
+ continue;
104
+ }
105
+ if (part === "negate") {
106
+ mods.negate = true;
107
+ continue;
108
+ }
109
+ if (part === "trim") {
110
+ mods.trim = true;
111
+ continue;
112
+ }
113
+ if (part === "enlarge") {
114
+ mods.enlarge = true;
115
+ continue;
116
+ }
117
+ const [key, ...valueParts] = part.split("_");
118
+ const value = valueParts.join("_");
119
+ switch (key) {
120
+ case "w":
121
+ mods.width = parseInt(value, 10);
122
+ break;
123
+ case "h":
124
+ mods.height = parseInt(value, 10);
125
+ break;
126
+ case "f":
127
+ mods.fit = value;
128
+ break;
129
+ case "p":
130
+ mods.position = decodeURIComponent(value);
131
+ break;
132
+ case "fm":
133
+ mods.format = value;
134
+ break;
135
+ case "q":
136
+ mods.quality = parseInt(value, 10);
137
+ break;
138
+ case "blur":
139
+ mods.blur = parseFloat(value);
140
+ break;
141
+ case "sharpen":
142
+ mods.sharpen = parseFloat(value);
143
+ break;
144
+ case "rot":
145
+ mods.rotate = parseInt(value, 10);
146
+ break;
147
+ case "bg":
148
+ mods.background = decodeURIComponent(value);
149
+ break;
150
+ case "br":
151
+ mods.brightness = parseFloat(value);
152
+ break;
153
+ case "con":
154
+ mods.contrast = parseFloat(value);
155
+ break;
156
+ case "sat":
157
+ mods.saturation = parseFloat(value);
158
+ break;
159
+ }
160
+ }
161
+ return mods;
162
+ }
163
+ function getContentType(src, format) {
164
+ return {
165
+ webp: "image/webp",
166
+ avif: "image/avif",
167
+ jpg: "image/jpeg",
168
+ jpeg: "image/jpeg",
169
+ png: "image/png",
170
+ gif: "image/gif",
171
+ svg: "image/svg+xml"
172
+ }[format || src.split(".").pop()?.toLowerCase() || ""] || "image/jpeg";
173
+ }
174
+ //#endregion
175
+ export { ubeanImagePlugin as default, ubeanImagePlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/image",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Image optimization and transformation for ubean",
5
5
  "files": [
6
6
  "dist"