Skip to content

Commit 3d2e52e

Browse files
committed
chore: tweaks
1 parent 00ba3eb commit 3d2e52e

9 files changed

Lines changed: 107 additions & 35 deletions

File tree

.oxlintrc.json

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,63 +11,92 @@
1111
},
1212
"plugins": ["import", "unicorn", "oxc", "promise", "jsdoc", "vitest", "node"],
1313
"rules": {
14-
"catch-error-name": ["warn", { "name": "err" }],
15-
"curly": ["off", "multi-line"],
14+
// we should not enforce capitalized comments
15+
"capitalized-comments": "off",
16+
// prefer to export declarations instead of exporting at the end
1617
"group-exports": "off",
17-
"id-length": "off",
18+
// this rule is too restrictive
1819
"init-declarations": "off",
19-
"max-dependencies": "off",
20-
"max-lines": "off",
21-
"max-lines-per-function": "off",
22-
"max-params": ["warn", 4],
20+
// allow continue in complicated loops
2321
"no-continue": "off",
22+
// warn about console usage but allow it
2423
"no-console": "warn",
25-
"no-duplicate-imports": "off",
24+
// type imports can be duplicated with value imports
25+
"no-duplicate-imports": ["error", { "allowSeparateTypeImports": true }],
26+
// inline comments shall be allowed
27+
"no-inline-comments": "off",
2628
"no-magic-numbers": "off",
27-
// "no-magic-numbers": ["warn", { "ignore": [-1, 0, 1, 2] }],
29+
// allow nested ternary for better readability in some cases
2830
"no-nested-ternary": "off",
31+
// allow null usage
2932
"no-null": "off",
33+
// ternary operator shall be allowed for simple expressions
3034
"no-ternary": "off",
31-
"no-warning-comments": "off",
35+
// normally we do not enforce numeric separator usage
36+
"numeric-separators-style": "off",
37+
// we prefer to sort imports with its pkg name
3238
"sort-imports": "off",
39+
// object keys are not supposed to be sorted in many cases
3340
"sort-keys": "off",
3441

42+
// import plugin rules
43+
3544
"import/exports-last": "off",
3645
// usually we just export vue components as default export without naming it
3746
"import/no-anonymous-default-export": "off",
3847
// a rule that shall not be enabled anyway
3948
"import/no-named-export": "off",
49+
// allow importing stylesheets
4050
"import/no-unassigned-import": ["error", { "allow": ["**/*.css", "**/*.scss"] }],
41-
// named export is preferred in our codebase
51+
// named export is preferred
4252
"import/prefer-default-export": "off",
4353

44-
"jsdoc/check-tag-names": ["error", { "typed": true }],
45-
"jsdoc/require-param": "off",
54+
// jsdoc plugin rules
55+
56+
// duplicated typescript related jsdoc shall be warned
57+
"jsdoc/check-tag-names": ["warn", { "typed": true }],
58+
// we do not require types in jsdoc since we use TypeScript
4659
"jsdoc/require-param-type": "off",
47-
"jsdoc/require-returns": "off",
60+
// we do not require types in jsdoc since we use TypeScript
4861
"jsdoc/require-returns-type": "off",
4962

5063
"promise/always-return": "off",
64+
// we sometimes need to create new Promise instance
5165
"promise/avoid-new": "off",
66+
// we prefer async/await syntax
5267
"promise/prefer-await-to-then": "off",
68+
69+
// unicorn plugin rules
70+
// filename should not be enforced strictly, e.g. Vue SFC files shall be PascalCased
71+
// we shall expect a project level setting
5372
"unicorn/filename-case": "off",
54-
// toReversed can introduce memory overhead
73+
// toReversed can introduce memory overhead,
74+
// in some chained calls it is better to use reverse as the "reversed" array is also a temp variable.
5575
"unicorn/no-array-reverse": "off",
5676
// toSorted can introduce memory overhead
77+
// in some chained calls it is better to use reverse as the "sorted" array is also a temp variable.
5778
"unicorn/no-array-sort": "off",
58-
"unicorn/no-nested-ternary": "off",
59-
// at is not supported by our target environments
79+
// sometimes nested ternary is considerable
80+
"unicorn/no-nested-ternary": "warn",
81+
// Array.at() is too modern for browser targets
6082
"unicorn/prefer-at": "off",
61-
"unicorn/prefer-global-this": "off",
83+
// support starts with chrome71, firefox68. safari12.1, node12
84+
// leaving it to warn for edge cases
85+
"unicorn/prefer-global-this": "warn",
6286

63-
// seems conflicts with prettier
64-
"number-literal-case": "off",
65-
"numeric-separators-style": "off",
87+
// stylistic rules with default being tweaked
6688

67-
// style rules
68-
"capitalized-comments": "off",
69-
"max-statements": ["warn", { "max": 30 }],
70-
"no-inline-comments": "off"
89+
"catch-error-name": ["warn", { "name": "err" }],
90+
"curly": ["warn", "multi-line"],
91+
"id-length": "off",
92+
"max-dependencies": ["warn", { "ignoreTypeImports": true, "max": 15 }],
93+
"max-lines": ["warn", { "max": 500, "skipBlankLines": true, "skipComments": true }],
94+
"max-lines-per-function": [
95+
"warn",
96+
{ "max": 100, "skipBlankLines": true, "skipComments": true }
97+
],
98+
"max-params": ["warn", 4],
99+
"max-statements": ["warn", { "max": 30 }]
71100
},
72101
"overrides": [
73102
{

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"editor.defaultFormatter": "oxc.oxc-vscode"
2+
"editor.defaultFormatter": "oxc.oxc-vscode",
3+
"cSpell.words": ["crypted"]
34
}

src/base64.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
/* oxlint-disable unicorn/prefer-code-point unicorn/prefer-math-trunc */
1+
// oxlint-disable unicorn/prefer-code-point unicorn/prefer-math-trunc
22
import { BASE64_CODE, BASE64_INDEX } from "./constant.js";
33

44
/**
55
* Encodes a byte array to base64 with up to length bytes of input, using the custom bcrypt alphabet.
66
*
77
* @param byteArray Byte array
88
* @param length Maximum input length
9+
*
10+
* @returns Encoded string
911
*/
1012
export const encodeBase64 = (byteArray: number[] | Buffer, length: number): string => {
1113
if (length <= 0 || length > byteArray.length) throw new Error(`Illegal length: ${length}`);
@@ -45,6 +47,8 @@ export const encodeBase64 = (byteArray: number[] | Buffer, length: number): stri
4547
*
4648
* @param contentString String to decode
4749
* @param length Maximum output length
50+
*
51+
* @returns Decoded bytes
4852
*/
4953
// oxlint-disable-next-line max-statements
5054
export const decodeBase64 = (contentString: string, length: number): number[] => {

src/compare.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ import { getIllegalArgumentsTypeError } from "./utils.js";
88
*
99
* @param content String to compare
1010
* @param hash Hash to test against
11+
*
12+
* @returns `true` if the string matches the hash, `false` otherwise
1113
*/
1214
export const compareSync = (content: string, hash: string): boolean => {
13-
if (typeof content !== "string" || typeof hash !== "string")
15+
if (typeof content !== "string" || typeof hash !== "string") {
1416
throw getIllegalArgumentsTypeError(content, hash);
17+
}
1518

1619
if (hash.length !== 60) return false;
1720

@@ -25,6 +28,8 @@ export const compareSync = (content: string, hash: string): boolean => {
2528
* @param hash Data to be compared to
2629
* @param progressCallback Callback successively called with the percentage of rounds completed
2730
* (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
31+
*
32+
* @returns Promise resolving to `true` if the data matches the hash, `false` otherwise
2833
*/
2934
export const compare = (
3035
content: string,

src/constant.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// oxlint-disable no-magic-numbers
2+
13
export const BCRYPT_SALT_LEN = 16;
24

35
export const GENERATE_SALT_DEFAULT_LOG2_ROUNDS = 10;

src/crypt.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ const key = (key: number[], P: Int32Array<ArrayBuffer>, S: Int32Array<ArrayBuffe
157157

158158
/**
159159
* Expensive key schedule Blowfish.
160+
*
161+
* @param data Data bytes
162+
* @param key Key bytes
163+
* @param P P-array
164+
* @param S S-boxes
160165
*/
161166
const expensiveKeyScheduleBlowFish = (
162167
data: number[],
@@ -213,6 +218,9 @@ const expensiveKeyScheduleBlowFish = (
213218
* @param salt Salt bytes to use
214219
* @param rounds Number of rounds
215220
* @param progressCallback Callback called with the current progress
221+
* @param sync Whether to run synchronously
222+
*
223+
* @returns Crypted bytes
216224
*/
217225
// oxlint-disable-next-line max-params
218226
export const crypt = (
@@ -237,6 +245,8 @@ export const crypt = (
237245

238246
/**
239247
* Calculates the next round.
248+
*
249+
* @returns Next round or result
240250
*/
241251
const next = (): Promise<number[] | void> | number[] | void => {
242252
if (progressCallback) progressCallback(round / rounds);
@@ -251,8 +261,9 @@ export const crypt = (
251261
if (Date.now() - start > MAX_EXECUTION_TIME) break;
252262
}
253263
} else {
254-
for (let i = 0; i < 64; i++)
264+
for (let i = 0; i < 64; i++) {
255265
for (let j = 0; j < cLength >> 1; j++) encipher(cdata, j << 1, P, S);
266+
}
256267
const result: number[] = [];
257268

258269
for (let i = 0; i < cLength; i++) {
@@ -267,13 +278,14 @@ export const crypt = (
267278
return result;
268279
}
269280

270-
if (!sync)
281+
if (!sync) {
271282
return new Promise((resolve) =>
272283
// oxlint-disable-next-line no-promise-executor-return
273284
nextTick(() => {
274285
void (next() as Promise<number[] | undefined>).then(resolve);
275286
}),
276287
);
288+
}
277289
};
278290

279291
if (!sync) return next() as Promise<number[]>;

src/hash.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* oxlint-disable unicorn/prefer-code-point */
1+
// oxlint-disable unicorn/prefer-code-point
22

33
import { decodeBase64, encodeBase64 } from "./base64.js";
44
import { BCRYPT_SALT_LEN, C_ORIG, GENERATE_SALT_DEFAULT_LOG2_ROUNDS } from "./constant.js";
@@ -12,6 +12,9 @@ import { convertToUFT8Bytes } from "./uft8.js";
1212
* @param content String to hash
1313
* @param salt Salt to use
1414
* @param progressCallback Callback called with the current progress
15+
* @param sync Whether to run synchronously
16+
*
17+
* @returns Resulting hash
1518
*/
1619
// oxlint-disable-next-line max-statements
1720
const _hash = (
@@ -93,6 +96,8 @@ const _hash = (
9396
/**
9497
* Finishes hashing.
9598
* @param bytes Byte array
99+
*
100+
* @returns Resulting hash
96101
*/
97102
const finish = (bytes: number[]): string =>
98103
`$2${minor >= "a" ? minor : ""}$${rounds < 10 ? "0" : ""}${rounds}$${encodeBase64(
@@ -101,10 +106,11 @@ const _hash = (
101106
)}${encodeBase64(bytes, C_ORIG.length * 4 - 1)}`;
102107

103108
// Sync
104-
if (!sync)
109+
if (!sync) {
105110
return (
106111
crypt(passwordBytes, saltBytes, rounds, false, progressCallback) as Promise<number[]>
107112
).then((bytes) => finish(bytes));
113+
}
108114

109115
return finish(crypt(passwordBytes, saltBytes, rounds, true, progressCallback) as number[]);
110116
};
@@ -129,6 +135,8 @@ export const hashSync = (
129135
* @param salt Salt length to generate or salt to use
130136
* @param progressCallback Callback successively called with the percentage of rounds completed
131137
* (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
138+
*
139+
* @returns Promise resolving to the resulting hash
132140
*/
133141
export const hash = async (
134142
contentString: string,

src/salt.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const genSaltSync = (rounds = GENERATE_SALT_DEFAULT_LOG2_ROUNDS): string
2424
* Asynchronously generates a salt.
2525
*
2626
* @param rounds Number of rounds to use, defaults to 10 if omitted
27+
* @returns Promise resolving to the resulting salt
2728
*/
2829
export const genSalt = (rounds = GENERATE_SALT_DEFAULT_LOG2_ROUNDS): Promise<string> =>
2930
new Promise((resolve, reject) =>

src/uft8.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
/* oxlint-disable unicorn/prefer-code-point */
1+
// oxlint-disable unicorn/prefer-code-point
22

3-
/** Calculates the byte length of a string encoded as UTF8. */
3+
/**
4+
* Calculates the byte length of a string encoded as UTF8.
5+
*
6+
* @param content String to measure
7+
* @returns Byte length
8+
*/
49
export const getUTF8ByteLength = (content: string): number => {
510
let charCodePoint = 0;
611
let length = 0;
@@ -21,7 +26,12 @@ export const getUTF8ByteLength = (content: string): number => {
2126
return length;
2227
};
2328

24-
/** Converts a string to an array of UTF8 bytes. */
29+
/**
30+
* Converts a string to an array of UTF8 bytes.
31+
*
32+
* @param content String to convert
33+
* @returns Byte array
34+
*/
2535
export const convertToUFT8Bytes = (content: string): number[] => {
2636
let offset = 0;
2737
let c1;

0 commit comments

Comments
 (0)