Skip to content

Commit 89b8230

Browse files
committed
feat: Add predicates
0 parents  commit 89b8230

20 files changed

+8447
-0
lines changed

.eslintrc.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module.exports = {
2+
extends: [
3+
'@mll-lab/eslint-config',
4+
'plugin:@mll-lab/recommended',
5+
],
6+
plugins: [],
7+
ignorePatterns: ['dist'],
8+
env: {
9+
jest: true,
10+
browser: true,
11+
node: true,
12+
es6: true,
13+
},
14+
parserOptions: {
15+
ecmaVersion: 6,
16+
sourceType: 'module',
17+
project: ['./tsconfig.eslint.json'],
18+
},
19+
rules: {
20+
'@typescript-eslint/switch-exhaustiveness-check': 'error',
21+
'default-case': 'off', // Replaced by @typescript-eslint/switch-exhaustiveness-check
22+
'import/no-unresolved': 'off',
23+
},
24+
settings: {
25+
'import/extensions': ['.js', '.ts'],
26+
},
27+
};

.github/workflows/format.yml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: "Format"
2+
on:
3+
push:
4+
5+
jobs:
6+
eslint:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
with:
11+
ref: ${{ github.head_ref }}
12+
- uses: actions/setup-node@v2
13+
- run: yarn install
14+
- run: yarn run format
15+
- uses: stefanzweifel/git-auto-commit-action@v4
16+
with:
17+
commit_message: "refactor: Apply eslint fix"

.github/workflows/release.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: "Release"
2+
on:
3+
push:
4+
branches:
5+
- master
6+
jobs:
7+
# https://docs.github.com/en/actions/guides/publishing-nodejs-packages#publishing-packages-using-yarn
8+
# https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/github-actions.md
9+
package:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: actions/setup-node@v2
14+
- run: yarn install
15+
- run: yarn run build
16+
- run: npx semantic-release
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/validate.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: "Validate"
2+
on:
3+
pull_request:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
typecheck:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: actions/setup-node@v2
14+
- run: yarn install
15+
- run: yarn run typecheck
16+
17+
lint:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v2
21+
- uses: actions/setup-node@v2
22+
- run: yarn install
23+
- run: yarn run lint
24+
25+
test:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v2
29+
- uses: actions/setup-node@v2
30+
- run: yarn install
31+
- run: yarn run test
32+
33+
build:
34+
runs-on: ubuntu-latest
35+
steps:
36+
- uses: actions/checkout@v2
37+
- uses: actions/setup-node@v2
38+
- run: yarn install
39+
- run: yarn run build

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules/
2+
dist/
3+
storybook-static/
4+
*.log
5+
.idea

.prettierrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('@mll-lab/prettier-config');

