Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: revamp website #231

Merged
merged 8 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions README.md

This file was deleted.

1 change: 1 addition & 0 deletions README.md
25 changes: 7 additions & 18 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict'

const sass = require('gulp-sass')(require('sass'))
const strip = require('gulp-strip-css-comments')
const prefix = require('gulp-autoprefixer')
const cssnano = require('gulp-cssnano')
Expand All @@ -9,13 +8,8 @@ const concat = require('gulp-concat')
const gulp = require('gulp')

const src = {
css: ['public/sass/style.scss'],
js: [
'node_modules/prismjs/prism.js',
'node_modules/prismjs/components/prism-json.js',
'node_modules/anchor-js/anchor.js',
'public/js/main.js'
]
css: ['public/css/style.css'],
js: ['public/js/main.js']
}

const dist = {
Expand All @@ -26,19 +20,9 @@ const dist = {
}
}

function watch () {
gulp.watch(src.css, styles)
gulp.watch(src.js, scripts)
}

const styles = () =>
gulp
.src(src.css)
.pipe(
sass({
includePaths: ['node_modules/hack/dist', 'node_modules/prismjs/themes']
}).on('error', sass.logError)
)
.pipe(concat(`${dist.name.css}.min.css`))
.pipe(prefix())
.pipe(strip({ all: true }))
Expand All @@ -54,6 +38,11 @@ const scripts = () =>

const build = gulp.parallel(styles, scripts)

function watch () {
gulp.watch(src.css, styles)
gulp.watch(src.js, scripts)
}

