@uxf/resizer 11.88.0 → 11.122.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/README.md +111 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,29 +1,49 @@
|
|
|
1
1
|
# @uxf/resizer
|
|
2
|
+
|
|
2
3
|
[](https://www.npmjs.com/package/@uxf/resizer)
|
|
3
4
|
|
|
5
|
+
On-the-fly image resizing that serves the `/generated/...` URLs produced by `resizerImageUrl` (`@uxf/core`). It ships Next.js App Router route handlers for local development and a standalone Express server (`uxf-resizer`) for self-hosting. Resizing is done with [`sharp`](https://sharp.pixelplumbing.com/).
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
This package **serves and generates** resized images. It does **not** build image URLs — that is done client-side by `resizerImageUrl` from `@uxf/core/utils/resizer`, which encodes the resize parameters into a `/generated/...` path.
|
|
10
|
+
|
|
11
|
+
- **Production** — a shared/global resizer service handles the `/generated/...` requests; you typically do not run this package there.
|
|
12
|
+
- **Local development** — mount `ProxyGET` / `StaticGET` as Next.js route handlers so `/generated/...` URLs resolve during `next dev`.
|
|
13
|
+
- **Self-hosting** — run the `uxf-resizer` CLI (Express server) driven by a config file.
|
|
14
|
+
|
|
15
|
+
Both entry points read the same URL segments (width, height, fit, position, background, trim, quality, target format) and pipe the source image through `sharp`. Generated files are cached on disk and re-served on subsequent requests.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
4
18
|
|
|
5
|
-
## Installation + example (local dev next routes)
|
|
6
19
|
```
|
|
7
20
|
yarn add @uxf/resizer --dev
|
|
8
21
|
```
|
|
9
22
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
23
|
+
The only runtime dependency is `sharp`. The standalone server additionally needs `express`, `path-to-regexp`, `process`, and `yargs` — they are **not** installed transitively, so add them yourself when you use the CLI:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
yarn add @uxf/resizer express path-to-regexp process yargs --dev
|
|
14
27
|
```
|
|
15
28
|
|
|
16
|
-
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
Next.js App Router route handlers for local development. Two handlers are exported:
|
|
32
|
+
|
|
33
|
+
- `ProxyGET` — proxies uploaded images from the API and resizes them.
|
|
34
|
+
- `StaticGET` — resizes static assets (`public/` files and Next.js `_next/static/media` imports).
|
|
35
|
+
|
|
36
|
+
Folder structure:
|
|
17
37
|
|
|
18
38
|
```shell
|
|
19
39
|
src/
|
|
20
40
|
app/
|
|
21
41
|
generated/
|
|
22
42
|
[...path]/
|
|
23
|
-
route.ts
|
|
43
|
+
route.ts # ProxyGET → uploaded images
|
|
24
44
|
static/
|
|
25
45
|
[...path]/
|
|
26
|
-
route.ts
|
|
46
|
+
route.ts # StaticGET → static images
|
|
27
47
|
```
|
|
28
48
|
|
|
29
49
|
```ts
|
|
@@ -40,49 +60,99 @@ import { StaticGET as GET } from "@uxf/resizer";
|
|
|
40
60
|
export { GET };
|
|
41
61
|
```
|
|
42
62
|
|
|
43
|
-
|
|
63
|
+
Both handlers read their upstream location from environment variables:
|
|
64
|
+
|
|
65
|
+
```shell
|
|
66
|
+
# .env.local
|
|
67
|
+
NEXT_PUBLIC_FRONTEND_URL=http://127.0.0.1:3000 # StaticGET source (Next.js static media)
|
|
68
|
+
NEXT_PUBLIC_API_URL=https://uxf.cz # ProxyGET source (fetches <API_URL>/upload/...)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## API
|
|
72
|
+
|
|
73
|
+
Exported from the package root (`@uxf/resizer`):
|
|
74
|
+
|
|
75
|
+
| Export | Signature | Description |
|
|
76
|
+
|--------|-----------|-------------|
|
|
77
|
+
| `ProxyGET` | `(request: Request) => Promise<Response>` | Next.js route handler. Matches `/generated/:namespace/:p1/:p2/:filename_..._:extension.:toFormat`, fetches the source from `${NEXT_PUBLIC_API_URL}/upload/:namespace/:p1/:p2/:filename.:extension`, resizes, caches under the process CWD, and returns the image. |
|
|
78
|
+
| `StaticGET` | `(request: Request) => Promise<Response>` | Next.js route handler. Matches `/generated/static/..._:quality/:version/:filename.:extension.:toFormat`. Reads local `public/:filename.:extension`; for `_next/static/media/*` imports it fetches from `${NEXT_PUBLIC_FRONTEND_URL}`. |
|
|
79
|
+
|
|
80
|
+
Command-line server:
|
|
81
|
+
|
|
44
82
|
```
|
|
45
|
-
yarn add @uxf/resizer express path-to-regexp process yargs
|
|
46
83
|
uxf-resizer
|
|
47
84
|
```
|
|
48
85
|
|
|
49
|
-
|
|
86
|
+
Starts an Express server on port `3000` that applies the routes from the configuration (see below). Requires the extra dependencies listed under Installation.
|
|
87
|
+
|
|
88
|
+
## Route parameters
|
|
89
|
+
|
|
90
|
+
The URL segments understood by every route. They are produced by `resizerImageUrl` (`@uxf/core`) and mapped onto [`sharp`](https://sharp.pixelplumbing.com/) options.
|
|
50
91
|
|
|
51
|
-
|
|
92
|
+
| Parameter | Values | Default (falls back to sharp) |
|
|
93
|
+
|------------|--------------------------------------------|----------------------------------------|
|
|
94
|
+
| width | `number` or `x` (auto) | `undefined` (auto) |
|
|
95
|
+
| height | `number` or `x` (auto) | `undefined` (auto) |
|
|
96
|
+
| fit | fit code (see below) | `cover` |
|
|
97
|
+
| position | position code (see below) | sharp default (`centre`) |
|
|
98
|
+
| background | hex (e.g. `FFFFFF`) or `t` (transparent) | `#<hex>` |
|
|
99
|
+
| trim | `number` (threshold) or `nt` (no trim) | no trim |
|
|
100
|
+
| quality | `number` (1–100) or `x` (auto) | sharp default (avif: 50, others: 80) |
|
|
101
|
+
| toFormat | `webp`, `png`, `avif`, `jpg`, `svg` | `jpg` |
|
|
102
|
+
|
|
103
|
+
`svg` is a passthrough — the source file is copied unchanged, without resizing.
|
|
104
|
+
|
|
105
|
+
### Fit codes
|
|
106
|
+
|
|
107
|
+
- `cv`: cover
|
|
108
|
+
- `f`: fill
|
|
109
|
+
- `cn`: contain
|
|
110
|
+
- `in`: inside
|
|
111
|
+
- `out`: outside
|
|
112
|
+
|
|
113
|
+
### Position codes
|
|
114
|
+
|
|
115
|
+
- `a`: attention
|
|
116
|
+
- `b`: bottom
|
|
117
|
+
- `c`: centre
|
|
118
|
+
- `e`: entropy
|
|
119
|
+
- `l`: left
|
|
120
|
+
- `lb`: left bottom
|
|
121
|
+
- `lt`: left top
|
|
122
|
+
- `r`: right
|
|
123
|
+
- `rb`: right bottom
|
|
124
|
+
- `rt`: right top
|
|
125
|
+
- `t`: top
|
|
126
|
+
|
|
127
|
+
## Server configuration
|
|
128
|
+
|
|
129
|
+
The `uxf-resizer` CLI reads its config from `.resizer-config.json` in the working directory, or from the `UXF_RESIZER_CONFIG` environment variable (an inline JSON string, which takes precedence). Generated files are written to `UXF_RESIZER_GENERATE_PATH` (defaults to the process CWD).
|
|
130
|
+
|
|
131
|
+
The config is an array of `{ route, source }` objects. `route` is a [`path-to-regexp`](https://github.com/pillarjs/path-to-regexp) pattern that captures the resize parameters; `source` is the original file location (a local path or an `http(s)` URL, which is fetched). `source` may reference any captured segment, including the domain as a parameter (e.g. `https://:url/...`).
|
|
52
132
|
|
|
53
133
|
```json
|
|
54
134
|
[
|
|
55
135
|
{
|
|
56
|
-
"route": "/generated/:
|
|
57
|
-
"source": "
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"route": "/generated/:namespace/:p1/:p2/:filename([a-f0-9\\-]+)_:width(\\d+)_:height(\\d+)_:fit([a-z]+).:extension",
|
|
61
|
-
"source": "/var/www/UXF/projects/resizer/example-upload/:namespace/:p1/:p2/:filename.:extension"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"route": "/generated/static/:width(\\d+)_:height(\\d+)/:filename(*).:extension.:toExtension",
|
|
65
|
-
"source": "https://www.uxf.cz/:filename+"
|
|
136
|
+
"route": "/generated/static/:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)/:version/:filename(*).:extension.:toFormat",
|
|
137
|
+
"source": "https://static.example.dev/:filename+.:extension"
|
|
66
138
|
},
|
|
67
139
|
{
|
|
68
|
-
"route": "
|
|
69
|
-
"source": "https://s3.
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"route": "/:url/generated/static/:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)/:version/:filename(*).:extension.:toFormat",
|
|
73
|
-
"source": "https://:url/:filename+.:extension"
|
|
140
|
+
"route": "/generated/:namespace/:p1/:p2/:filename([a-f0-9\\-]+)_:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)_:extension.:toFormat",
|
|
141
|
+
"source": "https://s3.example.dev/:namespace/:p1/:p2/:filename.:extension"
|
|
74
142
|
}
|
|
75
143
|
]
|
|
76
144
|
```
|
|
77
145
|
|
|
78
|
-
|
|
146
|
+
`resizerGetDefaultConfig(generatedFilesUrl, staticFilesUrl)` from `@uxf/core/utils/resizer` returns exactly this two-route shape.
|
|
79
147
|
|
|
80
|
-
|
|
148
|
+
### UXF Basic configuration (deprecated)
|
|
149
|
+
|
|
150
|
+
Deprecated — use the global resizer for all projects instead.
|
|
81
151
|
|
|
82
152
|
```json
|
|
83
153
|
[
|
|
84
154
|
{
|
|
85
|
-
"route": "/generated/static/:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)/:version/:filename(*).:extension.:toFormat",
|
|
155
|
+
"route": "/generated/static/:width(\\d+|x)_:height(\\d+|x)_:fit([a-z]+)_:position([a-z]+)_:background([a-z]+)_:trim([a-z]+)_:quality(\\d+|x)/:version/:filename(*).:extension.:toFormat",
|
|
86
156
|
"source": "https://uxf-base.uxf.dev/:filename+.:extension"
|
|
87
157
|
},
|
|
88
158
|
{
|
|
@@ -92,36 +162,16 @@ This is deprecated. Please use our global resizer for all projects.
|
|
|
92
162
|
]
|
|
93
163
|
```
|
|
94
164
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
| Parameter name | Type | Default sharp value |
|
|
98
|
-
|----------------|------------------------------------|----------------------------------------|
|
|
99
|
-
| width | `number` or `x` (auto) | `undefined` |
|
|
100
|
-
| height | `number` or `x` (auto) | `undefined` |
|
|
101
|
-
| fit | `Fit` | cover |
|
|
102
|
-
| position | `Position` | |
|
|
103
|
-
| background | `FFFFFF` or `t` (transparent) | |
|
|
104
|
-
| toFormat | `webp`, `png`, `avif`, `jpg` | `jpg` |
|
|
105
|
-
| trim | `number` or `nt` (not trim) | |
|
|
106
|
-
| quality | `number` (min: 1, max: 100) or `x` | default of sharp (avif: 50, other: 80) |
|
|
165
|
+
## Gotchas
|
|
107
166
|
|
|
167
|
+
- **URLs are built elsewhere.** Encode the parameters with `resizerImageUrl` from `@uxf/core/utils/resizer`; this package only serves the resulting paths.
|
|
168
|
+
- **CLI dependencies are not transitive.** `express`, `path-to-regexp`, `process`, and `yargs` are dev dependencies of this package, so a consumer running `uxf-resizer` must install them explicitly.
|
|
169
|
+
- **Generated files are cached on disk.** Once a variant exists under the output path it is served as-is; delete the cached file to force regeneration.
|
|
170
|
+
- **The server listens on a fixed port `3000`** and an empty or invalid configuration throws on startup.
|
|
171
|
+
- **`quality` defaults to sharp's own defaults** when set to `x` (avif ≈ 50, others ≈ 80). Values are expected in the `1–100` range.
|
|
108
172
|
|
|
109
|
-
|
|
110
|
-
- `cv`: cover,
|
|
111
|
-
- `f`: fill,
|
|
112
|
-
- `cn`: contain,
|
|
113
|
-
- `in`: inside,
|
|
114
|
-
- `out`: outside,
|
|
173
|
+
## Links
|
|
115
174
|
|
|
116
|
-
|
|
117
|
-
-
|
|
118
|
-
- `
|
|
119
|
-
- `c`: centre
|
|
120
|
-
- `e`: entropy
|
|
121
|
-
- `l`: left
|
|
122
|
-
- `lb`: left bottom
|
|
123
|
-
- `lt`: left top
|
|
124
|
-
- `r`: right
|
|
125
|
-
- `rb`: right bottom
|
|
126
|
-
- `rt`: right top
|
|
127
|
-
- `t`: top
|
|
175
|
+
- [npm: @uxf/resizer](https://www.npmjs.com/package/@uxf/resizer)
|
|
176
|
+
- [sharp documentation](https://sharp.pixelplumbing.com/)
|
|
177
|
+
- URL builder: `resizerImageUrl` in `@uxf/core/utils/resizer`
|