├── .devcontainer
├── Dockerfile
├── devcontainer.json
├── docker-compose.yml
├── imgproxy-truncated.env
├── imgproxy-unsigned.env
├── imgproxy.env
├── init.sh
├── minio-dump
│ └── test-bucket
│ │ ├── test-image.png
│ │ └── test-image.svg
├── minio.env
├── test-image.png
└── workspace.env
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .github
├── dependabot.yml
└── workflows
│ ├── build.yml
│ ├── dependabot-auto-merge.yml
│ └── publish-npm-package.yml
├── .gitignore
├── .ncurc.json
├── .nvmrc
├── .prettierrc
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── docs
├── .nojekyll
├── assets
│ ├── highlight.css
│ ├── icons.js
│ ├── icons.svg
│ ├── main.js
│ ├── navigation.js
│ ├── search.js
│ └── style.css
├── classes
│ └── ParamBuilder.html
├── enums
│ ├── GradientDirection.html
│ ├── GravityType.html
│ ├── ResizeType.html
│ ├── ResizingAlgorithm.html
│ ├── UnsharpeningMode.html
│ └── WatermarkPosition.html
├── functions
│ ├── chain.html
│ └── default.html
├── index.html
├── modules.html
└── types
│ ├── AdjustOptions.html
│ ├── BackgroundAlphaOptions.html
│ ├── BackgroundOptions.html
│ ├── BlurDetectionOptions.html
│ ├── BlurOptions.html
│ ├── BrightnessOptions.html
│ ├── BuildOptions.html
│ ├── CacheBusterOptions.html
│ ├── ContrastOptions.html
│ ├── CropOptions.html
│ ├── DPIOptions.html
│ ├── DprOptions.html
│ ├── DrawDetectionOptions.html
│ ├── DuotoneOptions.html
│ ├── ExpiresOptions.html
│ ├── ExtendAspectRatioOptions.html
│ ├── ExtendOptions.html
│ ├── FallbackImageUrlOptions.html
│ ├── FileNameOptions.html
│ ├── FormatOptions.html
│ ├── FormatQualityOptions.html
│ ├── GifOptions.html
│ ├── GradientOptions.html
│ ├── GravityOptions.html
│ ├── HashsumOptions.html
│ ├── JpegOptions.html
│ ├── MaxBytesOptions.html
│ ├── MinHeightOptions.html
│ ├── MinWidthOptions.html
│ ├── MonochromeOptions.html
│ ├── PaddingOptions.html
│ ├── PageOptions.html
│ ├── PixelateOptions.html
│ ├── PngOptions.html
│ ├── PresetOptions.html
│ ├── QualityOptions.html
│ ├── ResizeOptions.html
│ ├── ResizingAlgorithmOptions.html
│ ├── RotationOptions.html
│ ├── SaturationOptions.html
│ ├── SharpenOptions.html
│ ├── SkipProcessingOptions.html
│ ├── StyleOptions.html
│ ├── TrimOptions.html
│ ├── UnsharpeningOptions.html
│ ├── VideoThumbnailKeyframesOptions.html
│ ├── VideoThumbnailSecondOptions.html
│ ├── VideoThumbnailTileOptions.html
│ ├── WatermarkOptions.html
│ ├── WatermarkShadowOptions.html
│ ├── WatermarkSizeOptions.html
│ ├── WatermarkTextOptions.html
│ ├── WatermarkUrlOptions.html
│ └── ZoomOptions.html
├── jest.config.ts
├── jest.globals.ts
├── jest.setup.ts
├── package-lock.json
├── package.json
├── rollup.config.js
├── scripts
├── micro-benchmark.cjs
├── minio-dump.sh
├── minio-restore.sh
└── populate-readme.cjs
├── src
├── common.ts
├── crypto
│ ├── codec.ts
│ ├── common.ts
│ ├── hmac.ts
│ └── sha256.ts
├── enums
│ ├── gradient-direction.enum.ts
│ ├── gravity-type.enum.ts
│ ├── hashsum-type.enum.ts
│ ├── resize-type.enum.ts
│ ├── resizing-algorithm.enum.ts
│ ├── unsharpening-mode.enum.ts
│ └── watermark-position.enum.ts
├── index.ts
├── param-builder.ts
├── transformers
│ ├── adjust.ts
│ ├── auto-rotate.ts
│ ├── background-alpha.ts
│ ├── background.ts
│ ├── blur-detections.ts
│ ├── blur.ts
│ ├── brightness.ts
│ ├── cache-buster.ts
│ ├── contrast.ts
│ ├── crop.ts
│ ├── disable-animation.ts
│ ├── dpi.ts
│ ├── dpr.ts
│ ├── draw-detections.ts
│ ├── duotone.ts
│ ├── enforce-thumbnail.ts
│ ├── enlarge.ts
│ ├── expires.ts
│ ├── extend-aspect-ratio.ts
│ ├── extend.ts
│ ├── fallback-image-url.ts
│ ├── filename.ts
│ ├── format-quality.ts
│ ├── format.ts
│ ├── gif-options.ts
│ ├── gradient.ts
│ ├── gravity.ts
│ ├── hashsum.ts
│ ├── jpeg-options.ts
│ ├── keep-copypright.ts
│ ├── max-bytes.ts
│ ├── min-height.ts
│ ├── min-width.ts
│ ├── monochrome.ts
│ ├── pad.ts
│ ├── page.ts
│ ├── pixelate.ts
│ ├── png-options.ts
│ ├── preset.ts
│ ├── quality.ts
│ ├── raw.ts
│ ├── resize.ts
│ ├── resizing-algorithm.ts
│ ├── return-attachment.ts
│ ├── rotate.ts
│ ├── saturation.ts
│ ├── sharpen.ts
│ ├── skip-processing.ts
│ ├── strip-color-profile.ts
│ ├── strip-metadata.ts
│ ├── style.ts
│ ├── trim.ts
│ ├── unsharpen.ts
│ ├── video-thumbnail-keyframes.ts
│ ├── video-thumbnail-second.ts
│ ├── video-thumbnail-tile.ts
│ ├── watermark-shadow.ts
│ ├── watermark-size.ts
│ ├── watermark-text.ts
│ ├── watermark-url.ts
│ ├── watermark.ts
│ └── zoom.ts
└── utils.ts
├── test
├── .gitkeep
├── chain.test.ts
├── clone.test.ts
├── crypto
│ ├── base64.test.ts
│ ├── hmac.test.ts
│ └── sha256.test.ts
├── override.test.ts
├── signature.test.ts
├── transformers.test.ts
└── unset.test.ts
├── tsconfig.build.json
├── tsconfig.json
└── typedoc.json
/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | # Update the VARIANT arg in docker-compose.yml to pick a Node version: 10, 12, 14
2 | ARG VARIANT=18
3 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
4 |
5 | # See https://github.com/microsoft/vscode-dev-containers/tree/master/containers/docker-from-docker for more documentation
6 | # On how to use docker from within docker
7 |
8 | # Install Docker CE CLI
9 | RUN apt-get update \
10 | && apt-get install -y apt-transport-https ca-certificates curl gnupg2 lsb-release \
11 | && curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | apt-key add - 2>/dev/null \
12 | && echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list \
13 | && apt-get update \
14 | && apt-get install -y docker-ce-cli
15 |
16 | # Install Docker Compose
17 | RUN LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")') \
18 | && curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
19 | && chmod +x /usr/local/bin/docker-compose
20 |
21 | # Update args in docker-compose.yaml to set the UID/GID of the "node" user.
22 | ARG USER_UID=1000
23 | ARG USER_GID=$USER_UID
24 | RUN if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then groupmod --gid $USER_GID node && usermod --uid $USER_UID --gid $USER_GID node; fi
25 |
26 | # Add the node user to the docker group to access
27 | # the daemon without sudo
28 | RUN groupadd docker
29 | RUN usermod -a -G docker node
30 |
31 | # Add minio CLI
32 | # See https://min.io/download#/linux
33 | RUN wget https://dl.min.io/client/mc/release/linux-amd64/mc \
34 | && mv mc /usr/local/bin/minio-cli \
35 | && chmod +x /usr/local/bin/minio-cli
36 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "imgproxy-js",
3 | "dockerComposeFile": "docker-compose.yml",
4 | "service": "application",
5 | "workspaceFolder": "/workspace",
6 | "customizations": {
7 | "vscode": {
8 | "settings": {
9 | "terminal.integrated.defaultProfile.linux": "bash"
10 | },
11 | "extensions": [
12 | "dbaeumer.vscode-eslint",
13 | "esbenp.prettier-vscode",
14 | "mikestead.dotenv",
15 | "ms-azuretools.vscode-docker",
16 | "ms-vsliveshare.vsliveshare",
17 | "wayou.vscode-todo-highlight",
18 | "streetsidesoftware.code-spell-checker"
19 | ]
20 | }
21 | },
22 | "forwardPorts": [4000, 5000, 9000, 9001],
23 | "postCreateCommand": "bash -i .devcontainer/init.sh",
24 | "remoteUser": "node",
25 | "portsAttributes": {
26 | "4000": {
27 | "label": "Imgproxy Server"
28 | },
29 | "5000": {
30 | "label": "Imgproxy Server (Unsigned)"
31 | },
32 | "9000": {
33 | "label": "Minio Server"
34 | },
35 | "9001": {
36 | "label": "Minio Console"
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/.devcontainer/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 |
3 | networks:
4 | imgproxy-url-builder-network:
5 | name: imgproxy-url-builder-network
6 | driver: bridge
7 |
8 | volumes:
9 | imgproxy-url-builder-minio__data:
10 | driver: local
11 |
12 | services:
13 | application:
14 | container_name: imgproxy-url-builder
15 | build:
16 | context: .
17 | dockerfile: Dockerfile
18 | args:
19 | VARIANT: 20
20 | USER_UID: 1000
21 | USER_GID: 1000
22 | networks:
23 | - imgproxy-url-builder-network
24 | volumes:
25 | - ..:/workspace:cached
26 | - /var/run/docker.sock:/var/run/docker.sock
27 | command: sleep infinity
28 | user: node
29 | env_file:
30 | - ./workspace.env
31 | ports:
32 | - 4000:4000
33 | - 4001:4001
34 | - 4002:4002
35 | - 9000:9000
36 | - 9001:9001
37 |
38 | # Minio
39 | imgproxy-url-builder-minio:
40 | container_name: imgproxy-url-builder-minio
41 | image: minio/minio:RELEASE.2021-10-23T03-28-24Z
42 | network_mode: service:application
43 | volumes:
44 | - type: volume
45 | source: imgproxy-url-builder-minio__data
46 | target: /data
47 | volume:
48 | nocopy: false
49 | command: server /data --console-address :9001
50 | env_file:
51 | - ./minio.env
52 |
53 | # Imgproxy
54 | imgproxy-url-builder-imgproxy:
55 | container_name: imgproxy-url-builder-imgproxy
56 | image: darthsim/imgproxy:v3.13.2
57 | network_mode: service:application
58 | env_file:
59 | - ./imgproxy.env
60 |
61 | imgproxy-url-builder-imgproxy-unsigned:
62 | container_name: imgproxy-url-builder-imgproxy-unsigned
63 | image: darthsim/imgproxy:v3.13.2
64 | network_mode: service:application
65 | env_file:
66 | - ./imgproxy-unsigned.env
67 |
68 | imgproxy-url-builder-imgproxy-ttruncated:
69 | container_name: imgproxy-url-builder-imgproxy-truncated
70 | image: darthsim/imgproxy:v3.13.2
71 | network_mode: service:application
72 | env_file:
73 | - ./imgproxy-truncated.env
74 |
--------------------------------------------------------------------------------
/.devcontainer/imgproxy-truncated.env:
--------------------------------------------------------------------------------
1 | IMGPROXY_BIND=0.0.0.0:4002
2 | IMGPROXY_ALLOWED_SOURCES=s3://
3 | IMGPROXY_USE_S3=true
4 | IMGPROXY_S3_ENDPOINT=http://localhost:9000
5 | IMGPROXY_KEY=91bdcda48ce22cd7d8d3a0eda930b3db1762bc1cba5dc13542e723b68fe55d6f9d18199cbe35191a45faf22593405cad0fe76ffec67d24f8aee861ac8fe44d96
6 | IMGPROXY_SALT=72456c286761260f320391fe500fcec53755958dabd288867a6db072e1bc1dbd84b15079838a83a715edc1ecad50c3ce91dd8fdef6f981816fa274f91d8ecf06
7 | AWS_ACCESS_KEY_ID=minio_user
8 | AWS_SECRET_ACCESS_KEY=minio_password
9 | IMGPROXY_SIGNATURE_SIZE=13
--------------------------------------------------------------------------------
/.devcontainer/imgproxy-unsigned.env:
--------------------------------------------------------------------------------
1 | IMGPROXY_BIND=0.0.0.0:4001
2 | IMGPROXY_ALLOWED_SOURCES=s3://
3 | IMGPROXY_USE_S3=true
4 | IMGPROXY_S3_ENDPOINT=http://localhost:9000
5 | AWS_ACCESS_KEY_ID=minio_user
6 | AWS_SECRET_ACCESS_KEY=minio_password
--------------------------------------------------------------------------------
/.devcontainer/imgproxy.env:
--------------------------------------------------------------------------------
1 | IMGPROXY_BIND=0.0.0.0:4000
2 | IMGPROXY_ALLOWED_SOURCES=s3://
3 | IMGPROXY_USE_S3=true
4 | IMGPROXY_S3_ENDPOINT=http://localhost:9000
5 | IMGPROXY_KEY=91bdcda48ce22cd7d8d3a0eda930b3db1762bc1cba5dc13542e723b68fe55d6f9d18199cbe35191a45faf22593405cad0fe76ffec67d24f8aee861ac8fe44d96
6 | IMGPROXY_SALT=72456c286761260f320391fe500fcec53755958dabd288867a6db072e1bc1dbd84b15079838a83a715edc1ecad50c3ce91dd8fdef6f981816fa274f91d8ecf06
7 | AWS_ACCESS_KEY_ID=minio_user
8 | AWS_SECRET_ACCESS_KEY=minio_password
--------------------------------------------------------------------------------
/.devcontainer/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Init minio
4 | minio-cli alias set myminio/ http://localhost:9000 minio_user minio_password
5 |
6 | # Init project
7 | nvm install
8 | nvm use
9 | nvm alias default $(node --version)
10 | nvm install-latest-npm
11 | npm i
12 |
--------------------------------------------------------------------------------
/.devcontainer/minio-dump/test-bucket/test-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitPatty/imgproxy-url-builder/0d6c9dd0c09d75c274a8ffb8949bfb64422fc266/.devcontainer/minio-dump/test-bucket/test-image.png
--------------------------------------------------------------------------------
/.devcontainer/minio-dump/test-bucket/test-image.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
87 |
--------------------------------------------------------------------------------
/.devcontainer/minio.env:
--------------------------------------------------------------------------------
1 | MINIO_ACCESS_KEY=minio_user
2 | MINIO_SECRET_KEY=minio_password
--------------------------------------------------------------------------------
/.devcontainer/test-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BitPatty/imgproxy-url-builder/0d6c9dd0c09d75c274a8ffb8949bfb64422fc266/.devcontainer/test-image.png
--------------------------------------------------------------------------------
/.devcontainer/workspace.env:
--------------------------------------------------------------------------------
1 | IMGPROXY_URL=http://localhost:4000
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | coverage/**
2 | dist/**
3 | scripts/**
4 | **/*.sh
5 | rollup.config.js
6 | populate-readme.cjs
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "env": {
4 | "node": true,
5 | "es6": true
6 | },
7 | "ignorePatterns": ["coverage/**", "dist/**", "scripts/**", "**/*.sh"],
8 | "extends": [
9 | "eslint:recommended",
10 | "plugin:@typescript-eslint/eslint-recommended",
11 | "plugin:@typescript-eslint/recommended",
12 | "plugin:jest/recommended",
13 | "plugin:prettier/recommended"
14 | ],
15 | "parser": "@typescript-eslint/parser",
16 | "parserOptions": {
17 | "project": "./tsconfig.json",
18 | "tsconfigRootDir": "./"
19 | },
20 | "plugins": ["@typescript-eslint", "jest", "prettier"],
21 | "rules": {
22 | "@typescript-eslint/explicit-function-return-type": [
23 | "error",
24 | {
25 | "allowExpressions": true,
26 | "allowConciseArrowFunctionExpressionsStartingWithVoid": true
27 | }
28 | ],
29 | "@typescript-eslint/no-floating-promises": ["error"],
30 | "@typescript-eslint/no-shadow": ["error"],
31 | "@typescript-eslint/explicit-member-accessibility": ["error"],
32 | "no-console": ["error"],
33 | "no-return-await": ["error"],
34 | "padding-line-between-statements": [
35 | "error",
36 | {
37 | "blankLine": "always",
38 | "prev": "*",
39 | "next": "function"
40 | }
41 | ],
42 | "prettier/prettier": [
43 | "error",
44 | {},
45 | {
46 | "usePrettierrc": true
47 | }
48 | ],
49 | "require-await": ["error"]
50 | },
51 | "overrides": [
52 | {
53 | "files": ["test/**/*.js"],
54 | "rules": {
55 | "@typescript-eslint/explicit-function-return-type": "off"
56 | }
57 | }
58 | ]
59 | }
60 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.css text eol=lf
2 | *.env text eol=lf
3 | *.js text eol=lf
4 | *.json text eol=lf
5 | *.lock text eol=lf
6 | *.md text eol=lf
7 | *.sh text eol=lf
8 | *.svg text eol=lf
9 | *.ts text eol=lf
10 | *.tsx text eol=lf
11 | *.yml text eol=lf
12 |
13 | # Dockerfiles
14 | *.Dockerfile text eol=lf
15 | Dockerfile text eol=lf
16 |
17 | # dotfiles
18 | .git* text eol=lf
19 | .npmignore text eol=lf
20 | .nvmrc text eol=lf
21 | .prettierrc text eol=lf
22 |
23 | # Binaries
24 | *.ico binary
25 | *.jpg binary
26 | *.png binary
27 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: 2
3 | updates:
4 | - package-ecosystem: npm
5 | directory: '/'
6 | schedule:
7 | interval: monthly
8 | open-pull-requests-limit: 5
9 | reviewers:
10 | - bitpatty
11 | labels:
12 | - dependencies
13 | groups:
14 | production-dependencies:
15 | dependency-type: 'production'
16 | development-dependencies:
17 | dependency-type: 'development'
18 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on: push
4 |
5 | jobs:
6 | build:
7 | if: github.repository_owner == 'bitpatty'
8 | name: Build Project
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - uses: actions/setup-node@v3
13 | with:
14 | node-version: '22.10.0'
15 | - run: npm install
16 | - run: npm run build
17 | - run: npm run test
18 | - name: Coveralls
19 | uses: coverallsapp/github-action@v1
20 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot-auto-merge.yml:
--------------------------------------------------------------------------------
1 | name: auto-merge
2 |
3 | on:
4 | pull_request:
5 |
6 | jobs:
7 | auto-merge:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v3
11 | - uses: ahmadnassri/action-dependabot-auto-merge@v2
12 | with:
13 | target: minor
14 | github-token: ${{ secrets.BOT_TOKEN }}
15 |
--------------------------------------------------------------------------------
/.github/workflows/publish-npm-package.yml:
--------------------------------------------------------------------------------
1 | name: Publish npm package
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | publish-github:
9 | if: github.repository_owner == 'bitpatty'
10 | name: Publish NPM package (GitHub Registry)
11 | runs-on: ubuntu-latest
12 | environment: github-registry
13 | permissions:
14 | contents: read
15 | packages: write
16 | steps:
17 | - uses: actions/checkout@v3
18 | - uses: actions/setup-node@v3
19 | with:
20 | node-version: '22.10.0'
21 | registry-url: 'https://npm.pkg.github.com'
22 | scope: '@bitpatty'
23 | - run: npm install
24 | - run: npm run build
25 | - run: echo "registry=https://npm.pkg.github.com/@bitpatty" >> .npmrc
26 | - run: npm publish
27 | env:
28 | NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 |
30 | publish-npmjs:
31 | if: github.repository_owner == 'bitpatty'
32 | name: Publish NPM package (npmjs.org)
33 | runs-on: ubuntu-latest
34 | environment: npm-registry
35 | steps:
36 | - uses: actions/checkout@v3
37 | - uses: actions/setup-node@v3
38 | with:
39 | node-version: '22.10.0'
40 | registry-url: 'https://registry.npmjs.org'
41 | - run: npm install
42 | - run: npm run build
43 | - run: npm publish --access=public
44 | env:
45 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | /index.js
4 | coverage
--------------------------------------------------------------------------------
/.ncurc.json:
--------------------------------------------------------------------------------
1 | {
2 | "reject": []
3 | }
4 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v22.10.0
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all",
4 | "printWidth": 80
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "[html]": {
3 | "editor.defaultFormatter": "esbenp.prettier-vscode"
4 | },
5 | "[javascript]": {
6 | "editor.defaultFormatter": "esbenp.prettier-vscode"
7 | },
8 | "[javascriptreact]": {
9 | "editor.defaultFormatter": "esbenp.prettier-vscode"
10 | },
11 | "[typescript]": {
12 | "editor.defaultFormatter": "esbenp.prettier-vscode"
13 | },
14 | "[typescriptreact]": {
15 | "editor.defaultFormatter": "esbenp.prettier-vscode"
16 | },
17 | "[json]": {
18 | "editor.quickSuggestions": {
19 | "strings": true
20 | },
21 | "editor.suggest.insertMode": "replace",
22 | "editor.defaultFormatter": "esbenp.prettier-vscode"
23 | },
24 | "files.autoSave": "off",
25 | "breadcrumbs.symbolSortOrder": "type",
26 | "coverage-gutters.coverageReportFileName": "coverage/**/index.html",
27 | "coverage-gutters.showLineCoverage": true,
28 | "editor.codeLens": true,
29 | "editor.detectIndentation": true,
30 | "editor.formatOnSave": true,
31 | "editor.minimap.maxColumn": 150,
32 | "editor.tabSize": 2,
33 | "explorer.confirmDragAndDrop": false,
34 | "files.associations": {
35 | "*.erb": "html",
36 | "*.html.erb": "html"
37 | },
38 | "git.confirmSync": false,
39 | "git.enableSmartCommit": true,
40 | "html.format.wrapLineLength": 150,
41 | "javascript.updateImportsOnFileMove.enabled": "always",
42 | "search.exclude": {
43 | "**/*.eot": true,
44 | "**/*.png": true,
45 | "**/*.svg": true,
46 | "**/*.ttf": true,
47 | "**/*.woff": true,
48 | "**/*.woff2": true,
49 | "**/.git": true,
50 | "**/bower_components": true,
51 | "**/dist/": true,
52 | "**/node_modules": true,
53 | "**/tmp": true,
54 | "**/docs/": true
55 | },
56 | "todohighlight.keywords": ["@TODO"],
57 | "typescript.preferences.importModuleSpecifier": "relative",
58 | "typescript.referencesCodeLens.enabled": true,
59 | "typescript.referencesCodeLens.showOnAllFunctions": true,
60 | "typescript.reportStyleChecksAsWarnings": true,
61 | "typescript.updateImportsOnFileMove.enabled": "always",
62 | "workbench.editor.enablePreview": false,
63 | "workbench.editor.enablePreviewFromQuickOpen": false,
64 | "cSpell.enabled": true,
65 | "cSpell.words": ["imgproxy", "rotr"],
66 | "cSpell.ignorePaths": [
67 | ".devcontainer",
68 | ".github",
69 | "docs",
70 | "package-lock.json",
71 | "node_modules",
72 | "vscode-extension",
73 | ".git/objects",
74 | ".vscode",
75 | ".vscode-insiders"
76 | ]
77 | }
78 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Matteias Collet and contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
--------------------------------------------------------------------------------
/docs/assets/highlight.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --light-hl-0: #795E26;
3 | --dark-hl-0: #DCDCAA;
4 | --light-hl-1: #000000;
5 | --dark-hl-1: #D4D4D4;
6 | --light-hl-2: #A31515;
7 | --dark-hl-2: #CE9178;
8 | --light-hl-3: #0000FF;
9 | --dark-hl-3: #569CD6;
10 | --light-hl-4: #AF00DB;
11 | --dark-hl-4: #C586C0;
12 | --light-hl-5: #001080;
13 | --dark-hl-5: #9CDCFE;
14 | --light-hl-6: #008000;
15 | --dark-hl-6: #6A9955;
16 | --light-hl-7: #098658;
17 | --dark-hl-7: #B5CEA8;
18 | --light-hl-8: #0070C1;
19 | --dark-hl-8: #4FC1FF;
20 | --light-code-background: #FFFFFF;
21 | --dark-code-background: #1E1E1E;
22 | }
23 |
24 | @media (prefers-color-scheme: light) { :root {
25 | --hl-0: var(--light-hl-0);
26 | --hl-1: var(--light-hl-1);
27 | --hl-2: var(--light-hl-2);
28 | --hl-3: var(--light-hl-3);
29 | --hl-4: var(--light-hl-4);
30 | --hl-5: var(--light-hl-5);
31 | --hl-6: var(--light-hl-6);
32 | --hl-7: var(--light-hl-7);
33 | --hl-8: var(--light-hl-8);
34 | --code-background: var(--light-code-background);
35 | } }
36 |
37 | @media (prefers-color-scheme: dark) { :root {
38 | --hl-0: var(--dark-hl-0);
39 | --hl-1: var(--dark-hl-1);
40 | --hl-2: var(--dark-hl-2);
41 | --hl-3: var(--dark-hl-3);
42 | --hl-4: var(--dark-hl-4);
43 | --hl-5: var(--dark-hl-5);
44 | --hl-6: var(--dark-hl-6);
45 | --hl-7: var(--dark-hl-7);
46 | --hl-8: var(--dark-hl-8);
47 | --code-background: var(--dark-code-background);
48 | } }
49 |
50 | :root[data-theme='light'] {
51 | --hl-0: var(--light-hl-0);
52 | --hl-1: var(--light-hl-1);
53 | --hl-2: var(--light-hl-2);
54 | --hl-3: var(--light-hl-3);
55 | --hl-4: var(--light-hl-4);
56 | --hl-5: var(--light-hl-5);
57 | --hl-6: var(--light-hl-6);
58 | --hl-7: var(--light-hl-7);
59 | --hl-8: var(--light-hl-8);
60 | --code-background: var(--light-code-background);
61 | }
62 |
63 | :root[data-theme='dark'] {
64 | --hl-0: var(--dark-hl-0);
65 | --hl-1: var(--dark-hl-1);
66 | --hl-2: var(--dark-hl-2);
67 | --hl-3: var(--dark-hl-3);
68 | --hl-4: var(--dark-hl-4);
69 | --hl-5: var(--dark-hl-5);
70 | --hl-6: var(--dark-hl-6);
71 | --hl-7: var(--dark-hl-7);
72 | --hl-8: var(--dark-hl-8);
73 | --code-background: var(--dark-code-background);
74 | }
75 |
76 | .hl-0 { color: var(--hl-0); }
77 | .hl-1 { color: var(--hl-1); }
78 | .hl-2 { color: var(--hl-2); }
79 | .hl-3 { color: var(--hl-3); }
80 | .hl-4 { color: var(--hl-4); }
81 | .hl-5 { color: var(--hl-5); }
82 | .hl-6 { color: var(--hl-6); }
83 | .hl-7 { color: var(--hl-7); }
84 | .hl-8 { color: var(--hl-8); }
85 | pre, code { background: var(--code-background); }
86 |
--------------------------------------------------------------------------------
/docs/assets/navigation.js:
--------------------------------------------------------------------------------
1 | window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA5XYXW/TMBQG4P+S64myic/dtRS2gQZl65gE4uIsOU1MHTuyna0Z4r+jfUDsxCfHu35fP2lqO43743fmcOeyw+zIQCFQuaUwmDuhVbaXNeCq7DBD1dZ2Nio8q1wts71sK1SRHb75s+db18J1667BiPIvosefoRW3GBveJ8xoocq5LLURrqqjiF+grQtlKzANKqHKU12MPs8wp6VLcGhqMNuVtiL2/Y4KtLUCA/WiFbJA0zO5BGvRzvw0NPYPfGVe/Gqt+9LcXcv2jOsatLMgDJWD529f77888KQF5NvS6FYVc9lUQJDxVrrNsqmibM0S3cMiptBIJ8Wd4FIVI8rKKbSWsoYFVrxbChTmZZzzDvIKF611SN3muMGaWjkD5CocxKxmdENJfcQpy9UJgfQJazTUd9QnrGHghlunsQ7rttpphZQYpJz1ftcIg9RSDVPecqiKuW0wd2fghCbVeC/Nn0QTpQ8g5RXk25MaSrwwkjCJGqsLiZ+hpiZoELOaNjVQ+ysI06SvLUjhukkw7HDukdgQWp+wxuPLCQWFcYJ2Td9jmHLWMdjKtjVhhSlnfWywJCAv4pRT2C06R27aQcxqQh3j3S8SxQ3yBO9SFK6iOT9mNa10XhlN7qZRgRNXUBRCUdMQprxVUp/Li1hF7FCCI6UwZjX63tLvy6BFakEEISdNP22e9px5ODsQVBAmSf4BYgqN9FhfO5j40R/EnHYOrjVT3qjAig9nHooLUtbaimZldI7W0tsqWmJl10lquv2Mc9ZGUBPsRZzinxQJLVLh1G+iQL2u2vpKgZCfsNsYqMlH+3T7adc6x1yTb1MT1addZS3IKSSL3BX+H7QJeJgne+cVFPqGU4NWuk0/umKdZHeNO+pBHesku/RbcaTCqd+1pnagF3FKXoHw/nXZtOr+1GRn90E4+tULb2CBG2iliw19jEaDf/4FX4DUo1kTAAA="
--------------------------------------------------------------------------------
/docs/types/BlurOptions.html:
--------------------------------------------------------------------------------
1 |
BlurOptions | @bitpatty/imgproxy-url-builder
3 |
--------------------------------------------------------------------------------
/docs/types/BrightnessOptions.html:
--------------------------------------------------------------------------------
1 | BrightnessOptions | @bitpatty/imgproxy-url-builderType Alias BrightnessOptions
BrightnessOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/CacheBusterOptions.html:
--------------------------------------------------------------------------------
1 | CacheBusterOptions | @bitpatty/imgproxy-url-builderType Alias CacheBusterOptions
CacheBusterOptions: string
3 |
--------------------------------------------------------------------------------
/docs/types/ContrastOptions.html:
--------------------------------------------------------------------------------
1 | ContrastOptions | @bitpatty/imgproxy-url-builderType Alias ContrastOptions
ContrastOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/DPIOptions.html:
--------------------------------------------------------------------------------
1 | DPIOptions | @bitpatty/imgproxy-url-builder
3 |
--------------------------------------------------------------------------------
/docs/types/DprOptions.html:
--------------------------------------------------------------------------------
1 | DprOptions | @bitpatty/imgproxy-url-builder
3 |
--------------------------------------------------------------------------------
/docs/types/FileNameOptions.html:
--------------------------------------------------------------------------------
1 | FileNameOptions | @bitpatty/imgproxy-url-builderType Alias FileNameOptions
FileNameOptions: string
3 |
--------------------------------------------------------------------------------
/docs/types/MaxBytesOptions.html:
--------------------------------------------------------------------------------
1 | MaxBytesOptions | @bitpatty/imgproxy-url-builderType Alias MaxBytesOptions
MaxBytesOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/MinHeightOptions.html:
--------------------------------------------------------------------------------
1 | MinHeightOptions | @bitpatty/imgproxy-url-builderType Alias MinHeightOptions
MinHeightOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/MinWidthOptions.html:
--------------------------------------------------------------------------------
1 | MinWidthOptions | @bitpatty/imgproxy-url-builderType Alias MinWidthOptions
MinWidthOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/PageOptions.html:
--------------------------------------------------------------------------------
1 | PageOptions | @bitpatty/imgproxy-url-builder
3 |
--------------------------------------------------------------------------------
/docs/types/PixelateOptions.html:
--------------------------------------------------------------------------------
1 | PixelateOptions | @bitpatty/imgproxy-url-builderType Alias PixelateOptions
PixelateOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/QualityOptions.html:
--------------------------------------------------------------------------------
1 | QualityOptions | @bitpatty/imgproxy-url-builderType Alias QualityOptions
QualityOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/SharpenOptions.html:
--------------------------------------------------------------------------------
1 | SharpenOptions | @bitpatty/imgproxy-url-builderType Alias SharpenOptions
SharpenOptions: number
3 |
--------------------------------------------------------------------------------
/docs/types/WatermarkTextOptions.html:
--------------------------------------------------------------------------------
1 | WatermarkTextOptions | @bitpatty/imgproxy-url-builderType Alias WatermarkTextOptions
WatermarkTextOptions: string
3 |
--------------------------------------------------------------------------------
/docs/types/WatermarkUrlOptions.html:
--------------------------------------------------------------------------------
1 | WatermarkUrlOptions | @bitpatty/imgproxy-url-builderType Alias WatermarkUrlOptions
WatermarkUrlOptions: string
3 |
--------------------------------------------------------------------------------
/jest.config.ts:
--------------------------------------------------------------------------------
1 | import type { JestConfigWithTsJest } from 'ts-jest';
2 |
3 | export default (): JestConfigWithTsJest => {
4 | return {
5 | preset: 'ts-jest',
6 | testEnvironment: 'node',
7 | coverageReporters: ['lcov', 'html', 'json'],
8 | setupFilesAfterEnv: ['./jest.setup.ts'],
9 | verbose: true,
10 | testMatch: ['**/*.test.ts'],
11 | extensionsToTreatAsEsm: ['.ts'],
12 | moduleNameMapper: {
13 | '^(\\.{1,2}/.*)\\.js$': '$1',
14 | },
15 | transform: {
16 | '^.+\\.tsx?$': [
17 | 'ts-jest',
18 | {
19 | tsconfig: 'tsconfig.json',
20 | useESM: true,
21 | },
22 | ],
23 | },
24 | };
25 | };
26 |
--------------------------------------------------------------------------------
/jest.globals.ts:
--------------------------------------------------------------------------------
1 | const jestGlobals = {
2 | buildOptions: {
3 | signature: {
4 | key: '91bdcda48ce22cd7d8d3a0eda930b3db1762bc1cba5dc13542e723b68fe55d6f9d18199cbe35191a45faf22593405cad0fe76ffec67d24f8aee861ac8fe44d96',
5 | salt: '72456c286761260f320391fe500fcec53755958dabd288867a6db072e1bc1dbd84b15079838a83a715edc1ecad50c3ce91dd8fdef6f981816fa274f91d8ecf06',
6 | },
7 | baseUrl: 'http://localhost:4000',
8 | path: 's3://test-bucket/test-image.png',
9 | },
10 | };
11 |
12 | export default jestGlobals;
13 |
--------------------------------------------------------------------------------
/jest.setup.ts:
--------------------------------------------------------------------------------
1 | import { ParamBuilder } from './src/index.js';
2 |
3 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4 | // @ts-ignore
5 | declare global {
6 | // eslint-disable-next-line @typescript-eslint/no-namespace
7 | namespace jest {
8 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
9 | interface Matchers {
10 | toIncludeModifier(str: string): jest.CustomMatcherResult;
11 | toIncludeModifierIdentifier(
12 | keyof: keyof ParamBuilder,
13 | ): jest.CustomMatcherResult;
14 | }
15 | }
16 | }
17 |
18 | expect.extend({
19 | toIncludeModifier(
20 | received: ParamBuilder,
21 | expected: string,
22 | ): jest.CustomMatcherResult {
23 | const values = Array.from(received.modifiers.values());
24 | const hasValue = values.includes(expected);
25 |
26 | return {
27 | pass: hasValue,
28 | message: () =>
29 | hasValue
30 | ? ''
31 | : `Could not find modifier "${expected}" in ${JSON.stringify(
32 | values,
33 | )} `,
34 | };
35 | },
36 |
37 | toIncludeModifierIdentifier(
38 | received: ParamBuilder,
39 | expected: keyof ParamBuilder,
40 | ): jest.CustomMatcherResult {
41 | const values = Array.from(received.modifiers.keys());
42 | const hasValue = values.includes(expected);
43 |
44 | return {
45 | pass: hasValue,
46 | message: () =>
47 | hasValue
48 | ? ''
49 | : `Could not find modifier identifier "${expected}" in ${JSON.stringify(
50 | values,
51 | )} `,
52 | };
53 | },
54 | });
55 |
56 | export default undefined;
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bitpatty/imgproxy-url-builder",
3 | "version": "2.0.0-rc1",
4 | "description": "A TypeScript helper library for building imgproxy URLs",
5 | "author": "Matteias Collet ",
6 | "contributors": [
7 | {
8 | "name": "Coo van Leeuwen",
9 | "url": "https://github.com/c00"
10 | },
11 | {
12 | "name": "Ushakov Fedor",
13 | "url": "https://github.com/ushakovfserg"
14 | }
15 | ],
16 | "type": "module",
17 | "main": "dist/cjs/index.js",
18 | "module": "dist/esm/index.js",
19 | "types": "dist/types/index.d.ts",
20 | "exports": {
21 | ".": {
22 | "import": "./dist/esm/index.js",
23 | "require": "./dist/cjs/index.js",
24 | "types": "./dist/types/index.d.ts"
25 | }
26 | },
27 | "scripts": {
28 | "prebuild": "rm -rf dist",
29 | "build": "rollup -c",
30 | "test": "jest --verbose --coverage",
31 | "docs": "typedoc && node scripts/populate-readme.cjs",
32 | "deps:force-upgrade": "npm-check-updates -u && rm -rf node_modules && rm -f package-lock.json && npm i"
33 | },
34 | "keywords": [
35 | "imgproxy",
36 | "imgproxyjs",
37 | "browser",
38 | "node"
39 | ],
40 | "repository": {
41 | "type": "git",
42 | "url": "https://github.com/BitPatty/imgproxy-url-builder.git"
43 | },
44 | "license": "MIT",
45 | "bugs": {
46 | "url": "https://github.com/BitPatty/imgproxy-url-builder/issues"
47 | },
48 | "files": [
49 | "dist"
50 | ],
51 | "homepage": "https://github.com/BitPatty/imgproxy-url-builder#readme",
52 | "devDependencies": {
53 | "@types/jest": "29.5.14",
54 | "@types/node": "22.15.3",
55 | "@typescript-eslint/eslint-plugin": "8.31.1",
56 | "@typescript-eslint/parser": "8.31.1",
57 | "crypto-js": "4.2.0",
58 | "eslint": "9.25.1",
59 | "eslint-config-prettier": "10.1.2",
60 | "eslint-plugin-jest": "28.11.0",
61 | "eslint-plugin-prettier": "5.2.6",
62 | "npm-check-updates": "18.0.1",
63 | "prettier": "3.5.3",
64 | "rollup": "4.40.1",
65 | "rollup-plugin-typescript2": "0.36.0",
66 | "ts-jest": "29.3.2",
67 | "ts-node": "10.9.2",
68 | "tslib": "2.8.1",
69 | "typedoc": "0.28.3",
70 | "typescript": "5.8.3"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import pkg from './package.json' with { type: 'json' };
2 |
3 | import fs from 'fs';
4 | import path, { dirname } from 'path';
5 | import { fileURLToPath } from 'url';
6 |
7 | import typescript from 'rollup-plugin-typescript2';
8 |
9 | const __dirname = dirname(fileURLToPath(import.meta.url));
10 |
11 | const createPackageJson = {
12 | writeBundle: (opts) => {
13 | if (!['es', 'cjs'].includes(opts.format) || opts.file === pkg.types) return;
14 | const dirName = path.join(__dirname, path.dirname(opts.file));
15 | const output = JSON.stringify({
16 | type: opts.format === 'es' ? 'module' : 'commonjs',
17 | });
18 | fs.writeFileSync(path.join(dirName, 'package.json'), output);
19 | },
20 | };
21 |
22 | export default {
23 | input: 'src/index.ts',
24 | output: [
25 | {
26 | file: pkg.main,
27 | format: 'cjs',
28 | exports: 'named',
29 | sourcemap: true,
30 | strict: true,
31 | compact: false,
32 | },
33 | {
34 | file: pkg.module,
35 | format: 'es',
36 | exports: 'named',
37 | sourcemap: true,
38 | strict: true,
39 | compact: false,
40 | },
41 | ],
42 | plugins: [
43 | typescript({
44 | tsconfig: 'tsconfig.build.json',
45 | useTsconfigDeclarationDir: true,
46 | tsconfigOverride: {
47 | compilerOptions: {
48 | declaration: true,
49 | declarationDir: dirname(pkg.types),
50 | },
51 | },
52 | }),
53 | createPackageJson,
54 | ],
55 | external: [],
56 | };
57 |
--------------------------------------------------------------------------------
/scripts/micro-benchmark.cjs:
--------------------------------------------------------------------------------
1 | const crypto = require('crypto');
2 | const { performance } = require('perf_hooks');
3 | const CryptoJS = require('crypto-js');
4 | const { hmac } = require('../dist/cjs');
5 |
6 | // Configuration for the benchmark
7 | const message = 'Benchmarking HMAC performance';
8 | const key = 'supersecretkey';
9 | const initialIterations = 1000;
10 | const maxIterations = 100000;
11 | const incrementFactor = 10;
12 |
13 | // Node.js native HMAC implementation
14 | function nativeHmac(key, message) {
15 | return crypto.createHmac('sha256', key).update(message).digest('hex');
16 | }
17 |
18 | // CryptoJS HMAC implementation
19 | function cryptoJsHmac(key, message) {
20 | return CryptoJS.HmacSHA256(message, key).toString(CryptoJS.enc.Hex);
21 | }
22 |
23 | // Benchmark function to measure execution time
24 | function benchmark(label, func, iterations) {
25 | const start = performance.now();
26 | for (let i = 0; i < iterations; i++) {
27 | func();
28 | }
29 | const end = performance.now();
30 | console.log(
31 | `${label} took ${(end - start).toFixed(2)} ms for ${iterations} iterations`,
32 | );
33 | }
34 |
35 | // Ensure the key and message are in Uint8Array format for the
36 | // custom HMAC function
37 | const keyBytes = new Uint8Array(Buffer.from(key, 'utf-8'));
38 | const messageBytes = new Uint8Array(Buffer.from(message, 'utf-8'));
39 |
40 | console.log('Starting HMAC performance comparison:');
41 | for (
42 | let iterations = initialIterations;
43 | iterations <= maxIterations;
44 | iterations *= incrementFactor
45 | ) {
46 | console.log(`\nRunning ${iterations} iterations:`);
47 |
48 | benchmark('Node Native HMAC', () => nativeHmac(key, message), iterations);
49 | benchmark('CryptoJS HMAC', () => cryptoJsHmac(key, message), iterations);
50 | benchmark(
51 | 'Custom HMAC Implementation',
52 | () => hmac(keyBytes, messageBytes),
53 | iterations,
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/scripts/minio-dump.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | SCRIPT_PATH=$(dirname "$0")
4 | echo "Dumping minio files"
5 | cd $SCRIPT_PATH/..
6 | minio-cli cp --recursive myminio ./.devcontainer/minio-dump
--------------------------------------------------------------------------------
/scripts/minio-restore.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | SCRIPT_PATH=$(dirname "$0")
4 | echo "Restoring minio files"
5 | cd $SCRIPT_PATH/../.devcontainer/minio-dump
6 | minio-cli mb --ignore-existing myminio/test-bucket
7 | minio-cli rm --recursive --force myminio/test-bucket || true
8 | minio-cli cp --recursive . myminio
--------------------------------------------------------------------------------
/scripts/populate-readme.cjs:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const pbLines = fs
5 | .readFileSync(path.join(__dirname, '..', 'src', 'param-builder.ts'))
6 | .toString()
7 | .split('\n');
8 |
9 | const readmeLines = fs
10 | .readFileSync(path.join(__dirname, '..', 'README.md'))
11 | .toString()
12 | .split('\n');
13 |
14 | const comments = [];
15 | let currentComment = null;
16 |
17 | for (let i = 0; i < pbLines.length; i++) {
18 | if (currentComment && pbLines[i].includes('*/')) {
19 | comments.push(currentComment);
20 | currentComment = null;
21 | continue;
22 | }
23 |
24 | if (currentComment == null && pbLines[i].includes('/*')) {
25 | currentComment = pbLines[i];
26 | continue;
27 | }
28 |
29 | if (currentComment != null) {
30 | currentComment += `\n${pbLines[i]}`;
31 | }
32 | }
33 |
34 | const commentsWithExamples = comments.filter((c) => c.includes('@example'));
35 |
36 | const transformers = [];
37 |
38 | for (let i = 0; i < commentsWithExamples.length; i++) {
39 | const textLines = commentsWithExamples[i]
40 | .split('\n')
41 | .map((l) => l.trim().replace(/^[/*]+ {0,1}/, ''));
42 |
43 | let mode = 'description';
44 | let description = '';
45 | let example = '';
46 | let url = '';
47 | let functionName = '';
48 |
49 | for (let j = 0; j < textLines.length; j++) {
50 | if (
51 | textLines[j].trim().startsWith('See https://github.com/imgproxy/imgproxy')
52 | ) {
53 | mode = 'link';
54 | } else if (textLines[j].startsWith('@example')) {
55 | mode = 'example';
56 | } else if (mode !== 'description') {
57 | continue;
58 | }
59 |
60 | switch (mode) {
61 | case 'description':
62 | description += ` ${textLines[j]}`;
63 | break;
64 | case 'link':
65 | url = textLines[j].replace(/^.+(https\:\/\/[^ ]+).+$/, '$1');
66 | break;
67 | case 'example':
68 | for (let k = j + 1; k < textLines.length; k++) {
69 | if (k !== j + 1 && textLines[k].includes('```')) {
70 | example += '\n```';
71 | break;
72 | }
73 |
74 | if (!functionName && k >= j + 2 && textLines[k].startsWith('pb()')) {
75 | functionName = textLines[k].replace(/^pb\(\)\.([^(]+).+$/, '$1');
76 | }
77 |
78 | example += `\n${textLines[k]}`;
79 | }
80 | }
81 | }
82 |
83 | if (description && url && example && functionName)
84 | transformers.push({ description, url, example, functionName });
85 | }
86 |
87 | const sortedTransformers = transformers.sort((a, b) =>
88 | a.functionName.trim().toLowerCase() < b.functionName.trim().toLowerCase()
89 | ? -1
90 | : 1,
91 | );
92 |
93 | const toc = [];
94 | const markdown = [];
95 | for (let i = 0; i < sortedTransformers.length; i++) {
96 | toc.push(
97 | `- [${sortedTransformers[i].functionName}](#${sortedTransformers[
98 | i
99 | ].functionName.toLowerCase()}-imgproxy-docs)`,
100 | );
101 | markdown.push('');
102 | markdown.push(
103 | `### ${sortedTransformers[i].functionName} ([imgproxy docs](${sortedTransformers[i].url}))`,
104 | );
105 | markdown.push('');
106 | markdown.push(sortedTransformers[i].description.trim());
107 | markdown.push('');
108 | markdown.push('#### Example');
109 | markdown.push('');
110 | markdown.push(sortedTransformers[i].example.trim());
111 | }
112 |
113 | let newReadme = [];
114 |
115 | for (let i = 0; i < readmeLines.length; i++) {
116 | newReadme.push(readmeLines[i]);
117 |
118 | if (readmeLines[i].startsWith('## Modifiers')) {
119 | break;
120 | }
121 | }
122 |
123 | newReadme.push('');
124 | newReadme.push(...toc);
125 | newReadme.push(...markdown);
126 |
127 | fs.writeFileSync('README.md', newReadme.join('\n'));
128 |
--------------------------------------------------------------------------------
/src/common.ts:
--------------------------------------------------------------------------------
1 | import { base64urlEncode, parseHexString, utf8encode } from './crypto/codec.js';
2 | import { wordArrayToByteArray } from './crypto/common.js';
3 | import { hmac } from './crypto/hmac.js';
4 |
5 | /**
6 | * Stringifies the imgproxy modifier for use within the
7 | * imgproxy URL.
8 | *
9 | * @param opCode The operation key
10 | * @param values The values
11 | * @returns The stringified modifier
12 | */
13 | const stringifyOptions = (
14 | opCode: string,
15 | values: Array,
16 | ): string => {
17 | return [
18 | opCode,
19 | ...values.map((v) => (v == null ? '' : encodeURIComponent(v))),
20 | ]
21 | .join(':')
22 | .replace(/:+$/, '');
23 | };
24 |
25 | /**
26 | * Encodes the filepath to base64url.
27 | *
28 | * @param filePath The file path
29 | * @returns The base64url encoded file path
30 | */
31 | const encodeFilePath = (filePath: string): string => {
32 | return base64urlEncode(utf8encode(filePath));
33 | };
34 |
35 | /**
36 | * Generates the URL signature for the specified imgproxy param string.
37 | *
38 | * See https://github.com/imgproxy/imgproxy/blob/947d65cf29fe26e5e4d38ca8a17e44c7402e437c/docs/configuration.md#url-signature
39 | *
40 | * @param paramString The param string
41 | * @param key The hex-encoded key
42 | * @param salt The hex-encoded salt
43 | * @param length The number of bytes to use for the signature before encoding to Base64
44 | * @returns The base64url encoded signature
45 | */
46 | const generateSignature = (
47 | paramString: string,
48 | key: string,
49 | salt: string,
50 | length: number,
51 | ): string => {
52 | const path = paramString.startsWith('/') ? paramString : `/${paramString}`;
53 |
54 | // Parse key and salt from hex and ensure they're Uint8Array
55 | const keyBytes = parseHexString(key);
56 | const saltBytes = parseHexString(salt);
57 |
58 | // Create HMAC using the key and the combination of salt and path
59 | const h = hmac(keyBytes, new Uint8Array([...saltBytes, ...utf8encode(path)]));
60 |
61 | // Convert the HMAC output (Uint32Array) into a byte array (Uint8Array)
62 | const truncated = wordArrayToByteArray(h).slice(0, length);
63 |
64 | // Return the base64url-encoded signature
65 | return base64urlEncode(truncated);
66 | };
67 |
68 | export { stringifyOptions, encodeFilePath, generateSignature };
69 |
--------------------------------------------------------------------------------
/src/crypto/codec.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Masks the lowest 6 bits of the specified number
3 | *
4 | * @param num The number
5 | * @returns The lowest 6 bits
6 | */
7 | const low6 = (num: number): number => num & 0b0011_1111;
8 |
9 | /**
10 | * UTF-8 encodes the specified message
11 | *
12 | * @param msg The message
13 | * @returns The encoded message as a Uint8Array of bytes
14 | */
15 | const utf8encode = (msg: string): Uint8Array => {
16 | const encoder = new TextEncoder();
17 | return encoder.encode(msg);
18 | };
19 |
20 | /**
21 | * Parses a hex character and returns its numeric value
22 | *
23 | * @param char The hex char
24 | * @returns The numeric value
25 | */
26 | const parseHexChar = (char: string): number => {
27 | if (['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(char))
28 | return +char;
29 | switch (char.toUpperCase()) {
30 | case 'A':
31 | return 0xa;
32 | case 'B':
33 | return 0xb;
34 | case 'C':
35 | return 0xc;
36 | case 'D':
37 | return 0xd;
38 | case 'E':
39 | return 0xe;
40 | case 'F':
41 | return 0xf;
42 | }
43 |
44 | throw new Error(`Invalid hex char: ${char}`);
45 | };
46 |
47 | /**
48 | * Parses a string containing hex characters
49 | * into an array of bytes
50 | *
51 | * @param str The string
52 | * @returns The Uint8Array of parsed bytes
53 | */
54 | const parseHexString = (str: string): Uint8Array => {
55 | const res = new Uint8Array(Math.ceil(str.length / 2));
56 |
57 | for (let i = 0; i < str.length; i += 2) {
58 | res[i / 2] = (parseHexChar(str[i]) << 4) | parseHexChar(str[i + 1] || '0');
59 | }
60 |
61 | return res;
62 | };
63 |
64 | /**
65 | * Encodes the lowest 6 bits of the specified
66 | * number to its base64url representation
67 | *
68 | * @param b The number
69 | * @returns The base64url encoded character
70 | */
71 | const base64urlChar = (b: number): string => {
72 | const r = low6(b);
73 |
74 | // Uppercase letters
75 | if (r <= 25) return String.fromCharCode(65 + r);
76 | // Lowercase letters
77 | if (r <= 51) return String.fromCharCode(97 + r - 26);
78 | // Numbers
79 | if (r <= 61) return String.fromCharCode(48 + r - 52);
80 | // Base64 URL replacements for '+' and '/'
81 | return r === 62 ? '-' : '_';
82 | };
83 |
84 | /**
85 | * Encodes the specified array of bytes to
86 | * its base64url representation
87 | *
88 | * @param bytes The Uint8Array of bytes
89 | * @returns The base64url string
90 | */
91 | const base64urlEncode = (bytes: Uint8Array): string => {
92 | let res = '';
93 |
94 | for (let i = 0; i < bytes.length; i += 3) {
95 | // First byte
96 | res += base64urlChar(bytes[i] >>> 2);
97 | // Second byte
98 | res += base64urlChar(((bytes[i] & 0b11) << 4) | (bytes[i + 1] >>> 4));
99 | // Handle cases where fewer than 3 bytes are available
100 | if (i + 1 < bytes.length) {
101 | res += base64urlChar(
102 | ((bytes[i + 1] & 0b1111) << 2) | (bytes[i + 2] >>> 6),
103 | );
104 | if (i + 2 < bytes.length) {
105 | res += base64urlChar(bytes[i + 2] & 0b0011_1111);
106 | }
107 | }
108 | }
109 |
110 | return res;
111 | };
112 |
113 | export { utf8encode, base64urlEncode, parseHexString };
114 |
--------------------------------------------------------------------------------
/src/crypto/common.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * The block size used for hashing functions
3 | */
4 | const BLOCK_SIZE = 512;
5 |
6 | /**
7 | * Converts a word array (Uint32Array) into a byte array (Uint8Array)
8 | *
9 | * @param wordArray The Uint32Array
10 | * @returns The Uint8Array
11 | */
12 | const wordArrayToByteArray = (wordArray: Uint32Array): Uint8Array => {
13 | const byteArray = new Uint8Array(wordArray.length * 4);
14 | for (let i = 0; i < wordArray.length; i++) {
15 | byteArray[i * 4] = (wordArray[i] >>> 24) & 0xff;
16 | byteArray[i * 4 + 1] = (wordArray[i] >>> 16) & 0xff;
17 | byteArray[i * 4 + 2] = (wordArray[i] >>> 8) & 0xff;
18 | byteArray[i * 4 + 3] = wordArray[i] & 0xff;
19 | }
20 | return byteArray;
21 | };
22 |
23 | /**
24 | * Converts a byte array (Uint8Array) into a word array (Uint32Array)
25 | *
26 | * @param byteArray The Uint8Array
27 | * @returns The Uint32Array
28 | */
29 | const byteArrayToWordArray = (byteArray: Uint8Array): Uint32Array => {
30 | const wordArray = new Uint32Array(byteArray.length / 4);
31 | for (let i = 0; i < wordArray.length; i++) {
32 | wordArray[i] =
33 | (byteArray[i * 4] << 24) |
34 | (byteArray[i * 4 + 1] << 16) |
35 | (byteArray[i * 4 + 2] << 8) |
36 | byteArray[i * 4 + 3];
37 | }
38 | return wordArray;
39 | };
40 |
41 | export { BLOCK_SIZE, wordArrayToByteArray, byteArrayToWordArray };
42 |
--------------------------------------------------------------------------------
/src/crypto/hmac.ts:
--------------------------------------------------------------------------------
1 | import { sha256 } from './sha256.js';
2 | import { BLOCK_SIZE, wordArrayToByteArray } from './common.js';
3 |
4 | /**
5 | * Pads the specified byte-array to the block size.
6 | *
7 | * @param arr The Uint8Array
8 | * @param val The value to pad the array with
9 | * @returns The padded Uint8Array
10 | */
11 | const blockPad = (arr: Uint8Array, val = 0): Uint8Array => {
12 | const paddingSize = BLOCK_SIZE / 8 - arr.length;
13 | const paddedArray = new Uint8Array(arr.length + paddingSize);
14 | paddedArray.set(arr);
15 | if (val !== 0) {
16 | paddedArray.fill(val, arr.length);
17 | }
18 | return paddedArray;
19 | };
20 |
21 | /**
22 | * Gets the block-padded key.
23 | * If the key is longer than the block size, it is hashed using SHA-256.
24 | * If the key is shorter, it is padded to the block size.
25 | *
26 | * @param keyBytes The key as a Uint8Array
27 | * @returns The block-padded key
28 | */
29 | const getBlockKey = (keyBytes: Uint8Array): Uint8Array => {
30 | // If key is exactly BLOCK_SIZE (512 bits), return as is.
31 | if (keyBytes.length === BLOCK_SIZE / 8) return keyBytes;
32 |
33 | // If key is longer than BLOCK_SIZE, hash it and use that as the key.
34 | if (keyBytes.length > BLOCK_SIZE / 8)
35 | return blockPad(wordArrayToByteArray(sha256(keyBytes)));
36 |
37 | // Otherwise, pad the key to the block size.
38 | return blockPad(keyBytes);
39 | };
40 |
41 | /**
42 | * Creates the HMAC of the specified message.
43 | * Combines the key and message using inner and outer padding and returns the final HMAC as a Uint32Array.
44 | *
45 | * @param key The key (Uint8Array)
46 | * @param message The message (Uint8Array)
47 | * @returns The HMAC as a Uint32Array
48 | */
49 | const hmac = (key: Uint8Array, message: Uint8Array): Uint32Array => {
50 | const bK = getBlockKey(key); // Get block-padded key
51 |
52 | // Initialize inner and outer padding
53 | const oPad = new Uint8Array(bK.length);
54 | const iPad = new Uint8Array(bK.length);
55 |
56 | // XOR the key with 0x36 for iPad and 0x5c for oPad
57 | for (let i = 0; i < bK.length; i++) {
58 | oPad[i] = bK[i] ^ 0x5c;
59 | iPad[i] = bK[i] ^ 0x36;
60 | }
61 |
62 | // Perform inner hash: H( K ⊕ ipad || message )
63 | const innerHash = sha256(new Uint8Array([...iPad, ...message]));
64 |
65 | // Perform outer hash: H( K ⊕ opad || innerHash )
66 | return sha256(new Uint8Array([...oPad, ...wordArrayToByteArray(innerHash)]));
67 | };
68 |
69 | export { hmac };
70 |
--------------------------------------------------------------------------------
/src/crypto/sha256.ts:
--------------------------------------------------------------------------------
1 | import { BLOCK_SIZE, byteArrayToWordArray } from './common.js';
2 |
3 | // Constants
4 | const HASH_VALUES: Uint32Array = new Uint32Array([
5 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
6 | 0x1f83d9ab, 0x5be0cd19,
7 | ]);
8 |
9 | const ROUND_CONSTANTS: Uint32Array = new Uint32Array([
10 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
11 | 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
12 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
13 | 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
14 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
15 | 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
16 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
17 | 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
18 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
19 | 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
20 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
21 | ]);
22 |
23 | /**
24 | * Rotates the word right by the specified number of bits
25 | *
26 | * @param word The word
27 | * @param cnt The number of rotations
28 | * @returns The rotated word
29 | */
30 | const rotr = (word: number, cnt: number): number => {
31 | return (word >>> cnt) | (word << (32 - cnt));
32 | };
33 |
34 | /**
35 | * Prepares the message for chunking
36 | *
37 | * @param bytes The message bytes
38 | * @returns The padded message (32-bit word array)
39 | */
40 | const prepareMessage = (bytes: Uint8Array): Uint32Array => {
41 | const msgLen = bytes.length * 8;
42 | const totalLen = Math.ceil((msgLen + 65) / BLOCK_SIZE) * (BLOCK_SIZE / 8);
43 | const paddedMessage = new Uint8Array(totalLen);
44 |
45 | // Copy original bytes
46 | paddedMessage.set(bytes);
47 |
48 | // Append '1' bit
49 | paddedMessage[bytes.length] = 0b1000_0000;
50 |
51 | // Append the length of the message in bits (as 64-bit big-endian)
52 | const lenBytes = new DataView(new ArrayBuffer(8));
53 | lenBytes.setUint32(4, msgLen); // Only the lower 32 bits (since we're not hashing files > 4GB)
54 |
55 | paddedMessage.set(new Uint8Array(lenBytes.buffer), totalLen - 8);
56 |
57 | // Convert the byte array to 32-bit word array
58 | return byteArrayToWordArray(paddedMessage);
59 | };
60 |
61 | /**
62 | * Processes a single chunk (512-bit block) of the message
63 | *
64 | * @param chunk The chunk (32-bit word array)
65 | * @param hv The current hash value
66 | * @returns The updated hash value
67 | */
68 | const processChunk = (chunk: Uint32Array, hv: Uint32Array): Uint32Array => {
69 | const w = new Uint32Array(64);
70 | w.set(chunk);
71 |
72 | // Extend the message schedule array
73 | for (let i = 16; i < 64; i++) {
74 | const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
75 | const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
76 | w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;
77 | }
78 |
79 | // Initialize working variables
80 | let [a, b, c, d, e, f, g, h] = hv;
81 |
82 | // Compression function main loop
83 | for (let i = 0; i < 64; i++) {
84 | const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
85 | const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
86 | const ch = (e & f) ^ (~e & g);
87 | const maj = (a & b) ^ (a & c) ^ (b & c);
88 |
89 | const temp1 = (h + s1 + ch + ROUND_CONSTANTS[i] + w[i]) >>> 0;
90 | const temp2 = (s0 + maj) >>> 0;
91 |
92 | h = g;
93 | g = f;
94 | f = e;
95 | e = (d + temp1) >>> 0;
96 | d = c;
97 | c = b;
98 | b = a;
99 | a = (temp1 + temp2) >>> 0;
100 | }
101 |
102 | // Add the compressed chunk to the current hash value
103 | hv[0] = (hv[0] + a) >>> 0;
104 | hv[1] = (hv[1] + b) >>> 0;
105 | hv[2] = (hv[2] + c) >>> 0;
106 | hv[3] = (hv[3] + d) >>> 0;
107 | hv[4] = (hv[4] + e) >>> 0;
108 | hv[5] = (hv[5] + f) >>> 0;
109 | hv[6] = (hv[6] + g) >>> 0;
110 | hv[7] = (hv[7] + h) >>> 0;
111 |
112 | return hv;
113 | };
114 |
115 | /**
116 | * Calculates the SHA256 of the specified byte array
117 | *
118 | * @param bytes The Uint8Array of the byte array
119 | * @returns The SHA256 as a Uint32Array
120 | */
121 | const sha256 = (bytes: Uint8Array): Uint32Array => {
122 | const message = prepareMessage(bytes);
123 | let hash = new Uint32Array(HASH_VALUES); // Copy of initial hash values
124 |
125 | // Process each 512-bit chunk
126 | for (let i = 0; i < message.length; i += 16) {
127 | const chunk = message.subarray(i, i + 16);
128 | hash = processChunk(chunk, hash);
129 | }
130 |
131 | return hash;
132 | };
133 |
134 | export { sha256 };
135 |
--------------------------------------------------------------------------------
/src/enums/gradient-direction.enum.ts:
--------------------------------------------------------------------------------
1 | enum GradientDirection {
2 | UP = 'up',
3 | DOWN = 'down',
4 | LEFT = 'left',
5 | RIGHT = 'RIGHT',
6 | }
7 |
8 | export default GradientDirection;
9 |
--------------------------------------------------------------------------------
/src/enums/gravity-type.enum.ts:
--------------------------------------------------------------------------------
1 | enum GravityType {
2 | NORTH = 'no',
3 | SOUTH = 'so',
4 | EAST = 'ea',
5 | WEST = 'we',
6 | NORTHEAST = 'noea',
7 | NORTHWEST = 'nowe',
8 | SOUTHEAST = 'soea',
9 | SOUTHWEST = 'sowe',
10 | CENTER = 'ce',
11 | SMART = 'sm',
12 | FOCUS_POINT = 'fp',
13 | }
14 |
15 | export default GravityType;
16 |
--------------------------------------------------------------------------------
/src/enums/hashsum-type.enum.ts:
--------------------------------------------------------------------------------
1 | enum HashsumType {
2 | NONE = 'none',
3 | MD5 = 'md5',
4 | SHA1 = 'sha1',
5 | SHA256 = 'sha256',
6 | SHA512 = 'sha512',
7 | }
8 |
9 | export default HashsumType;
10 |
--------------------------------------------------------------------------------
/src/enums/resize-type.enum.ts:
--------------------------------------------------------------------------------
1 | enum ResizeType {
2 | FIT = 'fit',
3 | FILL = 'fill',
4 | FILL_DOWN = 'fill-down',
5 | FORCE = 'force',
6 | AUTO = 'auto',
7 | }
8 |
9 | export default ResizeType;
10 |
--------------------------------------------------------------------------------
/src/enums/resizing-algorithm.enum.ts:
--------------------------------------------------------------------------------
1 | enum ResizingAlgorithm {
2 | NEAREST = 'nearest',
3 | LINEAR = 'linear',
4 | CUBIC = 'cubic',
5 | LANCZOS2 = 'lanczos2',
6 | LANCZOS3 = 'lanczos3',
7 | }
8 |
9 | export default ResizingAlgorithm;
10 |
--------------------------------------------------------------------------------
/src/enums/unsharpening-mode.enum.ts:
--------------------------------------------------------------------------------
1 | enum UnsharpeningMode {
2 | AUTO = 'auto',
3 | NONE = 'none',
4 | ALWAYS = 'always',
5 | }
6 |
7 | export default UnsharpeningMode;
8 |
--------------------------------------------------------------------------------
/src/enums/watermark-position.enum.ts:
--------------------------------------------------------------------------------
1 | enum WatermarkPosition {
2 | CENTER = 'ce',
3 | NORTH = 'no',
4 | SOUTH = 'so',
5 | EAST = 'ea',
6 | WEST = 'we',
7 | NORTH_EAST = 'noea',
8 | NORTH_WEST = 'nowe',
9 | SOUTH_EAST = 'soea',
10 | SOUTH_WEST = 'sowe',
11 | REPLICATE = 're',
12 | }
13 |
14 | export default WatermarkPosition;
15 |
--------------------------------------------------------------------------------
/src/transformers/adjust.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The adjust options
5 | */
6 | type AdjustOptions = {
7 | /**
8 | * Integer ranging from -255 to 255
9 | */
10 | brightness?: number;
11 |
12 | /**
13 | * Floating point number ranging from 0.0 to 1.0
14 | */
15 | contrast?: number;
16 |
17 | /**
18 | * Floating point number ranging from 0.0 to 1.0
19 | */
20 | saturation?: number;
21 | };
22 |
23 | /**
24 | * Defines the brightness, contrast, and saturation.
25 | *
26 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#adjust-idadjust for the imgproxy documentation
27 | *
28 | * @param options The adjustment options
29 | * @returns The adjustment param string
30 | */
31 | const adjust = (options: AdjustOptions): string =>
32 | stringifyOptions('a', [
33 | options.brightness,
34 | options.contrast,
35 | options.saturation,
36 | ]);
37 |
38 | export default adjust;
39 | export { AdjustOptions };
40 |
--------------------------------------------------------------------------------
/src/transformers/auto-rotate.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Automatically rotates the image based on the EXIF orientation parameter.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#auto-rotate for the imgproxy documentation
7 | *
8 | * @returns The auto-rotate param string
9 | */
10 | const autoRotate = (): string => stringifyOptions('ar', [true]);
11 |
12 | export default autoRotate;
13 |
--------------------------------------------------------------------------------
/src/transformers/background-alpha.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The background alpha, a positive floating point number ranging from 0 to 1
5 | */
6 | type BackgroundAlphaOptions = number;
7 |
8 | /**
9 | * Adds alpha channel to background.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#background-alpha-idbackground-alpha for the imgproxy documentation
12 | *
13 | * @param percentage A positive floating point number between 0 and 1
14 | * @returns The background alpha param string
15 | */
16 | const backgroundAlpha = (percentage: BackgroundAlphaOptions): string =>
17 | stringifyOptions('bga', [percentage]);
18 |
19 | export default backgroundAlpha;
20 | export { BackgroundAlphaOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/background.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The background color
5 | */
6 | type BackgroundOptions =
7 | | string
8 | | {
9 | /**
10 | * The red channel (0-255)
11 | */
12 | r: number;
13 |
14 | /**
15 | * The green channel (0-255)
16 | */
17 | g: number;
18 |
19 | /**
20 | * The blue channel (0-255)
21 | */
22 | b: number;
23 | };
24 |
25 | /**
26 | * Fills the image background with the specified color.
27 | *
28 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#background for the imgproxy documentation
29 | *
30 | * @param options The background color (hex encoded string or RGB object)
31 | * @returns The background param string
32 | */
33 | const background = (options: BackgroundOptions): string =>
34 | stringifyOptions('bg', [
35 | ...(typeof options === 'string'
36 | ? [options]
37 | : [options.r, options.g, options.b]),
38 | ]);
39 |
40 | export default background;
41 | export { BackgroundOptions };
42 |
--------------------------------------------------------------------------------
/src/transformers/blur-detections.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The blur detection options
5 | */
6 | type BlurDetectionOptions = {
7 | /**
8 | * The blur radius
9 | */
10 | sigma: number;
11 |
12 | /**
13 | * The class names. If omitted, imgproxy blurs all the detected objects.
14 | */
15 | classNames?: string[];
16 | };
17 |
18 | /**
19 | * Detects objects of the provided classes and blurs them.
20 | *
21 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#blur-detections-idblur-detections for the imgproxy documentation
22 | *
23 | * @param options The detection options
24 | * @returns The blur detection param string
25 | */
26 | const blurDetections = (options: BlurDetectionOptions): string =>
27 | stringifyOptions('bd', [options.sigma, ...(options.classNames ?? [])]);
28 |
29 | export default blurDetections;
30 | export { BlurDetectionOptions };
31 |
--------------------------------------------------------------------------------
/src/transformers/blur.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The blur radius
5 | */
6 | type BlurOptions = number;
7 |
8 | /**
9 | * Applies a gaussian blur filter to the image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#blur for the imgproxy documentation
12 | *
13 | * @param sigma The size of the blur mask
14 | * @returns The blur param string
15 | */
16 | const blur = (sigma: BlurOptions): string => stringifyOptions('bl', [sigma]);
17 |
18 | export default blur;
19 | export { BlurOptions };
20 |
--------------------------------------------------------------------------------
/src/transformers/brightness.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The brightness, an integer ranging from -255 to 255.
5 | */
6 | type BrightnessOptions = number;
7 |
8 | /**
9 | * Adjusts the brightness of an image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#brightness-idbrightness for the imgproxy documentation
12 | *
13 | * @param value An integer number ranging from -255 to 255.
14 | * @returns The brightness param string
15 | */
16 | const brightness = (value: BrightnessOptions): string =>
17 | stringifyOptions('br', [value]);
18 |
19 | export default brightness;
20 | export { BrightnessOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/cache-buster.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The cache buster
5 | */
6 | type CacheBusterOptions = string;
7 |
8 | /**
9 | * Adds a cache buster to the imgproxy params.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#cache-buster for the imgproxy documentation
12 | *
13 | * @param buster The cache buster
14 | * @returns The cache buster param string
15 | */
16 | const cacheBuster = (buster: CacheBusterOptions): string =>
17 | stringifyOptions('cb', [buster]);
18 |
19 | export default cacheBuster;
20 | export { CacheBusterOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/contrast.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The percentage (positive floating number from 0-1)
5 | */
6 | type ContrastOptions = number;
7 |
8 | /**
9 | * Adjust contrast of the resulting image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#contrast-idcontrast for the imgproxy documentation
12 | *
13 | * @param percentage A positive floating point number, where 1
14 | * keeps the contrast unchanged.
15 | * @returns The contrast param string
16 | */
17 | const contrast = (percentage: ContrastOptions): string =>
18 | stringifyOptions('co', [percentage]);
19 |
20 | export default contrast;
21 | export { ContrastOptions };
22 |
--------------------------------------------------------------------------------
/src/transformers/crop.ts:
--------------------------------------------------------------------------------
1 | import GravityType from '../enums/gravity-type.enum.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The available options for the crop operation
6 | */
7 | type CropOptions = {
8 | /**
9 | * The width of the cropped size
10 | *
11 | * if width == 0 or unset : imgproxy uses the full width
12 | * if width >= 1 : imgproxy treats it as absolute value
13 | * if width <= 1 : imgproxy treats it as relative value
14 | */
15 | width?: number;
16 | /**
17 | * The height of the cropped size
18 | *
19 | * if height == 0 or unset : imgproxy uses the full height
20 | * if height >= 1 : imgproxy treats it as absolute value
21 | * if height <= 1 : imgproxy treats it as relative value
22 | */
23 | height?: number;
24 | /**
25 | * (Optional) The gravity for the cropping operation
26 | */
27 | gravity?: {
28 | /**
29 | * Specifies the gravity type
30 | */
31 | type: GravityType;
32 |
33 | /**
34 | * (Optional) Specifies the offset by X and Y axes
35 | */
36 | offset?: {
37 | /**
38 | * The gravity offset on the X axis
39 | */
40 | x: number;
41 | /**
42 | * The gravity offset on the Y axis
43 | */
44 | y: number;
45 | };
46 | };
47 | };
48 |
49 | /**
50 | * Crops the image.
51 | *
52 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#crop for the imgproxy documentation
53 | *
54 | * @param options The cropping options
55 | * @returns The cropping param string
56 | */
57 | const crop = (options?: CropOptions): string =>
58 | stringifyOptions('c', [
59 | options?.width ?? 0,
60 | options?.height ?? 0,
61 | options?.gravity?.type,
62 | options?.gravity?.offset?.x,
63 | options?.gravity?.offset?.y,
64 | ]);
65 |
66 | export default crop;
67 | export { CropOptions };
68 |
--------------------------------------------------------------------------------
/src/transformers/disable-animation.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Use a single frame of animated images.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/cfa4b596d1f31656f9116cc16f2a4ff7d15c2837/docs/generating_the_url.md#disable-animation-iddisable-animation for the imgproxy documentation
7 | *
8 | * @returns The disable animation param string
9 | */
10 | const disableAnimation = (): string => stringifyOptions('da', [true]);
11 |
12 | export default disableAnimation;
13 |
--------------------------------------------------------------------------------
/src/transformers/dpi.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The DPI value
5 | */
6 | type DPIOptions = number;
7 |
8 | /**
9 | * When set, imgproxy will replace the image's DPI metadata with the provided value.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/8629c5eca1e422908363f471513bfc887d778a85/docs/generating_the_url.md#dpi-iddpi for the imgproxy documentation
12 | *
13 | * @param value The DPI value
14 | * @returns The DPI param string
15 | */
16 | const dpi = (value: DPIOptions): string => stringifyOptions('dpi', [value]);
17 |
18 | export default dpi;
19 | export { DPIOptions };
20 |
--------------------------------------------------------------------------------
/src/transformers/dpr.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The DPR factor (must be greater than 0)
5 | */
6 | type DprOptions = number;
7 |
8 | /**
9 | * Multiplies the dimensions according to the specified factor.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#dpr for the imgproxy documentation
12 | *
13 | * @param value The DPR factor
14 | * @returns The DPR param string
15 | */
16 | const dpr = (value: DprOptions): string => stringifyOptions('dpr', [value]);
17 |
18 | export default dpr;
19 | export { DprOptions };
20 |
--------------------------------------------------------------------------------
/src/transformers/draw-detections.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The draw detection options
5 | */
6 | type DrawDetectionOptions = {
7 | /**
8 | * The class names. If omitted, imgproxy draws the
9 | * bounding boxes of all the detected objects.
10 | */
11 | classNames?: string[];
12 | };
13 |
14 | /**
15 | * Detects objects of the provided classes and draws their
16 | * bounding boxes.
17 | *
18 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#draw-detections-iddraw-detections for the imgproxy documentation
19 | *
20 | * @param options The detection options
21 | * @returns The draw detection param string
22 | */
23 | const drawDetections = (options: DrawDetectionOptions): string =>
24 | stringifyOptions('dd', [true, ...(options.classNames ?? [])]);
25 |
26 | export default drawDetections;
27 | export { DrawDetectionOptions };
28 |
--------------------------------------------------------------------------------
/src/transformers/duotone.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common';
2 |
3 | type DuotoneOptions = {
4 | /**
5 | * A positive floating-point number between 0 and 1 that
6 | * defines the intensity of the duotone effect
7 | */
8 | intensity: number;
9 |
10 | /**
11 | * The hex-coded value for the dark areas
12 | */
13 | color1: string;
14 |
15 | /**
16 | * The hex-coded value for the light areas
17 | */
18 | color2: string;
19 | };
20 |
21 | /**
22 | * Converts the image to duotone with specified intensity and colors.
23 | *
24 | * See https://github.com/imgproxy/imgproxy-docs/blob/7d15484aea6a1fae5f1dfd1806b5551a4774658d/docs/usage/processing.mdx?plain=1#L429 for the imgproxy documentation
25 | *
26 | * @param options The duotone options
27 | * @returns The duotone param string
28 | */
29 | const duotone = (options: DuotoneOptions): string =>
30 | stringifyOptions('dt', [options.intensity, options.color1, options.color2]);
31 |
32 | export default duotone;
33 | export { DuotoneOptions };
34 |
--------------------------------------------------------------------------------
/src/transformers/enforce-thumbnail.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * If the source image has an embedded thumbnail, imgproxy will use the
5 | * embedded thumbnail instead of the main image.
6 | *
7 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#enforce-thumbnail for the imgproxy documentation
8 | *
9 | * @returns The enforce thumbnail param string
10 | */
11 | const enforceThumbnail = (): string => stringifyOptions('eth', [true]);
12 |
13 | export default enforceThumbnail;
14 |
--------------------------------------------------------------------------------
/src/transformers/enlarge.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Enlarges the image if it is smaller than the given size.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#enlarge for the imgproxy documentation
7 | *
8 | * @returns The enlarge param string
9 | */
10 | const enlarge = (): string => stringifyOptions('el', [true]);
11 |
12 | export default enlarge;
13 |
--------------------------------------------------------------------------------
/src/transformers/expires.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The expiration date / unix timestamp
5 | */
6 | type ExpiresOptions = Date | number;
7 |
8 | /**
9 | * Returns a 404 if the expiration date is reached.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#expires for the imgproxy documentation
12 | *
13 | * @param options The unix timestamp
14 | * @returns The expiration param string
15 | */
16 | const expires = (options: ExpiresOptions): string =>
17 | stringifyOptions('exp', [
18 | typeof options === 'number'
19 | ? options
20 | : Math.floor(options.getTime() / 1000),
21 | ]);
22 |
23 | export default expires;
24 | export { ExpiresOptions };
25 |
--------------------------------------------------------------------------------
/src/transformers/extend-aspect-ratio.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | import { GravityType } from '../index.js';
4 |
5 | /**
6 | * The extend aspect ratio options
7 | */
8 | type ExtendAspectRatioOptions = {
9 | /**
10 | * (Optional) The gravity for the cropping operation
11 | */
12 | gravity?: {
13 | /**
14 | * Specifies the gravity type
15 | */
16 | type: Exclude;
17 |
18 | /**
19 | * (Optional) Specifies the offset by X and Y axes
20 | */
21 | offset?: {
22 | /**
23 | * The gravity offset on the X axis
24 | */
25 | x: number;
26 | /**
27 | * The gravity offset on the Y axis
28 | */
29 | y: number;
30 | };
31 | };
32 | };
33 |
34 | /**
35 | * Extends the image to the requested aspect ratio.
36 | *
37 | * See https://github.com/imgproxy/imgproxy/blob/1a9768a2c682e88820064aa3d9a05ea234ff3cc4/docs/generating_the_url.md#extend-aspect-ratio for the imgproxy documentation
38 | *
39 | * @returns The extend aspect ratio param string
40 | */
41 | const extendAspectRatio = (options?: ExtendAspectRatioOptions): string =>
42 | stringifyOptions('exar', [
43 | true,
44 | options?.gravity?.type,
45 | options?.gravity?.offset?.x,
46 | options?.gravity?.offset?.y,
47 | ]);
48 |
49 | export default extendAspectRatio;
50 | export { ExtendAspectRatioOptions };
51 |
--------------------------------------------------------------------------------
/src/transformers/extend.ts:
--------------------------------------------------------------------------------
1 | import GravityType from '../enums/gravity-type.enum.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The extend options
6 | */
7 | type ExtendOptions = {
8 | /**
9 | * The gravity
10 | */
11 | gravity: {
12 | type: Exclude;
13 |
14 | /**
15 | * The gravity offset
16 | */
17 | offset?: {
18 | /**
19 | * The gravity offset on the X axis
20 | */
21 | x: number;
22 |
23 | /**
24 | * The gravity offset on the y axis
25 | */
26 | y: number;
27 | };
28 | };
29 | };
30 |
31 | /**
32 | * Extends the image if it is smaller than the given size.
33 | *
34 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#extend for the imgproxy documentation
35 | *
36 | * @param options The extend options
37 | * @returns The extend param string
38 | */
39 | const extend = (options?: ExtendOptions): string =>
40 | stringifyOptions('ex', [
41 | true,
42 | options?.gravity.type,
43 | options?.gravity.offset?.x,
44 | options?.gravity.offset?.y,
45 | ]);
46 |
47 | export default extend;
48 | export { ExtendOptions };
49 |
--------------------------------------------------------------------------------
/src/transformers/fallback-image-url.ts:
--------------------------------------------------------------------------------
1 | import { base64urlEncode, utf8encode } from '../crypto/codec.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The fallback image URL
6 | */
7 | type FallbackImageUrlOptions = string;
8 |
9 | /**
10 | * Sets a custom fallback image by specifying its URL.
11 | *
12 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#fallback-image-url-idfallback-image-url for the imgproxy documentation
13 | *
14 | * @param url The fallback image URL
15 | * @returns The fallback image URL param string
16 | */
17 | const fallbackImageUrl = (url: FallbackImageUrlOptions): string =>
18 | stringifyOptions('fiu', [base64urlEncode(utf8encode(url))]);
19 |
20 | export default fallbackImageUrl;
21 | export { FallbackImageUrlOptions };
22 |
--------------------------------------------------------------------------------
/src/transformers/filename.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The file name
5 | */
6 | type FileNameOptions = string;
7 |
8 | /**
9 | * Sets the filename for the Content-Disposition header.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/41b9ebe9277ef3e664e0a842fbc0e912b2640969/docs/generating_the_url.md#filename for the imgproxy documentation
12 | *
13 | * @param name The filename
14 | * @param base64Encoded Whether the file name is base64 encoded
15 | * @returns The filename param string
16 | */
17 | const fileName = (name: FileNameOptions, base64Encoded = false): string =>
18 | stringifyOptions('fn', [name, base64Encoded ? true : undefined]);
19 |
20 | export default fileName;
21 | export { FileNameOptions };
22 |
--------------------------------------------------------------------------------
/src/transformers/format-quality.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * A record consisting of a mapping from extension/format to the quality factor
5 | */
6 | type FormatQualityOptions = Record;
7 |
8 | /**
9 | * Sets the desired quality for each format.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#format-quality for the imgproxy documentation
12 | *
13 | * @param options The format quality options
14 | * @returns The format quality param string
15 | */
16 | const formatQuality = (options: FormatQualityOptions): string =>
17 | stringifyOptions(
18 | 'fq',
19 | Object.entries(options).flatMap((e) => e),
20 | );
21 |
22 | export default formatQuality;
23 | export { FormatQualityOptions };
24 |
--------------------------------------------------------------------------------
/src/transformers/format.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The file format
5 | */
6 | type FormatOptions =
7 | | 'png'
8 | | 'jpg'
9 | | 'webp'
10 | | 'avif'
11 | | 'gif'
12 | | 'ico'
13 | | 'heic'
14 | | 'bmp'
15 | | 'tiff';
16 |
17 | /**
18 | * Specifies the resulting image format.
19 | *
20 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#format for the imgproxy documentation
21 | *
22 | * @param imageFormat The target format
23 | * @returns The format param string
24 | */
25 | const format = (imageFormat: FormatOptions): string =>
26 | stringifyOptions('f', [imageFormat]);
27 |
28 | export default format;
29 | export { FormatOptions };
30 |
--------------------------------------------------------------------------------
/src/transformers/gif-options.ts:
--------------------------------------------------------------------------------
1 | // Removed in version 3.0.0
2 | // See: https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/CHANGELOG.md#removed
3 |
4 | import { stringifyOptions } from '../common.js';
5 |
6 | /**
7 | * The GIF options
8 | */
9 | type GifOptions = {
10 | /**
11 | * If true, enables GIF frames optimization.
12 | */
13 | optimizeFrames?: boolean;
14 |
15 | /**
16 | * If true, enables GIF transparency optimization.
17 | */
18 | optimizeTransparency?: boolean;
19 | };
20 |
21 | /**
22 | * Allows redefining GIF saving options.
23 | *
24 | * @deprecated Automatically applied since version 3.0.0
25 | * @param options The gif options
26 | * @returns The gif option param string
27 | */
28 | const gifOptions = (options: GifOptions): string =>
29 | stringifyOptions('gifo', [
30 | options.optimizeFrames,
31 | options.optimizeTransparency,
32 | ]);
33 |
34 | export default gifOptions;
35 | export { GifOptions };
36 |
--------------------------------------------------------------------------------
/src/transformers/gradient.ts:
--------------------------------------------------------------------------------
1 | import GradientDirection from '../enums/gradient-direction.enum.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The gradient options
6 | */
7 | type GradientOptions = {
8 | /**
9 | * The opacity
10 | */
11 | opacity: number | string;
12 |
13 | /**
14 | * Hex encoded value of the gradient color
15 | */
16 | color?: string;
17 |
18 | /**
19 | * The gradient direction
20 | */
21 | direction?: GradientDirection;
22 |
23 | /**
24 | * Relative position of the gradient start between 0.0 and 1.0
25 | */
26 | start?: number | string;
27 |
28 | /**
29 | * Relative position of the gradient stop between 0.0 and 1.0
30 | */
31 | stop?: number | string;
32 | };
33 |
34 | /**
35 | * Places a gradient on the processed image.
36 | *
37 | * See https://github.com/imgproxy/imgproxy/blob/cfa4b596d1f31656f9116cc16f2a4ff7d15c2837/docs/generating_the_url.md#gradient-idgradient for the imgproxy documentation
38 | *
39 | * @param options The gradient options
40 | * @returns The gradient param string
41 | */
42 | const gradient = (options: GradientOptions): string =>
43 | stringifyOptions('gr', [
44 | options.opacity,
45 | options.color ?? '000',
46 | options.direction ?? GradientDirection.DOWN,
47 | options.start ?? '0.0',
48 | options.stop ?? '1.0',
49 | ]);
50 |
51 | export default gradient;
52 | export { GradientOptions };
53 |
--------------------------------------------------------------------------------
/src/transformers/gravity.ts:
--------------------------------------------------------------------------------
1 | import GravityType from '../enums/gravity-type.enum.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The gravity options
6 | */
7 | type GravityOptions = {
8 | /**
9 | * The gravity type
10 | */
11 | type: GravityType;
12 |
13 | /**
14 | * The gravity offset
15 | */
16 | offset?: {
17 | /**
18 | * The gravity offset on the X axis
19 | */
20 | x: number;
21 |
22 | /**
23 | * The gravity offset on the y axis
24 | */
25 | y: number;
26 | };
27 | };
28 |
29 | /**
30 | * Sets the gravity.
31 | *
32 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#gravity for the imgproxy documentation
33 | *
34 | * @param options The gravity options
35 | * @returns The gravity param string
36 | */
37 | const gravity = (options: GravityOptions): string =>
38 | stringifyOptions('g', [options.type, options.offset?.x, options.offset?.y]);
39 |
40 | export default gravity;
41 | export { GravityOptions };
42 |
--------------------------------------------------------------------------------
/src/transformers/hashsum.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | import HashsumType from '../enums/hashsum-type.enum.js';
4 |
5 | type HashsumOptions = {
6 | /**
7 | * The expected hex-encoded hashsum of the source image
8 | */
9 | hashsum: string;
10 |
11 | /**
12 | * The hashsum type
13 | */
14 | type?: HashsumType;
15 | };
16 |
17 | /**
18 | * When `hashsum_type` is not `none`, imgproxy will calculate the hashsum of the source image
19 | * and compare it with the provided hashsum.
20 | *
21 | * If they don't match, imgproxy will respond with 422.
22 | *
23 | * See https://github.com/imgproxy/imgproxy-docs/blob/f9d7908d253ec2b31425b988a48f8c28cb271c58/docs/usage/processing.mdx#L916 for the imgproxy documentation
24 | *
25 | * @returns The auto-rotate param string
26 | */
27 | const hashsum = (options: HashsumOptions): string =>
28 | stringifyOptions('hashsum', [
29 | options.type ?? HashsumType.NONE,
30 | options.hashsum,
31 | ]);
32 |
33 | export default hashsum;
34 | export { HashsumOptions };
35 |
--------------------------------------------------------------------------------
/src/transformers/jpeg-options.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The JPEG options
5 | */
6 | type JpegOptions = {
7 | /**
8 | * If true, enables progressive JPEG compression
9 | */
10 | progressive?: boolean;
11 |
12 | /**
13 | * If true, chrominance sub-sampling is disabled
14 | */
15 | noSubsample?: boolean;
16 |
17 | /**
18 | * If true, enables trellis quantization for each
19 | * 8x8 block
20 | */
21 | trellisQuant?: boolean;
22 |
23 | /**
24 | * If true, enables overshooting of samples with
25 | * extreme values
26 | */
27 | overshootDeringing?: boolean;
28 |
29 | /**
30 | * If true, split the spectrum of DCT coefficients
31 | * into separate scans
32 | */
33 | optimizeScans?: boolean;
34 |
35 | /**
36 | * Quantization table to use
37 | *
38 | * 0: Table from JPEG Annex K (default);
39 | * 1: Flat table;
40 | * 2: Table tuned for MSSIM on Kodak image set;
41 | * 3: Table from ImageMagick by N. Robidoux;
42 | * 4: Table tuned for PSNR-HVS-M on Kodak image set;
43 | * 5: Table from Relevance of Human Vision to JPEG-DCT Compression (1992);
44 | * 6: Table from DCTune Perceptual Optimization of Compressed Dental X-Rays (1997);
45 | * 7: Table from A Visual Detection Model for DCT Coefficient Quantization (1993);
46 | * 8: Table from An Improved Detection Model for DCT Coefficient Quantization (1993).
47 | */
48 | quantizationTable?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
49 | };
50 |
51 | /**
52 | * Allows redefining JPEG saving options.
53 | *
54 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#jpeg-options-idjpeg-options for the imgproxy documentation
55 | *
56 | * @param options The jpeg options
57 | * @returns The jpeg option param string
58 | */
59 | const jpegOptions = (options: JpegOptions): string =>
60 | stringifyOptions('jpgo', [
61 | options.progressive,
62 | options.noSubsample,
63 | options.trellisQuant,
64 | options.overshootDeringing,
65 | options.optimizeScans,
66 | options.quantizationTable,
67 | ]);
68 |
69 | export default jpegOptions;
70 | export { JpegOptions };
71 |
--------------------------------------------------------------------------------
/src/transformers/keep-copypright.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Preserve the copyright info while stripping metadata.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#keep-copyright for the imgproxy documentation
7 | *
8 | * @returns The keep copyright param string
9 | */
10 | const keepCopyright = (): string => stringifyOptions('kcr', [true]);
11 |
12 | export default keepCopyright;
13 |
--------------------------------------------------------------------------------
/src/transformers/max-bytes.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The number of bytes
5 | */
6 | type MaxBytesOptions = number;
7 |
8 | /**
9 | * Limits the file size to the specified number of bytes.
10 | *
11 | * Note: only applicable to jpg, webp, heic and tiff.
12 | *
13 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#max-bytes for the imgproxy documentation
14 | *
15 | * @param maxBytes The number of bytes
16 | * @returns The max bytes param string
17 | */
18 | const maxBytes = (bytes: MaxBytesOptions): string =>
19 | stringifyOptions('mb', [bytes]);
20 |
21 | export default maxBytes;
22 | export { MaxBytesOptions };
23 |
--------------------------------------------------------------------------------
/src/transformers/min-height.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The min height of the resulting image
5 | */
6 | type MinHeightOptions = number;
7 |
8 | /**
9 | * Defines the minimum height of the resulting image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#min-height for the imgproxy documentation
12 | *
13 | * @param height The minimum height
14 | * @returns The min height param string
15 | */
16 | const minHeight = (height: MinHeightOptions): string =>
17 | stringifyOptions('mh', [height]);
18 |
19 | export default minHeight;
20 | export { MinHeightOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/min-width.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The min width of the resulting image
5 | */
6 | type MinWidthOptions = number;
7 |
8 | /**
9 | * Defines the minimum width of the resulting image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#min-width for the imgproxy documentation
12 | *
13 | * @param width The minimum width
14 | * @returns The min width param string
15 | */
16 | const minWidth = (width: MinWidthOptions): string =>
17 | stringifyOptions('mw', [width]);
18 |
19 | export default minWidth;
20 | export { MinWidthOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/monochrome.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The monochrome options
5 | */
6 | type MonochromeOptions = {
7 | /**
8 | * A positive floating-point number between 0 and 1 that defines
9 | * the intensity of the monochrome effect.
10 | *
11 | * When intensity is greater than zero, imgproxy will convert the
12 | * resulting image to monochrome.
13 | */
14 | intensity: number;
15 |
16 | /**
17 | * A hex-coded value of the color that will be used as a base for the
18 | * monochrome palette.
19 | */
20 | color?: string;
21 | };
22 |
23 | /**
24 | * Converts the image to monochrome.
25 | *
26 | * See https://github.com/imgproxy/imgproxy-docs/blob/7d15484aea6a1fae5f1dfd1806b5551a4774658d/docs/usage/processing.mdx?plain=1#L415 for the imgproxy documentation
27 | *
28 | * @param options The monochrome options
29 | * @returns The monochrome param string
30 | */
31 | const monochrome = (options: MonochromeOptions): string =>
32 | stringifyOptions('mc', [
33 | options.intensity,
34 | ...(options.color ? [options.color] : []),
35 | ]);
36 |
37 | export default monochrome;
38 | export { MonochromeOptions };
39 |
--------------------------------------------------------------------------------
/src/transformers/pad.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The available options for the crop operation
5 | */
6 | type PaddingOptions = {
7 | /**
8 | * The top padding (and all other sides if not set explicitly)
9 | */
10 | top?: number;
11 |
12 | /**
13 | * The right padding (and left if it won't be set explicitly)
14 | */
15 | right?: number;
16 |
17 | /**
18 | * The bottom padding
19 | */
20 | bottom?: number;
21 |
22 | /**
23 | * The left padding
24 | */
25 | left?: number;
26 | };
27 |
28 | /**
29 | * Applies the specified padding to the image.
30 | *
31 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#padding for the imgproxy documentation
32 | *
33 | * @param options The padding options
34 | * @returns The padding param string
35 | */
36 | const pad = (options: PaddingOptions): string =>
37 | stringifyOptions('pd', [
38 | options.top,
39 | options.right,
40 | options.bottom,
41 | options.left,
42 | ]);
43 |
44 | export default pad;
45 | export { PaddingOptions };
46 |
--------------------------------------------------------------------------------
/src/transformers/page.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The page number (starting from 0)
5 | */
6 | type PageOptions = number;
7 |
8 | /**
9 | * When source image supports pagination (PDF, TIFF) or animation (GIF, WebP), this option allows
10 | * specifying the page to use.
11 | *
12 | * Pages numeration starts from zero.
13 | *
14 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#page-idpage for the imgproxy documentation
15 | *
16 | * @param pg The page to use
17 | * @returns The page param string
18 | */
19 | const page = (pg: PageOptions): string => stringifyOptions('pg', [pg]);
20 |
21 | export default page;
22 | export { PageOptions };
23 |
--------------------------------------------------------------------------------
/src/transformers/pixelate.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The size of a pixel
5 | */
6 | type PixelateOptions = number;
7 |
8 | /**
9 | * Apply the pixelate filter to the resulting image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#pixelate for the imgproxy documentation
12 | *
13 | * @param pixelSize The size of a pixel
14 | * @returns The pixelate param string
15 | */
16 | const pixelate = (pixelSize: PixelateOptions): string =>
17 | stringifyOptions('pix', [pixelSize]);
18 |
19 | export default pixelate;
20 | export { PixelateOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/png-options.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The PNG options
5 | */
6 | type PngOptions = {
7 | /**
8 | * If true, enables interlaced PNG compression
9 | */
10 | interlaced?: boolean;
11 |
12 | /**
13 | * If true, enables PNG quantization.
14 | */
15 | quantize?: boolean;
16 |
17 | /**
18 | * Maximum number of quantization palette entries.
19 | *
20 | * Should be between 2 and 256.
21 | */
22 | quantization_colors?: number;
23 | };
24 |
25 | /**
26 | * Allows redefining PNG saving options.
27 | *
28 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#png-options-idpng-options for the imgproxy documentation
29 | *
30 | * @param options The png options
31 | * @returns The png option param string
32 | */
33 | const pngOptions = (options: PngOptions): string =>
34 | stringifyOptions('pngo', [
35 | options.interlaced,
36 | options.quantize,
37 | options.quantization_colors,
38 | ]);
39 |
40 | export default pngOptions;
41 | export { PngOptions };
42 |
--------------------------------------------------------------------------------
/src/transformers/preset.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * A preset or a list of presets
5 | */
6 | type PresetOptions = string | string[];
7 |
8 | /**
9 | * Sets one or many presets to be used by the imgproxy.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#preset for the imgproxy documentation
12 | *
13 | * @param presets The preset(s)
14 | * @returns The preset param string
15 | */
16 | const preset = (presets: PresetOptions): string =>
17 | stringifyOptions('pr', Array.isArray(presets) ? presets : [presets]);
18 |
19 | export default preset;
20 | export { PresetOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/quality.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The quality in percentage (floating point number from 0.0 to 1.0)
5 | */
6 | type QualityOptions = number;
7 |
8 | /**
9 | * Redefines the quality of the resulting image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#quality for the imgproxy documentation
12 | *
13 | * @param percentage The percentage as floating point number from 0 to 1
14 | * @returns The quality param string
15 | */
16 | const quality = (percentage: QualityOptions): string =>
17 | stringifyOptions('q', [percentage]);
18 |
19 | export default quality;
20 | export { QualityOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/raw.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Returns a raw unprocessed and unchecked source image
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/f95f57bb4df35c69ae2257958006ef54b1c1d8c7/docs/generating_the_url.md#raw for the imgproxy documentation
7 | *
8 | * @returns The raw param string
9 | */
10 | const raw = (): string => stringifyOptions('raw', [true]);
11 |
12 | export default raw;
13 |
--------------------------------------------------------------------------------
/src/transformers/resize.ts:
--------------------------------------------------------------------------------
1 | import ResizeType from '../enums/resize-type.enum.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The resize options
6 | */
7 | type ResizeOptions = {
8 | /**
9 | * The resizing strategy
10 | */
11 | type?: ResizeType;
12 |
13 | /**
14 | * The target width
15 | */
16 | width?: number;
17 |
18 | /**
19 | * The target height
20 | */
21 | height?: number;
22 | };
23 |
24 | /**
25 | * Resizes the image.
26 | *
27 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#resize for the imgproxy documentation
28 | *
29 | * @param options The resizing options
30 | * @returns The resizing param string
31 | */
32 | const resize = (options: ResizeOptions): string =>
33 | stringifyOptions('rs', [options.type, options.width, options.height]);
34 |
35 | export default resize;
36 | export { ResizeOptions };
37 |
--------------------------------------------------------------------------------
/src/transformers/resizing-algorithm.ts:
--------------------------------------------------------------------------------
1 | import ResizingAlgorithm from '../enums/resizing-algorithm.enum.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The resizing algorithm
6 | */
7 | type ResizingAlgorithmOptions = ResizingAlgorithm;
8 |
9 | /**
10 | * Defines the algorithm that imgproxy will use for resizing.
11 | *
12 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#resizing-algorithm-idresizing-algorithm for the imgproxy documentation
13 | *
14 | * @param algorithm The resizing algorithm
15 | * @returns The resizing algorithm param string
16 | */
17 | const resizingAlgorithm = (algorithm: ResizingAlgorithmOptions): string =>
18 | stringifyOptions('ra', [algorithm]);
19 |
20 | export default resizingAlgorithm;
21 | export { ResizingAlgorithmOptions };
22 |
--------------------------------------------------------------------------------
/src/transformers/return-attachment.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Returns attachment in the Content-Disposition header.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#return-attachment for the imgproxy documentation
7 | *
8 | * @returns The attachment param string
9 | */
10 | const returnAttachment = (): string => stringifyOptions('att', [true]);
11 |
12 | export default returnAttachment;
13 |
--------------------------------------------------------------------------------
/src/transformers/rotate.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The rotation angle
5 | */
6 | type RotationOptions = 0 | 90 | 180 | 270;
7 |
8 | /**
9 | * Rotates the image by the specified angle.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#rotate for the imgproxy documentation
12 | *
13 | * @param angle The angle
14 | * @returns The rotate param string
15 | */
16 | const rotate = (angle: RotationOptions): string =>
17 | stringifyOptions('rot', [angle]);
18 |
19 | export default rotate;
20 | export { RotationOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/saturation.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The saturation (positive floating point number from 0 to 1).
5 | */
6 | type SaturationOptions = number;
7 |
8 | /**
9 | * Adjust saturation of the resulting image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#saturation-idsaturation for the imgproxy documentation
12 | *
13 | * @param percentage A positive floating point number, where 1
14 | * keeps the saturation unchanged
15 | * @returns The saturation param string
16 | */
17 | const saturation = (percentage: SaturationOptions): string =>
18 | stringifyOptions('sa', [percentage]);
19 |
20 | export default saturation;
21 | export { SaturationOptions };
22 |
--------------------------------------------------------------------------------
/src/transformers/sharpen.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The size of the sharpen mask (floating point number)
5 | */
6 | type SharpenOptions = number;
7 |
8 | /**
9 | * Applies a sharpen filter to the image.
10 | *
11 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#sharpen for the imgproxy documentation
12 | *
13 | * @param sigma The size of the sharpen mask
14 | * @returns The sharpen param string
15 | */
16 | const sharpen = (sigma: SharpenOptions): string =>
17 | stringifyOptions('sh', [sigma]);
18 |
19 | export default sharpen;
20 | export { SharpenOptions };
21 |
--------------------------------------------------------------------------------
/src/transformers/skip-processing.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * The list of formats which should not be processed
5 | */
6 | type SkipProcessingOptions = string[];
7 |
8 | /**
9 | * Skip the processing of the listed formats.
10 | *
11 | * Note: Processing can only be skipped when the requested format is
12 | * the same as the source format.
13 | *
14 | * Note: Video thumbnail processing can't be skipped
15 | *
16 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#skip-processing for the imgproxy documentation
17 | *
18 | * @param extensions The list of file extensions
19 | * @returns The skip processing param string
20 | */
21 | const skipProcessing = (extensions: SkipProcessingOptions): string =>
22 | stringifyOptions('skp', extensions);
23 |
24 | export default skipProcessing;
25 | export { SkipProcessingOptions };
26 |
--------------------------------------------------------------------------------
/src/transformers/strip-color-profile.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Strips the color profile from the image.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#strip-color-profile for the imgproxy documentation
7 | *
8 | * @returns The strip color profile param string
9 | */
10 | const stripColorProfile = (): string => stringifyOptions('scp', [true]);
11 |
12 | export default stripColorProfile;
13 |
--------------------------------------------------------------------------------
/src/transformers/strip-metadata.ts:
--------------------------------------------------------------------------------
1 | import { stringifyOptions } from '../common.js';
2 |
3 | /**
4 | * Strips the metadata from the image.
5 | *
6 | * See https://github.com/imgproxy/imgproxy/blob/6f292443eafb2e39f9252175b61faa6b38105a7c/docs/generating_the_url.md#strip-metadata for the imgproxy documentation
7 | *
8 | * @returns The strip metadata param string
9 | */
10 | const stripMetadata = (): string => stringifyOptions('sm', [true]);
11 |
12 | export default stripMetadata;
13 |
--------------------------------------------------------------------------------
/src/transformers/style.ts:
--------------------------------------------------------------------------------
1 | import { base64urlEncode, utf8encode } from '../crypto/codec.js';
2 | import { stringifyOptions } from '../common.js';
3 |
4 | /**
5 | * The CSS styles to apply to the source SVG image
6 | */
7 | type StyleOptions = Record | string;
8 |
9 | /**
10 | * Prepend a `
The blur radius
2 |