Skip to content

Commit 2509d6a

Browse files
authored
feat: @rocket.chat/string-helpers (#431)
1 parent 830b947 commit 2509d6a

File tree

84 files changed

+830
-59
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+830
-59
lines changed

.vscode/settings.json

+20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
{
22
"eslint.workingDirectories": [
3+
{
4+
"directory": "packages/css-in-js",
5+
"changeProcessCWD": true
6+
},
7+
{
8+
"directory": "packages/emitter",
9+
"changeProcessCWD": true
10+
},
311
{
412
"directory": "packages/fuselage",
513
"changeProcessCWD": true
@@ -16,6 +24,18 @@
1624
"directory": "packages/icons",
1725
"changeProcessCWD": true
1826
},
27+
{
28+
"directory": "packages/memo",
29+
"changeProcessCWD": true
30+
},
31+
{
32+
"directory": "packages/mp3-encoder",
33+
"changeProcessCWD": true
34+
},
35+
{
36+
"directory": "packages/string-helpers",
37+
"changeProcessCWD": true
38+
},
1939
{
2040
"directory": "packages/ui-kit",
2141
"changeProcessCWD": true

.yarn/releases/yarn-berry.cjs

+4-4
Large diffs are not rendered by default.

package.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
{
22
"private": true,
3-
"workspaces": {
4-
"packages": [
5-
"packages/*"
6-
]
7-
},
3+
"workspaces": [
4+
"packages/*"
5+
],
86
"devDependencies": {
97
"husky": "^5.1.1",
108
"lerna": "^3.20.2"

packages/css-in-js/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"@rollup/plugin-json": "^4.1.0",
4545
"@rollup/plugin-node-resolve": "^11.0.1",
4646
"@rollup/plugin-typescript": "^8.1.0",
47-
"@types/jest": "^26.0.19",
47+
"@types/jest": "^26.0.22",
4848
"@types/stylis": "^4.0.0",
4949
"@typescript-eslint/eslint-plugin": "^4.11.0",
5050
"@typescript-eslint/parser": "^4.11.0",

packages/emitter/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"@rollup/plugin-json": "^4.1.0",
5252
"@rollup/plugin-node-resolve": "^11.0.1",
5353
"@rollup/plugin-typescript": "^8.1.0",
54-
"@types/jest": "^26.0.19",
54+
"@types/jest": "^26.0.22",
5555
"@typescript-eslint/eslint-plugin": "^4.11.1",
5656
"@typescript-eslint/parser": "^4.11.1",
5757
"documentation": "^13.1.0",

packages/fuselage-hooks/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"@rollup/plugin-json": "^4.1.0",
5252
"@rollup/plugin-node-resolve": "^9.0.0",
5353
"@rollup/plugin-typescript": "^6.0.0",
54-
"@types/jest": "^26.0.15",
54+
"@types/jest": "^26.0.22",
5555
"@types/react-dom": "^16.9.8",
5656
"@types/resize-observer-browser": "^0.1.3",
5757
"@types/use-subscription": "^1.0.0",

packages/fuselage/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
"@storybook/react": "^6.1.11",
7676
"@storybook/source-loader": "^6.1.11",
7777
"@storybook/theming": "^6.1.11",
78-
"@types/jest": "^26.0.20",
78+
"@types/jest": "^26.0.22",
7979
"autoprefixer": "^10.0.1",
8080
"babel-loader": "^8.1.0",
8181
"caniuse-lite": "^1.0.30001151",

packages/fuselage/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"rootDir": "./src/",
44
"target": "ES5",
5-
"module": "ES2020",
5+
"module": "ESNext",
66
"lib": ["ES2020", "DOM"],
77
"downlevelIteration": true,
88
"declaration": true,

packages/memo/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
"url": "https://github.com/RocketChat/Rocket.Chat.Fuselage/issues"
3838
},
3939
"devDependencies": {
40-
"@types/react": "^16.14.0",
4140
"eslint": "^7.18.0",
4241
"eslint-config-prettier": "^7.2.0",
4342
"eslint-plugin-import": "^2.22.1",

packages/memo/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
33
"target": "es5",
4-
"module": "ES2020",
4+
"module": "ESNext",
55
"declaration": true,
66
"declarationMap": true,
77
"sourceMap": true,

packages/mp3-encoder/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"@rollup/plugin-commonjs": "^17.0.0",
5252
"@rollup/plugin-node-resolve": "^11.0.1",
5353
"@rollup/plugin-typescript": "^8.1.0",
54-
"@types/jest": "^26.0.19",
54+
"@types/jest": "^26.0.22",
5555
"@typescript-eslint/eslint-plugin": "^4.11.0",
5656
"@typescript-eslint/parser": "^4.11.0",
5757
"documentation": "^13.1.0",

packages/string-helpers/.eslintignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/node_modules
2+
/dist

packages/string-helpers/.eslintrc.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
module.exports = {
2+
extends: [
3+
'plugin:@typescript-eslint/recommended',
4+
'plugin:@typescript-eslint/eslint-recommended',
5+
'@rocket.chat/eslint-config',
6+
'prettier',
7+
],
8+
parser: '@typescript-eslint/parser',
9+
plugins: ['@typescript-eslint', 'prettier'],
10+
rules: {
11+
'@typescript-eslint/ban-ts-ignore': 'off',
12+
'@typescript-eslint/indent': 'off',
13+
'@typescript-eslint/no-extra-parens': 'off',
14+
'@typescript-eslint/no-explicit-any': 'off',
15+
'@typescript-eslint/no-unused-vars': [
16+
'error',
17+
{
18+
argsIgnorePattern: '^_',
19+
},
20+
],
21+
'func-call-spacing': 'off',
22+
'indent': 'off',
23+
'import/order': [
24+
'error',
25+
{
26+
'newlines-between': 'always',
27+
'groups': [
28+
'builtin',
29+
'external',
30+
'internal',
31+
['parent', 'sibling', 'index'],
32+
],
33+
'alphabetize': {
34+
order: 'asc',
35+
},
36+
},
37+
],
38+
'jsx-quotes': ['error', 'prefer-single'],
39+
'no-extra-parens': 'off',
40+
'no-spaced-func': 'off',
41+
'no-unused-vars': 'off',
42+
'no-useless-constructor': 'off',
43+
'no-use-before-define': 'off',
44+
'prefer-arrow-callback': ['error', { allowNamedFunctions: true }],
45+
'prettier/prettier': 2,
46+
},
47+
env: {
48+
browser: true,
49+
es6: true,
50+
jest: true,
51+
},
52+
settings: {
53+
'import/resolver': {
54+
node: {
55+
extensions: ['.js', '.ts', '.tsx'],
56+
},
57+
},
58+
'react': {
59+
version: 'detect',
60+
},
61+
},
62+
};

packages/string-helpers/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/dist
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/node_modules
2+
/dist

packages/string-helpers/.prettierrc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"singleQuote": true,
3+
"semi": true,
4+
"quoteProps": "consistent",
5+
"jsxSingleQuote": true,
6+
"printWidth": 80
7+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
errorOnDeprecated: true,
4+
testMatch: ['<rootDir>/src/**/*.spec.[jt]s?(x)'],
5+
globals: {
6+
'ts-jest': {
7+
tsconfig: {
8+
noUnusedLocals: false,
9+
noUnusedParameters: false,
10+
},
11+
},
12+
},
13+
};

packages/string-helpers/package.json

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"name": "@rocket.chat/string-helpers",
3+
"version": "0.23.0",
4+
"description": "Helper functions for string manipulation",
5+
"keywords": [
6+
"string",
7+
"helpers"
8+
],
9+
"author": {
10+
"name": "Rocket.Chat",
11+
"url": "https://rocket.chat/"
12+
},
13+
"homepage": "https://github.com/RocketChat/Rocket.Chat.Fuselage#readme",
14+
"license": "MIT",
15+
"publishConfig": {
16+
"access": "public"
17+
},
18+
"repository": {
19+
"type": "git",
20+
"url": "git+https://github.com/RocketChat/Rocket.Chat.Fuselage.git"
21+
},
22+
"main": "dist/cjs/index.js",
23+
"module": "dist/esm/index.js",
24+
"types": "dist/esm/index.d.ts",
25+
"typesVersions": {
26+
"<4.1": {
27+
"*": [
28+
"ts3.4/*"
29+
]
30+
}
31+
},
32+
"files": [
33+
"/dist"
34+
],
35+
"scripts": {
36+
"build": "run-s .:build:clean .:build:esm .:build:cjs .:build:ts3.4",
37+
".:build:clean": "rimraf dist",
38+
".:build:esm": "tsc -p tsconfig.json",
39+
".:build:cjs": "tsc -p tsconfig-cjs.json",
40+
".:build:ts3.4": "downlevel-dts dist/esm/ dist/ts3.4/ --to=3.4",
41+
"lint": "eslint src",
42+
"lint-fix": "eslint --fix src",
43+
"lint-staged": "lint-staged",
44+
"test": "jest --runInBand"
45+
},
46+
"bugs": {
47+
"url": "https://github.com/RocketChat/Rocket.Chat.Fuselage/issues"
48+
},
49+
"devDependencies": {
50+
"@types/jest": "^26.0.22",
51+
"@typescript-eslint/eslint-plugin": "^4.22.0",
52+
"@typescript-eslint/parser": "^4.22.0",
53+
"downlevel-dts": "^0.7.0",
54+
"eslint": "^7.24.0",
55+
"eslint-config-prettier": "^8.2.0",
56+
"eslint-plugin-import": "^2.22.1",
57+
"eslint-plugin-prettier": "^3.4.0",
58+
"jest": "^26.6.3",
59+
"lint-staged": "^10.5.4",
60+
"npm-run-all": "^4.1.5",
61+
"prettier": "^2.2.1",
62+
"rimraf": "^3.0.2",
63+
"ts-jest": "^26.5.5",
64+
"typescript": "^4.2.4"
65+
},
66+
"dependencies": {
67+
"tslib": "^2.2.0"
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { capitalize } from './capitalize';
2+
3+
describe('capitalize', () => {
4+
it('should convert "xyz" to "Xyz"', () => {
5+
expect(capitalize('xyz')).toBe('Xyz');
6+
});
7+
8+
it('should convert "xyz xyz" to "Xyz xyz"', () => {
9+
expect(capitalize('xyz xyz')).toBe('Xyz xyz');
10+
});
11+
12+
it('should convert " xyz" to " xyz"', () => {
13+
expect(capitalize(' xyz')).toBe(' xyz');
14+
});
15+
16+
it('should convert undefined to ""', () => {
17+
expect(capitalize((undefined as unknown) as string)).toBe('');
18+
});
19+
20+
it('should convert null to ""', () => {
21+
expect(capitalize((null as unknown) as string)).toBe('');
22+
});
23+
24+
it('should convert false to ""', () => {
25+
expect(capitalize((false as unknown) as string)).toBe('');
26+
});
27+
28+
it('should convert true to ""', () => {
29+
expect(capitalize((true as unknown) as string)).toBe('');
30+
});
31+
32+
it('should convert 0 to ""', () => {
33+
expect(capitalize((0 as unknown) as string)).toBe('');
34+
});
35+
36+
it('should convert 1 to ""', () => {
37+
expect(capitalize((1 as unknown) as string)).toBe('');
38+
});
39+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const capitalize = (s: string): string => {
2+
if (typeof s !== 'string') {
3+
return '';
4+
}
5+
6+
return s.charAt(0).toUpperCase() + s.slice(1);
7+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { escapeHTML } from './escapeHTML';
2+
3+
describe('escapeHTML', () => {
4+
it('works', () => {
5+
expect(escapeHTML('<div>Blah & "blah" & \'blah\'</div>')).toBe(
6+
'&lt;div&gt;Blah &amp; &quot;blah&quot; &amp; &#39;blah&#39;&lt;/div&gt;'
7+
);
8+
expect(escapeHTML('&lt;')).toBe('&amp;lt;');
9+
expect(escapeHTML(' ')).toBe(' ');
10+
expect(escapeHTML('¢')).toBe('&cent;');
11+
expect(escapeHTML('¢ £ ¥ € © ®')).toBe(
12+
'&cent; &pound; &yen; &euro; &copy; &reg;'
13+
);
14+
expect(escapeHTML((5 as unknown) as string)).toBe('5');
15+
expect(escapeHTML('')).toBe('');
16+
expect(escapeHTML((null as unknown) as string)).toBe('');
17+
expect(escapeHTML((undefined as unknown) as string)).toBe('');
18+
});
19+
});
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const characterToHtmlEntityCode = {
2+
'¢': 'cent',
3+
'£': 'pound',
4+
'¥': 'yen',
5+
'€': 'euro',
6+
'©': 'copy',
7+
'®': 'reg',
8+
'<': 'lt',
9+
'>': 'gt',
10+
'"': 'quot',
11+
'&': 'amp',
12+
"'": '#39',
13+
} as const;
14+
15+
const regex = new RegExp(
16+
`[${Object.keys(characterToHtmlEntityCode).join('')}]`,
17+
'g'
18+
);
19+
20+
const toString = (object: unknown): string => (object ? `${object}` : '');
21+
22+
const isEscapable = (
23+
char: string
24+
): char is keyof typeof characterToHtmlEntityCode =>
25+
char in characterToHtmlEntityCode;
26+
27+
const escapeChar = (char: string): string =>
28+
isEscapable(char) ? `&${characterToHtmlEntityCode[char]};` : '';
29+
30+
export const escapeHTML = (str: string): string =>
31+
toString(str).replace(regex, escapeChar);

0 commit comments

Comments
 (0)