Skip to content

Commit

Permalink
Merge pull request #4 from chukwumaijem/feature/get-gravatar-url
Browse files Browse the repository at this point in the history
Basic Gravatar URL
  • Loading branch information
Chukwuma Ezumezu committed May 2, 2020
2 parents 8c3f9e4 + 035c51d commit 42f2ce4
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120
}
65 changes: 64 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,69 @@
# JS Gravatar

[![npm package](https://img.shields.io/npm/v/js-gravatar.svg?style=flat-square)](https://www.npmjs.org/package/js-gravatar) ![](https://github.com/chukwumaijem/js-gravatar/workflows/Run%20Testt/badge.svg) ![](https://github.com/chukwumaijem/js-gravatar/workflows/Publish%20To%20NPM/badge.svg)
[![npm package](https://img.shields.io/npm/v/js-gravatar.svg?style=flat-square)](https://www.npmjs.org/package/js-gravatar) ![](https://github.com/chukwumaijem/js-gravatar/workflows/Run%20Test/badge.svg) ![](https://github.com/chukwumaijem/js-gravatar/workflows/Publish%20To%20NPM/badge.svg)

[Demo](https://codepen.io/chukwuma-ezumezu/pen/qYKOGW)

## Vanilla JS

Copy dist/js-gravatar.js into your library folder
Load it into your HTML script

```html
<script type="text/javascript" src="path/to/js-gravatar.js"></script>
```

You can use the [UNPKG](https://unpkg.com) link `https://unpkg.com/js-gravatar@1.0.1/dist/js-gravatar.js`. Remember to update the package number to the most recent.

Call the method with its options.

```js
JsGravatar({ element, numberOfDice: 2, callback });
```

## With npm (and CommonJS builder)

Install with npm.

```sh
npm install --save js-gravatar
```

Install with yarn.

```sh
yarn add js-gravatar
```

import the library

ES5

```js
const JsGravatar = require('js-gravatar');
```

ES6

```js
import JsGravatar from 'js-gravatar';
```

Call the method

```js
JsGravatar({ email: 'user@email.com', size: 10, defaultImage: 'identicon' });
JsGravatar({ email: 'user@email.com', defaultImage: 'monsterid' });
```

## Parameter Definitions

- `email`: Email address of the user to generate gravatar for - string
- `md5Hash`: Optional: MD5 hash of the email above. If email is provided, md5hash will be ignored. If neither email nor md5hash is provided, the library will throw en error - string
- `size`: Optional: The size of the image to be displayed. Should be from 1 to 2048 - number
- `defaultImage`: What image should be used if email does not have a gravatar. See options below - string

Defaultimage Options - ['404', 'mp', 'identicon', 'monsterid', 'wavatar', 'retro', 'robohash', 'blank']

## License

Expand Down
42 changes: 42 additions & 0 deletions lib/js-gravatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import md5 from 'md5';
import { Types, Errors } from './types';

export function validateOptions(options) {
const { email, md5Hash, size, defaultImage } = options;
if (!email && !md5Hash) throw new Error(Errors.MISSING_ARGUMENT_ERROR('email or md5Hash'));

if (size && Number.isNaN(Number(size))) throw new Error(Errors.INVALID_ARGUMENT_TYPE(size, 'number'));

if (size > 2048 || size < 1) throw new Error(Errors.IMAGE_SIZE_ERROR);

if (defaultImage && !Types.GRAVATAR_DEFAULTS.includes(defaultImage)) throw new Error(Errors.DEFAULT_IMAGE_ERROR);
}

function getMd5Hash(options) {
const { email, md5Hash } = options;
if (md5Hash) return md5Hash;

return md5(email.trim().toLowerCase());
}

export function buildQueryStringFromOptions(options) {
const { size, defaultImage } = options;
let queryString = '?';
if (size) queryString += `s=${size}&`;
if (defaultImage) queryString += `d=${defaultImage}&`;

if (queryString.endsWith('&') || queryString.endsWith('?')) {
return queryString.substr(0, queryString.length - 1);
}
return queryString;
}

function jsGravatar(options) {
validateOptions(options);
const emailHash = getMd5Hash(options);
const queryString = buildQueryStringFromOptions(options);

return `${Types.BASE_URL}/${emailHash}${queryString}`;
}

export default jsGravatar;
18 changes: 18 additions & 0 deletions lib/types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const Types = {
BASE_URL: (() => {
const protocol = window.location.protocol;
const gravatar_url = '//www.gravatar.com/avatar';
if (protocol !== 'https:') {
return `http:${gravatar_url}`;
}
return `https:${gravatar_url}`;
})(),
GRAVATAR_DEFAULTS: ['404', 'mp', 'identicon', 'monsterid', 'wavatar', 'retro', 'robohash', 'blank'],
};

export const Errors = {
MISSING_ARGUMENT_ERROR: (arg) => `${arg} is required but was not provided.`,
INVALID_ARGUMENT_TYPE: (arg, type) => `${arg} is expected to be of type ${type}, but received ${typeof arg}`,
DEFAULT_IMAGE_ERROR: `defaultImage can only be oneOf: ${Types.GRAVATAR_DEFAULTS.join(',')}`,
IMAGE_SIZE_ERROR: 'Size should not be greater than 2048 or less than 1.',
};
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "js-gravatar",
"version": "1.0.1",
"description": "A JS lirary to get a users gravatar and if it doesn't exist provides custom avatar",
"description": "A vanilla JS library to get a user's gravatar and if it doesn't exist provides one different from gravatar default",
"main": "dist/js-gravatar.js",
"scripts": {
"test": "node_modules/.bin/jest",
Expand Down Expand Up @@ -36,8 +36,11 @@
"@babel/core": "^7.8.7",
"@babel/preset-env": "^7.8.7",
"babel-loader": "^8.0.6",
"jest": "^25.1.0",
"jest": "^25.5.4",
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11"
},
"dependencies": {
"md5": "^2.2.1"
}
}
23 changes: 23 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS Gravatar - Demo</title>
</head>

<body>
<div>
<img id="image" />
</div>

<script src="../dist/js-gravatar.js"></script>
<script>
const imageSrc = jsGravatar({ email: 'user@email.com', defaultImage: 'identicon' });
const image = document.getElementById('image');
image.src = imageSrc;
</script>
</body>

</html>
40 changes: 37 additions & 3 deletions tests/js_gravatar.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
import jsGravatar, { buildQueryStringFromOptions, validateOptions } from '../lib/js-gravatar';
import { Types, Errors } from '../lib/types';

describe('JS Gravatar', function () {
it('1 + 1 should be 2', () => {
expect(1 + 1).toEqual(2);
describe('Throws an error', function () {
it('for missing email and md5hash', function () {
expect(() => validateOptions({ defaultImage: '404' })).toThrow(Errors.MISSING_ARGUMENT_ERROR('email or md5Hash'));
});

it('for invalid size options.', function () {
expect(() => validateOptions({ email: 'user@email.com', size: 0 })).toThrow(Errors.IMAGE_SIZE_ERROR);
expect(() => validateOptions({ email: 'user@email.com', size: 2049 })).toThrow(Errors.IMAGE_SIZE_ERROR);
});

it('for unexpected default image.', function () {
expect(() => validateOptions({ email: 'user@email.com', defaultImage: 'not-available' })).toThrow(
Errors.DEFAULT_IMAGE_ERROR,
);
});
});
});

describe('Correctly generates url query string', function() {
const size = 200;
const defaultImage = '404';

it('when only one property is supplied.', function () {
expect(buildQueryStringFromOptions({ size })).toBe(`?s=${size}`);
expect(buildQueryStringFromOptions({ defaultImage })).toBe(`?d=${defaultImage}`);
});

it('when both size and defaultImage are supplied.', function () {
expect(buildQueryStringFromOptions({ defaultImage, size })).toBe(`?s=${size}&d=${defaultImage}`);
});

it('when no property is available.', function () {
expect(buildQueryStringFromOptions({})).toBe('');
});
});
});
4 changes: 2 additions & 2 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
const path = require('path');

const BUILD_DIR = path.resolve(__dirname, 'dist/');
const APP_DIR = path.resolve(__dirname, 'js/');
const APP_DIR = path.resolve(__dirname, 'lib/');

const config = {
entry: APP_DIR + '/js-gravatar.js',
output: {
path: BUILD_DIR,
filename: 'js-gravatar.js',
publicPath: 'dist/',
library: 'js-gravatar',
library: 'jsGravatar',
libraryExport: 'default',
libraryTarget: 'umd',
},
Expand Down

0 comments on commit 42f2ce4

Please sign in to comment.