CONTRIBUTING.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Commit Messages
2+
3+
We use [semantic-release](https://github.com/semantic-release/semantic-release) to automatically generate
4+
- version number
5+
- changelog
6+
- releases
7+
8+
This requires to write commit messages that follow the [Angular commit message format](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-format).
9+
10+
Merge requests with a lot of intermediary commits must be cleaned up by force pushing rewritten commits.

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 MLL
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# @mll-lab/js-utils
2+
3+
[![npm](https://img.shields.io/npm/v/@mll-lab/js-utils)](https://www.npmjs.com/package/@mll-lab/js-utils)
4+
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
5+
6+
Shared JavaScript utilities of MLL
7+
8+
## Install
9+
10+
yarn add @mll-lab/js-utils
11+
12+
## Usage
13+
14+
Just import the functions you need and call them:
15+
16+
```typescript jsx
17+
import { isLabId } from '@mll-lab/js-utils';
18+
19+
isLabId('obviously not');
20+
```

babel.config.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
presets: ['@babel/preset-env'],
3+
plugins: [
4+
'@babel/plugin-transform-runtime',
5+
],
6+
};

jest.config.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
preset: 'ts-jest/presets/js-with-babel',
3+
roots: ['src'],
4+
moduleFileExtensions: ['ts', 'js', 'json'],
5+
testPathIgnorePatterns: ['node_modules/'],
6+
transform: {
7+
'^.+\\.ts$': 'ts-jest',
8+
},
9+
testMatch: ['**/*.test.ts'],
10+
};

package.json

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"name": "@mll-lab/js-utils",
3+
"version": "0.0.1",
4+
"module": "dist/index.js",
5+
"files": [
6+
"dist"
7+
],
8+
"types": "dist/index.d.ts",
9+
"description": "Shared JavaScript utilities of MLL",
10+
"scripts": {
11+
"build": "rollup --config",
12+
"test": "jest",
13+
"test:watch": "jest --watch",
14+
"typecheck": "tsc --noEmit",
15+
"lint": "eslint --ignore-path .gitignore --ext .ts .",
16+
"format": "yarn run lint --fix",
17+
"release": "standard-version"
18+
},
19+
"repository": {
20+
"type": "git",
21+
"url": "git+https://github.com/mll-lab/js-utils.git"
22+
},
23+
"keywords": [
24+
"js",
25+
"utils"
26+
],
27+
"author": "Benedikt Franke <[email protected]>",
28+
"license": "MIT",
29+
"bugs": {
30+
"url": "https://github.com/mll-lab/js-utils/issues"
31+
},
32+
"homepage": "https://github.com/mll-lab/js-utils",
33+
"peerDependencies": {
34+
"@babel/runtime": ">=7.13.6"
35+
},
36+
"devDependencies": {
37+
"@babel/core": "^7.13.1",
38+
"@babel/eslint-parser": "^7.13.14",
39+
"@babel/plugin-transform-runtime": "^7.13.6",
40+
"@babel/preset-env": "^7.13.0",
41+
"@babel/runtime": "^7.13.6",
42+
"@mll-lab/eslint-config": "^1.1.0",
43+
"@mll-lab/eslint-plugin": "^1.2.0",
44+
"@mll-lab/prettier-config": "^1.0.0",
45+
"@mll-lab/tsconfig": "^1.1.0",
46+
"@rollup/plugin-babel": "^5.3.0",
47+
"@rollup/plugin-commonjs": "^18.0.0",
48+
"@rollup/plugin-node-resolve": "^11.2.1",
49+
"@rollup/plugin-typescript": "^8.2.1",
50+
"@semantic-release/changelog": "^5.0.1",
51+
"@semantic-release/git": "^9.0.0",
52+
"@types/jest": "^26.0.20",
53+
"@types/node": "^14.14.31",
54+
"babel-jest": "^26.6.3",
55+
"babel-loader": "^8.2.2",
56+
"babel-plugin-require-context-hook": "^1.0.0",
57+
"jest": "^26.6.3",
58+
"prettier": "^2.2.1",
59+
"rollup": "^2.45.2",
60+
"rollup-plugin-peer-deps-external": "^2.2.4",
61+
"semantic-release": "^17.4.0",
62+
"ts-jest": "^26.5.1",
63+
"ts-loader": "^8.0.17",
64+
"ts-node": "^9.1.1",
65+
"typescript": "^4.1.3"
66+
}
67+
}

release.config.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
plugins: [
3+
'@semantic-release/commit-analyzer',
4+
'@semantic-release/release-notes-generator',
5+
'@semantic-release/npm',
6+
'@semantic-release/github',
7+
'@semantic-release/changelog',
8+
'@semantic-release/git',
9+
],
10+
};

