Skip to content

Commit 6dab332

Browse files
committed
Merge branch 'release/v1.0.0'
2 parents 711e859 + d56dbe0 commit 6dab332

File tree

10 files changed

+4492
-2
lines changed

10 files changed

+4492
-2
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["@babel/preset-env"]
3+
}

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
coverage/*
2+
build
3+
node_modules

.eslintrc.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": [
3+
"eslint:recommended"
4+
],
5+
"parserOptions": {
6+
"sourceType": "module"
7+
},
8+
"env": {
9+
"jest": true,
10+
"es6": true
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Build, test and lint
2+
on:
3+
push:
4+
branches:
5+
- master
6+
- develop
7+
pull_request:
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: actions/setup-node@v2
14+
with:
15+
node-version: '12.x'
16+
- run: yarn install
17+
- run: yarn test
18+
- run: yarn lint
19+
- run: yarn build

.github/workflows/publish.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Node.js Package
2+
on:
3+
release:
4+
types: [published]
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
# Setup .npmrc file to publish to npm
11+
- uses: actions/setup-node@v2
12+
with:
13+
node-version: '12.x'
14+
registry-url: 'https://registry.npmjs.org'
15+
- run: yarn install
16+
- run: yarn test
17+
- run: yarn lint
18+
- run: yarn build
19+
- run: yarn publish
20+
env:
21+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

README.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,25 @@
1-
# doi-prop-type
2-
DOI React Prop Type
1+
# DOI Prop Type
2+
3+
[![Build](https://github.com/OpenBookPublishers/doi-prop-type/actions/workflows/build_test_and_check.yml/badge.svg)](https://github.com/OpenBookPublishers/doi-prop-type/actions/workflows/build_test_and_check.yml)
4+
[![npm](https://img.shields.io/npm/v/doi-prop-type.svg)](https://www.npmjs.com/package/doi-prop-type)
5+
![GitHub](https://img.shields.io/github/license/OpenBookPublishers/doi-prop-type)
6+
7+
This package is used to validate if a React Prop value is a valid DOI, e.g. `10.11647/obp.0229`. To do so we compare the input against this regex: `/^10.\d{4,9}\/[-._\;\(\)\/:a-zA-Z0-9]+$/g`.
8+
9+
The [`prop-types` package](https://www.npmjs.com/package/prop-types) does not support a DOI prop type, therefore you can use this package to validate them, instead of using the permissive `PropType.string`.
10+
11+
## Installation
12+
`npm install --save doi-prop-type`
13+
14+
## Example Usage
15+
```javascript
16+
import React from 'react';
17+
import doiPropType from 'doi-prop-type';
18+
19+
// Create a generic component
20+
const Doi = props => ( <a href={`https://doi.org/${props.doi}`}>{props.doi}</a> );
21+
22+
Doi.propTypes = {
23+
link: doiPropType.isRequired, // can also specify doiPropType if it is not required
24+
};
25+
```

lib/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const isDoi = (value) => {
2+
return /^10.\d{4,9}\/[-._;()/:a-zA-Z0-9]+$/g.test(value);
3+
}
4+
5+
const requiredDoiPropType = (props, propName, componentName) => {
6+
const value = props[propName];
7+
8+
if (value == null || typeof value !== 'string' || !isDoi(value)) {
9+
return new TypeError(`Invalid DOI Prop Value: ${value} for ${propName} in ${componentName}`);
10+
}
11+
12+
return null;
13+
};
14+
15+
const doiPropType = (props, propName, componentName) => {
16+
if (props[propName] == null) {
17+
return null;
18+
}
19+
20+
return requiredDoiPropType(props, propName, componentName);
21+
};
22+
23+
doiPropType.isRequired = requiredDoiPropType;
24+
25+
export default doiPropType;

lib/index.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import doiPropType from './index';
2+
3+
describe('DOI Prop Type', () => {
4+
const propName = 'someproperty';
5+
const componentName = 'somecomponent';
6+
const validDoi = '10.11647/obp.0226';
7+
const invalidDoi = '10:11647/OBP.0226?%98.leon';
8+
const nonStringDoi = 10.001;
9+
10+
describe('doiPropType', () => {
11+
it('should throw an error if prop value is not a string', () => {
12+
const props = {};
13+
props[propName] = nonStringDoi;
14+
expect(doiPropType(props, propName, componentName))
15+
.toEqual(new TypeError(`Invalid DOI Prop Value: ${nonStringDoi} for ${propName} in ${componentName}`));
16+
});
17+
18+
it('should throw an error if prop value is not a valid DOI', () => {
19+
const props = {};
20+
props[propName] = invalidDoi;
21+
expect(doiPropType(props, propName, componentName))
22+
.toEqual(new TypeError(`Invalid DOI Prop Value: ${invalidDoi} for ${propName} in ${componentName}`));
23+
});
24+
25+
it('should return null if prop value is a valid DOI', () => {
26+
const props = {};
27+
props[propName] = validDoi;
28+
expect(doiPropType(props, propName, componentName)).toBeNull();
29+
});
30+
31+
it('should return null if prop is not defined', () => {
32+
const props = {};
33+
expect(doiPropType(props, propName, componentName)).toBeNull();
34+
});
35+
});
36+
37+
describe('validateRequiredDoi', () => {
38+
it('should throw an error if prop value is not a valid DOI', () => {
39+
const props = {};
40+
props[propName] = invalidDoi;
41+
expect(doiPropType.isRequired(props, propName, componentName))
42+
.toEqual(new TypeError(`Invalid DOI Prop Value: ${invalidDoi} for ${propName} in ${componentName}`));
43+
});
44+
45+
it('should throw an error if prop is not defined', () => {
46+
const props = {};
47+
expect(doiPropType.isRequired(props, propName, componentName))
48+
.toEqual(new TypeError(`Invalid DOI Prop Value: undefined for ${propName} in ${componentName}`));
49+
});
50+
});
51+
});

package.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "doi-prop-type",
3+
"version": "1.0.0",
4+
"description": "React Prop Types DOI Validator",
5+
"main": "./dist/index.js",
6+
"scripts": {
7+
"codecov": "codecov",
8+
"test": "jest",
9+
"build": "babel -d dist/ lib/ --ignore \"**/*.test.js\"",
10+
"lint": "eslint --ext .js .",
11+
"clean": "rm -rf dist/"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "git+https://github.com/OpenBookPublishers/doi-prop-type.git"
16+
},
17+
"keywords": [
18+
"react",
19+
"prop-types"
20+
],
21+
"author": "Javier Arias <javi@openbookpublishers.com>",
22+
"license": "MIT",
23+
"bugs": {
24+
"url": "https://github.com/OpenBookPublishers/doi-prop-type/issues"
25+
},
26+
"homepage": "https://github.com/OpenBookPublishers/doi-prop-type#readme",
27+
"devDependencies": {
28+
"@babel/cli": "^7.8.4",
29+
"@babel/core": "^7.8.4",
30+
"@babel/preset-env": "^7.8.4",
31+
"codecov": "^3.8.3",
32+
"eslint": "^6.8.0",
33+
"eslint-config-airbnb-base": "^14.0.0",
34+
"eslint-plugin-import": "^2.20.1",
35+
"jest": "^27.4.3"
36+
}
37+
}

0 commit comments

Comments
 (0)