Skip to content

Commit 1a06e7d

Browse files
ryasmiht2
authored andcommitted
fix: Fixes IRI regex. (#45)
* fix: Fixes IRI regex. * test(iri): Adds tests for IRIs. * fix: Moves source map support to dev deps.
1 parent d15c7fc commit 1a06e7d

File tree

8 files changed

+94
-15
lines changed

8 files changed

+94
-15
lines changed

.gitignore

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.DS_STORE
2-
node_modules
3-
npm-debug.log
4-
typings
5-
coverage
6-
dist
2+
/.nyc_output
3+
/coverage
4+
/dist
5+
/node_modules
6+
/npm-debug.log
7+
/typings

package-lock.json

Lines changed: 32 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"commit": "git-cz",
1919
"build": "tsc",
2020
"test": "mocha dist/**/*.test.js --exit",
21-
"cover": "nyc --lines 95 --check-coverage npm run test",
21+
"cover": "nyc --lines 100 --check-coverage npm run test",
2222
"clean": "rimraf dist",
2323
"lint": "tslint --project ./tsconfig.json -c ./tslint.json",
2424
"duplication": "jscpd",
@@ -38,17 +38,19 @@
3838
"@types/lodash": "4.14.92",
3939
"@types/mocha": "2.2.46",
4040
"@types/node": "9.3.0",
41+
"@types/source-map-support": "0.4.0",
4142
"assert": "1.4.1",
4243
"commitizen": "2.9.6",
4344
"cz-conventional-changelog": "2.1.0",
4445
"jscpd": "0.6.17",
4546
"mocha": "4.1.0",
4647
"nyc": "11.4.1",
4748
"rimraf": "2.6.2",
49+
"source-map-support": "^0.5.0",
4850
"tslint": "5.8.0",
4951
"typescript": "2.6.2"
5052
},
5153
"publishConfig": {
5254
"access": "public"
5355
}
54-
}
56+
}

src/helpers/regex.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export const escapedChar = (char: string) => {
2+
return `\\${char}`;
3+
};
4+
5+
export const capturePattern = (pattern: string) => {
6+
return `(${pattern})`;
7+
};
8+
9+
export const delimitedPattern = (pattern: string, delimeter: string) => {
10+
return `(?:${pattern})(?:${escapedChar(delimeter)}${pattern})*`;
11+
};
12+
13+
export const prefixedPattern = (prefix: string, pattern: string) => {
14+
return `${escapedChar(prefix)}(${pattern})`;
15+
};
16+
17+
export const optionalPattern = (pattern: string) => {
18+
return `(?:${pattern})?`;
19+
};

src/index.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import * as sourceMapSupport from 'source-map-support';
2+
sourceMapSupport.install();
3+
14
import * as assert from 'assert';
25
import validateStatement from './index';
36
import { statement } from './tests/factory';

src/regexValues/iri.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
11
/* tslint:disable:max-line-length */
22
import { checkRegex, Rule } from 'rulr';
33
import { createTypeWarning } from '../warnings/TypeWarning';
4+
import {
5+
escapedChar,
6+
optionalPattern,
7+
capturePattern,
8+
delimitedPattern,
9+
prefixedPattern,
10+
} from '../helpers/regex';
411

5-
export default checkRegex(
6-
/^[a-z](?:[-a-z0-9\+\.])*:(?:\/\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:])*@)?(?:\[(?:(?:(?:[0-9a-f]{1,4}:){6}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|::(?:[0-9a-f]{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4}:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+[-a-z0-9\._~!\$&\'\(\)\*\+,;=:]+)\]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}|(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=@])*)(?::[0-9]*)?(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@]))*)*|\/(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@]))*)*)?|(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@])))(?:\?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@])|[\uE000-\uF8FF\u0000-\uFFFD|\u0000-\uFFFD\/\?])*)?(?:\#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\u0000-\uFFFD!\$&\'\(\)\*\+,;=:@])|[\/\?])*)?$/i
7-
, createTypeWarning('Internationalized Resource Identifier (IRI)')) as Rule;
12+
const normChars = `w_~!$&'()*+,;=:-@`.split('').map(escapedChar).join('');
13+
const otherChars = '\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF\\uFFEF-\\uFFFD';
14+
const allChars = `[${normChars}${otherChars}]`;
15+
const allCharsWithDot = `(?:${allChars}|\\.)`;
16+
const extChars = `(?:${allChars}|(?:\\%[a-f0-9][a-f0-9]))`;
17+
18+
const scheme = `(?:(\\w+):\\/\\/)`;
19+
const authority = optionalPattern(capturePattern(delimitedPattern(`${extChars}+`, '.')));
20+
const path = optionalPattern(prefixedPattern('/', `(?:${allCharsWithDot}+\\/?)*`));
21+
const query = optionalPattern(prefixedPattern('?', `${extChars}*`));
22+
const fragment = optionalPattern(prefixedPattern('#', `${extChars}*`));
23+
24+
const regex = new RegExp(`^${scheme}${authority}${path}${query}${fragment}$`, 'i');
25+
26+
const warningConstructor = createTypeWarning('Internationalized Resource Identifier (IRI)');
27+
28+
export default checkRegex(regex, warningConstructor) as Rule;

src/tests/regexValues/iri.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ export default (test: Test) => {
1919
itsValid('ftp://foo.bar/baz', test);
2020
itsValid('http://⌘➡例子.测试✪उदाहरण.परीकإختبار/䨹', test);
2121
itsValid('http://-.~_!$&\'()*+,;=:%40:80%2f::::::@example.com', test);
22+
itsValid('http://www.example.com/fgdfgd?sdfsdfsdf#fgdgdfg', test);
23+
24+
// tslint:disable-next-line:max-line-length
25+
itsValid('http://some.large.test.string.for.regex/some-large-string/string.html?largeString=largeString&someStrangeText=%D0%9F%D1%81%D0%B5%D0%B2%D0%B4%D0%BE%D1%82%D1%83%D0%B1%D0%B5%D1%80%D0%BA%D1%83%D0%BB%D0%B5%D0%B7', test);
2226
};

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"lib": [
99
"es2016"
1010
],
11+
"sourceMap": true,
1112
"removeComments": true,
1213
"preserveConstEnums": true,
1314
"declaration": true,
@@ -27,4 +28,4 @@
2728
"dist/**/*"
2829
],
2930
"compileOnSave": true
30-
}
31+
}

0 commit comments

Comments
 (0)