module.exports.default = gulp.series(build, watch)
module.exports.build = build
module.exports.watch = watch
26 changes: 12 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,44 +83,45 @@
"youtube"
],
"dependencies": {
"@browserless/goto": "~9.9.4",
"@browserless/goto": "~9.9.5",
"@keyvhq/compress": "~1.6.28",
"@keyvhq/core": "~1.6.26",
"@keyvhq/multi": "~1.6.26",
"@keyvhq/redis": "~1.6.28",
"@microlink/mql": "~0.10.32",
"@microlink/ping-url": "~1.4.6",
"async-ratelimiter": "~1.3.7",
"browserless": "~9.9.4",
"browserless": "~9.9.7",
"cacheable-lookup": "~6.1.0",
"cacheable-response": "~2.8.2",
"cacheable-response": "~2.8.4",
"cheerio": "~1.0.0-rc.12",
"cors": "~2.8.5",
"data-uri-regex": "~0.1.4",
"data-uri-to-buffer": "~3.0.1",
"debug-logfmt": "~1.0.4",
"got": "~11.8.6",
"helmet": "~6.1.2",
"html-get": "~2.10.0",
"http-compression": "~1.0.4",
"html-get": "~2.10.2",
"http-compression": "~1.0.5",
"https-tls": "~1.0.12",
"ioredis": "~5.3.1",
"is-absolute-url": "~3.0.3",
"is-email-like": "~1.0.0",
"is-url-http": "~2.3.5",
"lodash": "~4.17.21",
"memoize-one": "~6.0.0",
"ms": "~2.1.3",
"on-finished": "~2.4.1",
"p-any": "~3.0.0",
"p-reflect": "~2.1.0",
"p-timeout": "~4.1.0",
"puppeteer": "~19.8.0",
"qsm": "~2.1.2",
"reachable-url": "~1.7.1",
"router-http": "~1.0.0",
"send-http": "~1.0.2",
"router-http": "~1.0.1",
"send-http": "~1.0.3",
"serve-static": "~1.15.0",
"srcset": "~4.0.0",
"tangerine": "~1.4.3",
"tangerine": "~1.4.7",
"top-user-agents": "~1.0.52",
"unique-random-array": "~2.0.0",
"url-regex": "~5.0.0"
Expand All @@ -129,6 +130,7 @@
"@commitlint/cli": "latest",
"@commitlint/config-conventional": "latest",
"anchor-js": "latest",
"async-listen": "latest",
"ava": "latest",
"browser-sync": "latest",
"concurrently": "latest",
Expand All @@ -140,15 +142,11 @@
"gulp-autoprefixer": "latest",
"gulp-concat": "latest",
"gulp-cssnano": "latest",
"gulp-sass": "latest",
"gulp-strip-css-comments": "latest",
"gulp-uglify": "latest",
"hack": "latest",
"nano-staged": "latest",
"npm-check-updates": "latest",
"prettier-standard": "latest",
"prismjs": "latest",
"sass": "latest",
"simple-git-hooks": "latest",
"standard": "latest",
"standard-markdown": "latest",
Expand All @@ -172,7 +170,7 @@
"dev": "TZ=UTC watchexec --clear --on-busy-update=restart node src/server.js",
"dev:docker": "docker build --platform linux/amd64 -t unavatar . && docker run --platform linux/amd64 --name unavatar -e NODE_ENV=staging -p 3000:3000 --rm unavatar",
"dev:docs": "concurrently \"npm run dev:docs:server\" \"npm run dev:docs:src\"",
"dev:docs:server": "cd public && browser-sync start --reload-delay 300 --server --files \"index.html, **/*.*\"",
"dev:docs:server": "browser-sync start public --server public --files \"index.html, README.md, public/**/*.(css|js)\"",
"dev:docs:src": "gulp",
"lint": "standard-markdown && standard",
"postrelease": "npm run release:tags && npm run release:github",
Expand Down
211 changes: 211 additions & 0 deletions public/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
![logo](https://unavatar.io/banner.png ':id=banner')

Welcome to **unavatar.io**, the ultimate avatar service that offers everything you need to easily retrieve user avatars:

- **Versatile**: A wide range of platforms and services including Facebook, Instagram, YouTube, Twitter, Gravatar, etc., meaning you can rule all of them just querying against unavatar.

- **Speed**: Designed to be fast and efficient, all requests are being cached and delivered +200 global datacenters, allowing you to consume avatars instantly, counting more than 20 millions requests per month.

- **Optimize**: All the images are not only compressed on-the-fly to reduce their size and save bandwith, but also optimized to maintain a high-quality ratio. They are ready for immediate use, enhancing the overall optimization of your website or application.

- **Integration**: The service seamlessly incorporates into your current applications or websites with ease. We offer straightforward documentation and comprehensive support to ensure a quick and effortless onboarding experience.

In summary, **unavatar.io** provides versatility, speed, optimization, and effortless integration, making it the ultimate avatar retrieval service.

## Quick start

The service is a single endpoint exposed in **unavatar.io** that can resolve:

- a **domain**: https://unavatar.io/reddit.com
- an **username**: https://unavatar.io/kikobeats
- an **email**: https://unavatar.io/sindresorhus@gmail.com

So, no matter what type of query you use, **unavatar.io** has you covered. You can read more about that in [providers](#providers).

## Query parameters

### TTL

Type: `string`<br/>
Default: `'24h'`<br/>
Range: from `'1h'` to `'28d'`

It determines the maximum quantity of time an avatar is considered fresh.

e.g., https://unavatar.io/kikobeats?ttl=1h

When you look up for a user avatar for the very first time, the service will determine it and cache it respecting TTL value.

The same resource will continue to be used until reach TTL expiration. After that, the resource will be computed, and cache as fresh, starting the cycle.

### Fallback

Type: `string`|`boolean`

When it can't be possible to get a user avatar, a fallback image is returned instead, and it can be personalized to fit better with your website or application style.

You can get one from **boringavatars.com**:

e.g., https://unavatar.io/github/37t?fallback=https://source.boringavatars.com/marble/120/1337_user?colors=264653r,2a9d8f,e9c46a,f4a261,e76f51

or **avatar.vercel.sh**:

e.g., https://unavatar.io/github/37t?fallback=https://avatar.vercel.sh/37t?size=400

or even an static image:

e.g., https://unavatar.io/github/37t?fallback=https://avatars.githubusercontent.com/u/66378906?v=4

You can pass `fallback=false` for explicitly disable this behavior. In that case, a `404 Not Found` HTTP status code will returned when is not possible to get the user avatar.

### JSON

The service returns media content by default.

This is in this way to make easier consume the service from HTML markup.

In case you want to get a JSON payload as response, just pass `json=true`:

e.g., https://unavatar.io/kikobeats?json

## Limitations

For preventing abusive usage, the service has associated a daily rate limit based on requests IP address.

You can verify for your rate limit state checking the following headers in the response:

- `x-rate-limit-limit`: The maximum number of requests that the consumer is permitted to make per minute.
- `x-rate-limit-remaining`: The number of requests remaining in the current rate limit window.
- `x-rate-limit-reset`: The time at which the current rate limit window resets in UTC epoch seconds.

When you reach the API quota limit, you will experience HTTP 429 errors, meaning you need to wait until the API quota reset. If you need need more quota, <a target="_blank" rel="noopener noreferrer" href="mailto:hello@microlink.io?subject=unavatar.io%20API%20key&amp;body=Hello%2C%0D%0A%0D%0AWe%20wanted%20unlimited%20usage%20for%20unavatar.io.%0D%0A%0D%0APlease%2C%20tell%20us%20how%20to%20proceed.">contact us</a>.

## Providers

With **unavatar.io**, you can retrieve user avatars based on an **email**, **domain**, or **username**.

The providers are grouped based on which kind of input they can resolve.

Based on that, a subset of providers will be used for resolving the user query, being the avatar resolved the fastest provider that resolve the query successfully.

Alternatively, you can query for an individual provider.

### DeviantArt

Type: `username`

It resolves user avatar against **deviantart.com**.

e.g., https://unavatar.io/deviantart/spyed

### Dribbble

Type: `username`

It resolves user avatar against **dribbble.com**.

e.g., https://unavatar.io/dribbble/omidnikrah

### DuckDuckGo

Type: `domain`

It resolves user avatar using **duckduckgo.com**.

e.g., https://unavatar.io/duckduckgo/gummibeer.dev

### GitHub

Type: `username`

It resolves user avatar against **github.com**.

e.g., https://unavatar.io/github/mdo

### Google

Type: `domain`

It resolves user avatar using **google.com**.

e.g., https://unavatar.io/google/netflix.com

### Gravatar

Type: `email`

It resolves user avatar against **gravatar.com**.

e.g., https://unavatar.io/gravatar/sindresorhus@gmail.com

### Instagram

Type: `username`

It resolves user avatar against **instagram.com**.

e.g., https://unavatar.io/instagram/willsmith

### Microlink

Type: `domain`

It resolves user avatar using **microlink.io**.

e.g., https://unavatar.io/microlink/microlink.io

### Read.cv

Type: `username`

It resolves user avatar against **read.cv**.

e.g., https://unavatar.io/readcv/elenatorro

### Reddit

Type: `username`

It resolves user avatar against **reddit.com**.

e.g., https://unavatar.io/reddit/kikobeats

### SoundCloud

Type: `username`

It resolves user avatar against **soundcloud.com**.

e.g., https://unavatar.io/soundcloud/gorillaz

### Substack

Type: `username`

It resolves user avatar against **substack.com**.

e.g., https://unavatar.io/substack/bankless

### Telegram

Type: `username`

It resolves user avatar against **telegram.com**.

e.g., https://unavatar.io/telegram/drsdavidsoft

### Twitter

Type: `username`

It resolves user avatar against **twitter.com**.

e.g., https://unavatar.io/twitter/kikobeats

### YouTube

Type: `username`

It resolves user avatar against **youtube.com**.

e.g., https://unavatar.io/youtube/casey
Loading