rollup.config.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import babel from '@rollup/plugin-babel';
2+
import commonjs from '@rollup/plugin-commonjs';
3+
import resolve from '@rollup/plugin-node-resolve';
4+
import typescript from '@rollup/plugin-typescript';
5+
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
6+
7+
export default {
8+
input: 'src/index.ts',
9+
output: [
10+
{
11+
dir: 'dist',
12+
format: 'esm',
13+
sourcemap: true,
14+
},
15+
],
16+
17+
// this resolves to window in the browser, thus enabling caching in the antd code below
18+
// (!) `this` has been rewritten to `undefined`
19+
// https://rollupjs.org/guide/en/#error-this-is-undefined
20+
// node_modules/antd/es/affix/index.js
21+
// 7: import _typeof from "@babel/runtime/helpers/esm/typeof";
22+
// 8:
23+
// 9: var __decorate = this && this.__decorate || function (decorators, target, key, desc) {
24+
context: 'this',
25+
26+
plugins: [
27+
peerDepsExternal(),
28+
resolve(),
29+
commonjs(),
30+
typescript({
31+
exclude: '**/*.test.ts',
32+
}),
33+
babel({
34+
babelHelpers: 'runtime',
35+
}),
36+
],
37+
};

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './predicates';

src/predicates.test.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { isLabId, isRackBarcode, PredicateFn } from './predicates';
2+
3+
function assertInvalid(predicate: PredicateFn, values: Array<any>) {
4+
test.each(values)(`invalid values for ${predicate.name}`, (value) =>
5+
expect(predicate(value)).toBe(false),
6+
);
7+
}
8+
9+
function assertValid(predicate: PredicateFn, values: Array<any>) {
10+
test.each(values)(`valid values for ${predicate.name}`, (value) => {
11+
expect(predicate(value)).toBe(true);
12+
});
13+
}
14+
15+
describe('predicates', () => {
16+
describe('isLabId', () => {
17+
assertValid(isLabId, ['17-123456']);
18+
assertInvalid(isLabId, ['asdf', '12345678', '123123123123']);
19+
});
20+
21+
describe('isRackBarcode', () => {
22+
assertValid(isRackBarcode, ['FE12345678']);
23+
assertInvalid(isRackBarcode, ['FE123456789', 'fe12345678', '12345678']);
24+
});
25+
});

src/predicates.ts

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
export type PredicateFn = (value: unknown) => boolean;
2+
3+
export function isString(value: unknown): value is string {
4+
return typeof value === 'string';
5+
}
6+
7+
export const isAlphanumeric: PredicateFn = (value) =>
8+
isString(value) && /^[A-Za-z0-9]+$/.test(value);
9+
10+
/**
11+
* BSNR (Betriebsstättennummer) ist eine eindeutige Zuordnung von Leistungen zu dem entsprechenden Ort der Leistungserbringung ermöglicht,
12+
* für alle vertrags(zahn)ärztlichen Leistungserbringer gültig
13+
* und klar abzugrenzen vom Institutskennzeichen (IK-Nummer) eines Krankenhauses.
14+
*/
15+
export const isBSNR: PredicateFn = (value) =>
16+
isString(value) && /^\d{9}$/.test(value);
17+
18+
// Taken from https://emailregex.com/
19+
// eslint-disable-next-line no-useless-escape
20+
export const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
21+
22+
export const isEmail: PredicateFn = (value) =>
23+
isString(value) && EMAIL_REGEX.test(value);
24+
25+
export const isOnlyDigits: PredicateFn = (value) =>
26+
isString(value) && /^\d+$/.test(value);
27+
28+
export const isURL: PredicateFn = (value) => {
29+
if (!isString(value)) {
30+
return false;
31+
}
32+
33+
try {
34+
// Constructing the URL object throws on invalid values
35+
// eslint-disable-next-line no-new
36+
new URL(value);
37+
return true;
38+
} catch {
39+
return false;
40+
}
41+
};
42+
43+
export const isWord: PredicateFn = (value) =>
44+
isString(value) && /^[\w-]+$/.test(value);
45+
46+
export const isLabId: PredicateFn = (value) =>
47+
isString(value) && /^\d{2}-\d{6}$/.test(value);
48+
49+
export const isRackBarcode: PredicateFn = (value) =>
50+
isString(value) && /^[A-Z]{2}\d{8}$/.test(value);

tsconfig.eslint.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"include": ["src", "*.js", "*.ts"],
4+
"exclude": ["node_modules", "dist"]
5+
}

0 commit comments

Comments
 (0)