Skip to content

Commit

Permalink
Merge pull request #96 from Automattic/maxime/url-utils
Browse files Browse the repository at this point in the history
First version of @gravatar-com/url-utils
  • Loading branch information
maxme authored Oct 7, 2024
2 parents cde0d76 + 6b1d6fc commit aacc7bc
Show file tree
Hide file tree
Showing 15 changed files with 842 additions and 0 deletions.
3 changes: 3 additions & 0 deletions web/packages/url-utils/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist

11 changes: 11 additions & 0 deletions web/packages/url-utils/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
extends: [ 'plugin:@wordpress/eslint-plugin/recommended' ],
plugins: [ 'prettier' ],
rules: {
'prettier/prettier': [ 'error', require( './.prettierrc.js' ) ], // Uses our .prettierrc.js config
},
};
2 changes: 2 additions & 0 deletions web/packages/url-utils/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
21 changes: 21 additions & 0 deletions web/packages/url-utils/.markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"default": true,
"MD003": {
"style": "atx"
},
"MD007": {
"indent": 4
},
"MD013": {
"line_length": 9999
},
"MD024": {
"allow_different_nesting": true
},
"MD033": {
"allowed_elements": [ "img" ]
},
"MD041": false,
"no-hard-tabs": false,
"whitespace": false
}
4 changes: 4 additions & 0 deletions web/packages/url-utils/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
...require( '@wordpress/prettier-config' ),
printWidth: 120,
};
195 changes: 195 additions & 0 deletions web/packages/url-utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Gravatar Url Utils

A set of utility function to generate Gravatar Avatar or Profile URLs.

## Quickstart

### Install with npm

Add the package to your project:

```sh
npm install --save @gravatar-com/url-utils
```

### Install with UNPKG

For Vanilla JavaScript, import the library as shown below:

```html
<!-- Import the url-utils library -->
<script src="https://unpkg.com/@gravatar-com/[email protected]" defer></script>

<script>
// The library is accessible as a global variable "GravatarUrlUtils"
console.log( GravatarUrlUtils.avatarUrl('[email protected]') );
</script>
```

### Usage

```js
import { avatarUrl, profileUrl } from '@gravatar-com/url-utils';

avatarUrl( '[email protected]', { size: 500 } );
// https://www.gravatar.com/avatar/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a?size=500

profileUrl( '[email protected]' );
// https://www.gravatar.com/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a
```

### Documentation

#### `avatarUrl`

Generates a Gravatar avatar URL for the given email.

##### Parameters

- `email` (string): The email address for which to generate the avatar URL.
- `options` (GravatarAvatarOptions): Optional settings for the avatar URL.
- `size` (number): The size of the avatar in pixels.
- `default` (string): The default image to use if no Gravatar is found.
- `rating` (string): The rating of the avatar (e.g., `g`, `pg`, `r`, `x`).
- `forcedefault` (boolean): Force the default image to always load.

##### Returns

- (string): The generated Gravatar avatar URL.

##### Example

```ts
avatarUrl( '[email protected]' );
// https://www.gravatar.com/avatar/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a

avatarUrl( '[email protected]', { size: 500 } );
// https://www.gravatar.com/avatar/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a?size=500

avatarUrl( '[email protected]', { size: 500, default: GravatarDefault.Robohash } );
// https://www.gravatar.com/avatar/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a?size=500&default=robohash

avatarUrl( '[email protected]', { size: 500, default: 'robohash' } );
// https://www.gravatar.com/avatar/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a?size=500&default=robohash
```

#### `profileUrl`

Generates a Gravatar profile URL for the given email.

##### Parameters

- `email` (string): The email address for which to generate the profile URL.
- `format` (GravatarFormat): The format of the profile data. Defaults to `GravatarFormat.HTML`,
- `GravatarFormat.HTML`: Returns the profile in HTML format.
- `GravatarFormat.JSON`: Returns the profile in JSON format.
- `GravatarFormat.XML`: Returns the profile in XML format.
- `GravatarFormat.QR`: Returns the profile as a QR code.
- `GravatarFormat.VCF`: Returns the profile as a VCF file.

##### Returns

- (string): The generated Gravatar profile URL. HTML returns the link to the user's profile, while JSON, XML, and QR return the profile data in the specified format.

##### Example

```ts
profileUrl( '[email protected]' );
// https://www.gravatar.com/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a

profileUrl( '[email protected]', GravatarFormat.QR );
// https://www.gravatar.com/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a.qr

profileUrl( '[email protected]', 'qr');
// https://www.gravatar.com/259b65833bbadfd58ee66dde290489a6e51518339de4886d2331027751f0913a.qr
```

Check out the [unit tests if you want to see more examples](tests/index.test.ts).

### Example React component

Example use with a React component:

```typescript
import { avatarUrl } from '@gravatar-com/url-utils';

interface GravatarProps {
email: string;
size?: number;
}

const Gravatar = ( { email, size }: GravatarProps ) => {
return (
<img
src={ avatarUrl( email, size ? { size: size } : null ) }
alt="User Avatar"
width={ size }
height={ size }
/>
);
};

export default Gravatar;
```

