npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ace-assist

v0.2.1

Published

An image store with resizing and PDF generation

Downloads

10

Readme

ACE Assist

This app provides endpoints for media transforms, PDF generation and convenience methods for managing S3 compatible assets. It's a Nodejs/Express app distributed as a Docker image.

Resized images are cached but it's advisable to use a CDN in front of the app and/or a high powered host.

The app leans heavily on the mighty sharp library for image operations.

 

/:slug/file/upload [POST]

Flow.js compatible upload target.

| Param | Description | | --- | --- | | slug | Project slug/folder |

| Data | Description | | --- | --- | | options | JSON containing upload options, see below... |

Upload options

| Option | Description | | --- | --- | | dzi | Deep Zoom image options |

 

/:slug/file/delete [DELETE]

| Param | Description | | --- | --- | | slug | Project slug/folder |

| Data | Description | | --- | --- | | files[] | Array of filenames to delete |

 

/:slug/transform/:options/:fileName [GET]

Resizes the requested image on-demand.

| Param | Description | | --- | --- | | slug | Project slug/folder | | filename | File to be transformed | | options | Serialized transform options, see below... |

Transform options

Options should be in the following format:

option:value

Multiple options can be combined with semi-colons:

w:200;h:200;g:attention

| Option | Description | | --- | --- | | w | Width in pixels or as a percentage if < 1 | | h | Height in pixels or as a percentage if < 1 | | q | Quality 1-100 (jpeg, webp) | | sm | Scale mode: fit or fill | | g | AUTO Crop method: north, south, east, west, center, entropy, attention | | x | MANUAL Crop method top-left x-axis coord 0-1 | | y | MANUAL Crop method top-left y-axis coord 0-1 | | x2 | MANUAL Crop method bottom-right x-axis coord 0-1 | | y2 | MANUAL Crop method bottom-right y-axis coord 0-1 | | bl | Blur 0.3+ | | sh | Sharpen 0.5+ | | f | Output format: jpg, png, webp |

 

/:slug/pdf/download [POST]

Accepts a POST request with a JSON payload in the request body. Uses PDFkit to generate PDFs.

| Parameter | Description | | --- | --- | | slug | Project slug/folder |

{
    "fileName": "lightbox.pdf",
    "layout": "landscape",
    "size": "A4",
    "margin": 0,
    "fonts": {
        "fontname": "https://www.example.com/fonts/example.ttf"
    },
    "assets": {
        "logo": "https://www.example.com/img/logo.png"
    },
    "pages": [
        [
            {
                "image": [
                    "logo",
                    36,
                    36,
                    {
                        "fit": [
                            200,
                            200
                        ]
                    }
                ]
            },
            {
                "fontSize": 12
            },
            {
                "font": "fontname"
            },
            {
                "text": [
                    "Copyright © 2017 Example. All Rights Reserved.",
                    36,
                    550,
                    {
                        "width": 769,
                        "align": "right"
                    }
                ]
            }
        ],
        [
            {
                "image": [
                    "slug/filename.jpg",
                    36,
                    36,
                    {
                        "fit": [
                            769,
                            495
                        ]
                    }
                ]
            },
            {
                "fontSize": 12
            },
            {
                "font": "fontname"
            },
            {
                "text": [
                    "Caption here",
                    36,
                    550
                ]
            }
        ]
    ]
}

 

OSX Dependencies

# libvips
$ brew install homebrew/science/vips --with-imagemagick --with-webp

# libvips from specific commit
$ git clone git://github.com/jcupitt/libvips.git; cd libvips; git reset --hard <commit id>; gtkdocize; ./bootstrap.sh; cd ../; rm -Rf libvips;

# ffmpeg
$ brew install libvpx ffmpeg --with-nonfree --with-tools --with-freetype --with-libass --with-libvorbis --with-libvpx --with-libx264 --with-x265 --with-libmp3lame --with-libfdk-aac

Usage (development)

You can add a nodemon.json file to your project to configure the public folder etc. This is useful if you're mounting a remote directory for example.

// nodemon.json
{
    "watch": ["routes", "lib"],
    "env": {
        "CACHE_MAX_SIZE": 100,
        "ACCESS_KEY_ID": "ACCESS_KEY_ID",
        "SECRET_ACCESS_KEY": "SECRET_ACCESS_KEY",
        "ENDPOINT": "ENDPOINT"
        "BUCKET": "BUCKET"
    }
}

