Skip to content

Commit 6201cdf

Browse files
committed
init
1 parent 7b0651f commit 6201cdf

File tree

9 files changed

+234
-0
lines changed

9 files changed

+234
-0
lines changed

.babelrc

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"modules": false,
7+
"loose": true
8+
}
9+
]
10+
],
11+
"env": {
12+
"test": {
13+
"presets": [
14+
[
15+
"@babel/preset-env",
16+
{
17+
"targets": "current node",
18+
"loose": true
19+
}
20+
]
21+
]
22+
}
23+
}
24+
}

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
commonjs/
3+
umd/
4+
es/
5+
esnext/
6+
coverage/
7+
.idea

README.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Semint
2+
3+
Semint is a small lib to encode/decode SemVer to/from integer.
4+
5+
# Install
6+
7+
```bash
8+
$ npm install -S @redtea/semint
9+
```
10+
11+
# Usage
12+
13+
```js
14+
// lib also support umd
15+
import {encode, decode, isValid} from 'semint';
16+
17+
// first argument is semver in string representation and second argument is max decimals numbers to encode one part of semver
18+
encode('1.1.1', 1); // 1 1 1
19+
encode('1.1.1', 2); // 1 01 01
20+
encode('1.1.1', 3); // 1 001 001
21+
encode('999.999.999', 3); // 999 999 999
22+
23+
// first argument is semver in number representation and second argument is the same as for `encode`
24+
decode(999999999, 3); // '999.999.999'
25+
26+
// `encode` and `decode` function use `isValid` to validate input and throw error if it is not valid
27+
isValid(999999999, 3); // true
28+
isValid(999999999, 1); // false
29+
isValid('999.999.999', 3); // true
30+
isValid('999.999.999', 1); // false
31+
isValid('999.999.999-1', 3); // false
32+
isValid('999.999.', 3); // false
33+
```
34+

rollup.config.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import babel from 'rollup-plugin-babel';
2+
import uglify from 'rollup-plugin-uglify';
3+
import pkg from './package.json';
4+
5+
6+
export default [
7+
{
8+
input: 'esnext/index.js',
9+
output: {
10+
name: 'Wod',
11+
file: pkg.main,
12+
format: 'umd',
13+
exports: 'named'
14+
},
15+
plugins: [
16+
babel({
17+
exclude: ['node_modules/**'],
18+
runtimeHelpers: true
19+
}),
20+
uglify()
21+
]
22+
},
23+
{
24+
input: 'esnext/index.js',
25+
output: [
26+
{
27+
file: pkg.module,
28+
format: 'es'
29+
}
30+
],
31+
plugins: [
32+
babel({
33+
exclude: ['node_modules/**'],
34+
runtimeHelpers: true
35+
})
36+
]
37+
}
38+
];

src/index.ts

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
export function isValid(semver: string | number, decimals = 4): boolean {
2+
if (decimals < 1) {
3+
return false;
4+
}
5+
6+
if (typeof semver === 'string') {
7+
const rx = new RegExp(`^${new Array(3).fill(`\\d{1,${decimals}}`).join('\\.')}$`);
8+
9+
return rx.test(semver);
10+
} else if (typeof semver === 'number') {
11+
return semver >= 0 && semver < 10 ** (decimals * 3) && semver % 1 === 0;
12+
}
13+
14+
return false;
15+
}
16+
17+
export function encode(semver: string, decimals = 4): number {
18+
if (!isValid(semver, decimals)) {
19+
throw new Error('not valid arguments');
20+
}
21+
22+
const one = 10 ** decimals;
23+
const parts = semver.split('.').map(Number);
24+
25+
let result = 0, mul = 1;
26+
27+
while (parts.length) {
28+
const part = parts.pop() as number;
29+
30+
result += part * mul;
31+
mul *= one;
32+
}
33+
34+
return result;
35+
}
36+
37+
export function decode(semver: number, decimals = 4): string {
38+
if (!isValid(semver, decimals)) {
39+
throw new Error('not valid arguments');
40+
}
41+
42+
const one = 10 ** decimals;
43+
44+
let result = [0, 0, 0], idx = 2, div = 1;
45+
46+
while(semver !== 0) {
47+
result[idx] = semver % one;
48+
semver = (semver - result[idx]) / one;
49+
idx--;
50+
}
51+
52+
return result.join('.');
53+
}

test/semint.spec.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {expect} from 'chai';
2+
import {
3+
encode,
4+
decode,
5+
isValid
6+
} from '../esnext';
7+
8+
describe('isValid', () => {
9+
it('should be false', () => {
10+
expect(isValid('1.1.1', 0)).to.be.false;
11+
expect(isValid('1.1.', 1)).to.be.false;
12+
expect(isValid('1.1.12', 1)).to.be.false;
13+
expect(isValid('1.1.1.1', 1)).to.be.false;
14+
expect(isValid('1.1.1-a', 1)).to.be.false;
15+
expect(isValid('1.12.1-a', 1)).to.be.false;
16+
});
17+
18+
it('should be true', () => {
19+
expect(isValid('1.1.1', 1)).to.be.true;
20+
expect(isValid('0.0.1', 1)).to.be.true;
21+
expect(isValid('12.1.1', 2)).to.be.true;
22+
});
23+
});
24+
25+
describe('encode', () => {
26+
it('should throw error', () => {
27+
expect(() => encode('1', 1)).to.throw('not valid arguments');
28+
});
29+
30+
it('should encode', () => {
31+
expect(encode('0.0.0', 1)).to.be.eq(0);
32+
expect(encode('0.0.1', 1)).to.be.eq(1);
33+
expect(encode('0.1.1', 1)).to.be.eq(11);
34+
expect(encode('1.1.1', 1)).to.be.eq(111);
35+
expect(encode('1.1.1', 2)).to.be.eq(10101);
36+
});
37+
});
38+
39+
describe('decode', () => {
40+
it('should throw error', () => {
41+
expect(() => decode(1111, 1)).to.throw('not valid arguments');
42+
});
43+
44+
it('should decode', () => {
45+
expect(decode(0, 1)).to.be.eq('0.0.0');
46+
expect(decode(1, 1)).to.be.eq('0.0.1');
47+
expect(decode(11, 1)).to.be.eq('0.1.1');
48+
expect(decode(111, 1)).to.be.eq('1.1.1');
49+
expect(decode(10101, 2)).to.be.eq('1.1.1');
50+
});
51+
});

tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"module": "es2015",
4+
"target": "es6",
5+
"strict": true,
6+
"baseUrl": "src",
7+
"outDir": "esnext",
8+
"esModuleInterop": true
9+
},
10+
"exclude": [
11+
"node_modules",
12+
"test",
13+
"types"
14+
]
15+
}

types/index.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export declare function isValid(semver: string | number, decimals?: number): boolean;
2+
export declare function encode(semver: string, decimals?: number): number;
3+
export declare function decode(semver: number, decimals?: number): string;

0 commit comments

Comments
 (0)