Use it like this:

```html
<Gravatar email="[email protected]" />
<Gravatar email="[email protected]" size={500} />
```

### Methods

```js
avatarUrl(email, options: GravatarOptions)
```

```js
profileUrl(email, format: GravatarFormat)
```

## Contribute

Project directory structure:

```sh
.
├── README.md # You are here
├── dist # Output files (js and types)
├── lint-staged.config.js
├── package.json
├── src # Code
│   ├── cli.ts # Very basic cli tool
│   └── index.ts # The main library
├── tests # Unit tests, you should proabaly start here
│   └── index.test.ts
├── webpack # Webpack config
├── tsconfig.json
└── babel.config.ts
```

### Build

Build the Javascript files from Typescript:

```sh
npm run build
```

Then you can run the command line tool:

```sh
npm exec -- gravatar --avatar [email protected]
npm exec -- gravatar --profile [email protected]
```

### Run tests

```sh
npm run test
```

## License

Gravatar Hovercards is licensed under [GNU General Public License v2 (or later)](../../../docs/LICENSE.md).
13 changes: 13 additions & 0 deletions web/packages/url-utils/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
'@babel/typescript',
],
};
5 changes: 5 additions & 0 deletions web/packages/url-utils/lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
'*.{js,jsx,ts,tsx}': [ () => 'npm run type-check', 'npm run lint:js' ],
'*.md': 'npm run lint:md',
'*.{js,jsx,ts,tsx,json,yaml,yml}': 'npm run format',
};
62 changes: 62 additions & 0 deletions web/packages/url-utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@gravatar-com/url-utils",
"description": "A utility library for generating Gravatar URLs.",
"homepage": "https://github.com/Automattic/gravatar/blob/trunk/web/packages/url-utils#readme",
"bugs": "https://github.com/Automattic/gravatar/issues",
"repository": "https://github.com/Automattic/gravatar/blob/trunk/web/packages/url-utils",
"version": "0.0.1",
"author": "Automattic Inc.",
"license": "GPL-2.0-or-later",
"keywords": [
"gravatar",
"url",
"utils",
"avatar"
],
"bin": {
"gravatar": "dist/cli.js"
},
"scripts": {
"test:unit": "wp-scripts test-unit-js",
"test:unit:help": "wp-scripts test-unit-js --help",
"test:unit:watch": "wp-scripts test-unit-js --watch",
"test:unit:debug": "wp-scripts --inspect-brk test-unit-js --runInBand --no-cache",
"format": "wp-scripts format",
"lint:js": "wp-scripts lint-js",
"lint:md": "wp-scripts lint-md-docs",
"lint": "run-p 'lint:*'",
"type-check": "tsc --noEmit",
"build": "npm run clean:dist && run-p 'build:types' 'build:core'",
"build:core": "webpack --config ./webpack/config.core.js --node-env=production",
"build:types": "tsc --declaration --declarationMap --emitDeclarationOnly",
"build:dev": "npm run clean:dist && run-p 'build:types' 'build:core --node-env=development'",
"build:watch": "npm run build:dev && watch 'npm run build:dev' ./src",
"clean:dist": "rimraf dist",
"clean:release": "rimraf release",
"clean": "run-p 'clean:*'",
"release": "release-it"
},
"files": [
"dist",
"README.md"
],
"types": "dist/index.d.ts",
"main": "dist/index.js",
"module": "dist/index.mjs",
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/node": "^22.6.1",
"lint-staged": "^15.2.10",
"release-it": "^17.4.0",
"rimraf": "^5.0.1",
"typescript": "^5.1.6",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"@babel/preset-typescript": "^7.24.7",
"js-sha256": "^0.11.0",
"terser-webpack-plugin": "^5.3.10",
"webpack-remove-empty-scripts": "^1.0.4"
}
}
34 changes: 34 additions & 0 deletions web/packages/url-utils/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env node
/* eslint-disable no-console */

import { avatarUrl, profileUrl } from '.';

function main() {
const args = process.argv.slice( 2 );

if ( args.length === 0 || args.includes( '--help' ) || args.includes( '-h' ) ) {
console.log( 'Usage: cli [options] <email>' );
console.log( 'Options:' );
console.log( ' --help, -h Show help' );
console.log( ' --avatar, -a Get avatar URL' );
console.log( ' --profile, -p Get profile URL' );
process.exit( 0 );
}

const email = args.find( ( arg ) => ! arg.startsWith( '-' ) );

if ( ! email ) {
console.error( 'You need to provide an email address' );
process.exit( 1 );
}

if ( args.includes( '--avatar' ) || args.includes( '-a' ) ) {
console.log( avatarUrl( email ) );
}

if ( args.includes( '--profile' ) || args.includes( '-p' ) ) {
console.log( profileUrl( email ) );
}
}

main();
Loading

0 comments on commit aacc7bc

Please sign in to comment.