Use these steps to get up and running in development.

# build docker image
$ docker build -t studiothomas/ace-assist .

# or bypassing build cache
$ docker build --no-cache -t studiothomas/ace-assist .

# stop/remove previous container if exists
$ docker stop ace-assist; docker rm ace-assist

# run container in interactive mode from image and bind ports, volumes
$ docker run --name ace-assist -i -p 49001:49001 \
    -v ~/assist/cache:/app/cache:rw \
    -v ~/assist/tmp:/app/tmp:rw \
    -e "HTTP_PORT=49001" \
    -e "HTTPS_PORT=49002" \
    -e "ENVIRONMENT=development" \
    -e "[email protected]" \
    -e "DOMAINS=example.com,example2.com" \
    -e "USERNAME=USERNAME" \
    -e "PASSWORD=PASSWORD" \
    -e "CACHE_MAX_SIZE=500" \
    -e "ACCESS_KEY_ID=ACCESS_KEY_ID" \
    -e "SECRET_ACCESS_KEY=SECRET_ACCESS_KEY" \
    -e "ENDPOINT=ENDPOINT" \
    -e "BUCKET=BUCKET" \
    studiothomas/ace-assist

# test in browser
http://localhost:49001

Usage (production)

# run container in daemon mode from image and bind ports, volumes with environment variables
$ docker run --name ace-assist -d -p 80:HTTP_PORT -p 443:HTTPS_PORT \
    -v /var/assist/cache:/app/cache:rw \
    -v /var/assist/tmp:/app/tmp:rw \
    -e "HTTP_PORT=49001" \
    -e "HTTPS_PORT=49002" \
    -e "ENVIRONMENT=production" \
    -e "[email protected]" \
    -e "DOMAINS=example.com,example2.com" \
    -e "USERNAME=USERNAME" \
    -e "PASSWORD=PASSWORD" \
    -e "CACHE_MAX_SIZE=500" \
    -e "ACCESS_KEY_ID=ACCESS_KEY_ID" \
    -e "SECRET_ACCESS_KEY=SECRET_ACCESS_KEY" \
    -e "ENDPOINT=ENDPOINT" \
    -e "BUCKET=BUCKET" \
    studiothomas/ace-assist

# using .env file
$ source .env; docker run --name ace-assist -d \
    -p 80:$HTTP_PORT -p 443:$HTTPS_PORT \
    --env-file=.env \
    -v /var/assist/cache:/app/cache:rw \
    -v /var/assist/tmp:/app/tmp:rw \
    studiothomas/ace-assist

Environment variables

HTTP_PORT
HTTPS_PORT
ENVIRONMENT
EMAIL
DOMAINS
USERNAME
PASSWORD
CACHE_MAX_SIZE
ACCESS_KEY_ID
SECRET_ACCESS_KEY
ENDPOINT
BUCKET

Useful commands

# Show free space
$ df -h

# Show largest directories
$ du -Sh | sort -rh | head -n 15

# Remove dangling images
$ docker rmi $(docker images -q -f dangling=true)

# Remove untagged images
$ docker rmi -f $(docker images | grep "<none>" | awk "{print \$3}")

# Resize partition to fill a resized volume on Digital Ocean (replace volume id)
$ sudo resize2fs /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-01

# Add key to remote host to use ssh without a password
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@remotehost

# Backup using rsync
$ rsync --recursive --compress --times --checksum --human-readable --rsh=ssh --verbose user@remotehost:/mnt/vol1/ /Volumes/vol1/backup

# Mount remote folder locally (requires sshfs/osxfuse)
$ sshfs user@remotehost:/mnt/vol1 ~/mnt/assist -ovolname=ASSIST

Backup Script

#!/bin/bash

# Add key to remote host to use ssh without a password
# $ ssh-keygen
# brew install ssh-copy-id
# $ ssh-copy-id -i ~/.ssh/id_rsa.pub user@remotehost

# rsync -rztche ssh root@remotehost:/shared /Volumes/HD/backup

rsync --recursive --compress --times --checksum --human-readable --rsh=ssh --verbose root@remotehost:/shared /Volumes/HD/backup