Skip to content

Commit fe6d808

Browse files
refactor(size-satisfies): migrate to TypeScript (#692)
* refactor(size-satisfies): migrate to TypeScript * Update workspaces/size-satisfies/package.json Co-authored-by: PierreDemailly <39910767+PierreDemailly@users.noreply.github.com> --------- Co-authored-by: PierreDemailly <39910767+PierreDemailly@users.noreply.github.com>
1 parent 9443133 commit fe6d808

9 files changed

Lines changed: 175 additions & 55 deletions

File tree

.changeset/early-ads-appear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nodesecure/size-satisfies": major
3+
---
4+
5+
Migrate codebase to TypeScript

tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
},
77
{
88
"path": "./workspaces/server"
9+
},
10+
{
11+
"path": "./workspaces/size-satisfies"
912
}
1013
]
1114
}

workspaces/size-satisfies/README.md

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ Scorecard](https://api.securityscorecards.dev/projects/github.com/NodeSecure/cli
77
![size](https://img.shields.io/github/languages/code-size/NodeSecure/size-satisfies?style=for-the-badge)
88
[![build](https://img.shields.io/github/actions/workflow/status/NodeSecure/cli/size-satisfies.yml?style=for-the-badge)](https://github.com/NodeSecure/cli/actions?query=workflow%3A%22Size+Satisfies+CI%22)
99

10-
Same as SemVer.satisfies but for file size!
10+
Check whether a file size satisfies a given constraint — like `semver.satisfies` but for bytes.
1111

1212
## Requirements
1313

14-
- [Node.js](https://nodejs.org/en/) v20 or higher
14+
- [Node.js](https://nodejs.org/en/) v18 or higher
1515

1616
## Getting Started
1717

@@ -26,25 +26,68 @@ $ yarn add @nodesecure/size-satisfies
2626
## Usage example
2727

2828
```js
29-
import { strict } from "assert";
30-
import sizeSatisfies from "size-satisfies";
29+
import sizeSatisfies from "@nodesecure/size-satisfies";
30+
31+
// String sizes are parsed using the `bytes` package (B, KB, MB, GB, …)
32+
console.log(sizeSatisfies(">= 45KB", "20MB")); // true — 20 MB is >= 45 KB
33+
console.log(sizeSatisfies("<= 45KB", "10B")); // true — 10 B is <= 45 KB
34+
console.log(sizeSatisfies("= 1MB", "1MB")); // true — exact match
35+
console.log(sizeSatisfies("> 45KB", "45KB")); // false — not strictly greater
36+
37+
// Numeric sizes are treated as bytes
38+
console.log(sizeSatisfies(">= 45KB", 46080)); // true — 46 080 B == 45 KB
39+
console.log(sizeSatisfies("= 45KB", 2000)); // false — 2 000 B != 45 KB
40+
console.log(sizeSatisfies("< 45KB", 0)); // true — 0 B < 45 KB
41+
42+
// Invalid patterns always return false
43+
console.log(sizeSatisfies("", "45KB")); // false — empty pattern
44+
console.log(sizeSatisfies("45KB", "45KB")); // false — missing operator
45+
console.log(sizeSatisfies("!! 45KB", "45KB")); // false — unknown operator
46+
47+
// Unparseable sizes fall back to 0
48+
console.log(sizeSatisfies("> 0KB", "not_a_size")); // false — 0 > 0 is false
49+
console.log(sizeSatisfies("= 0KB", "not_a_size")); // true — 0 == 0
50+
console.log(sizeSatisfies(">= not_a_size", "10KB")); // true — 10 KB >= 0
51+
```
52+
53+
## API
3154

32-
const { strictEqual } = strict;
55+
### `sizeSatisfies(pattern, size)`
3356

34-
strictEqual(sizeSatisfies(">= 45KB", "20MB"), true);
35-
strictEqual(sizeSatisfies("= 1MB", "1MB"), true);
36-
strictEqual(sizeSatisfies("= 1MB", 2000), false);
57+
```ts
58+
function sizeSatisfies(pattern: string, size: number | string): boolean
3759
```
3860

39-
The first argument of the `sizeSatisfies` method is the pattern with the operator + size. Available operators are `>=`, `<=`, `>`, `<`, `=`.
61+
Returns `true` when `size` satisfies the constraint expressed by `pattern`, `false` otherwise.
4062

41-
## API
63+
#### `pattern`
64+
65+
A string composed of an **operator** followed by a **size value** (with an optional space between them):
66+
67+
```
68+
">= 45KB"
69+
"< 1MB"
70+
"= 512B"
71+
```
72+
73+
| Operator | Meaning |
74+
|----------|--------------------------|
75+
| `>=` | greater than or equal to |
76+
| `<=` | less than or equal to |
77+
| `>` | strictly greater than |
78+
| `<` | strictly less than |
79+
| `=` | exactly equal to |
80+
81+
The size value in the pattern is parsed by the [`bytes`](https://www.npmjs.com/package/bytes) package and therefore supports the same units: `B`, `KB`, `MB`, `GB`, `TB`, `PB` (case-insensitive). An unparseable size value falls back to `0`.
82+
83+
A pattern that is empty, has no operator, or uses an unrecognised operator causes the function to return `false` immediately.
4284
43-
### sizeSatisfies(pattern: string, size: number | string): boolean
85+
#### `size`
4486
45-
When the size is a string we convert it to a bytes number. When the argument is a number we consider the value as bytes.
87+
The actual size to test against the pattern.
4688
47-
Invalid pattern will always return **false**.
89+
- **`number`** — interpreted as a raw byte count.
90+
- **`string`** — parsed by the [`bytes`](https://www.npmjs.com/package/bytes) package (e.g. `"45KB"`, `"1.5MB"`). An unparseable string falls back to `0`.
4891
4992
## License
5093

workspaces/size-satisfies/index.d.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

workspaces/size-satisfies/package.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
"version": "1.1.0",
44
"description": "Same as SemVer.satisfies but for file size!",
55
"type": "module",
6-
"exports": "./index.js",
6+
"main": "./dist/index.js",
7+
"types": "./dist/index.d.ts",
78
"scripts": {
8-
"lint": "eslint index.js",
9-
"test-only": "node --test test/test.js",
9+
"build": "tsc",
10+
"prepublishOnly": "npm run build",
11+
"lint": "eslint src/index.ts test",
12+
"test-only": "node --test test/test.ts",
1013
"test": "npm run lint && npm run test-only"
1114
},
1215
"publishConfig": {
@@ -20,8 +23,7 @@
2023
"directory": "workspaces/size-satisfies"
2124
},
2225
"files": [
23-
"index.js",
24-
"index.d.ts"
26+
"src"
2527
],
2628
"keywords": [
2729
"size",
@@ -42,6 +44,9 @@
4244
},
4345
"homepage": "https://github.com/NodeSecure/cli/master/workspaces/size-satisfies#readme",
4446
"dependencies": {
45-
"bytes": "^3.1.2"
47+
"bytes": "3.1.2"
48+
},
49+
"devDependencies": {
50+
"@types/bytes": "3.1.5"
4651
}
4752
}
Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,29 @@ const kOperators = {
88
">": (lh, rh) => lh > rh,
99
"<": (lh, rh) => lh < rh,
1010
"=": (lh, rh) => lh === rh
11-
};
11+
} satisfies Record<string, (lh: number, rh: number) => boolean>;
12+
13+
export function sizeSatisfies(
14+
pattern: string,
15+
size: number | string
16+
): boolean {
17+
const localSize = typeof size === "number" ?
18+
size :
19+
bytes(size) ?? 0;
1220

13-
/**
14-
* @function sizeSatisfies
15-
* @param {!string} pattern
16-
* @param {!(number | string)} size
17-
* @returns {boolean}
18-
*/
19-
function sizeSatisfies(pattern, size) {
20-
const localSize = typeof size === "number" ? size : bytes(size);
2121
const regexResult = /^(?<operator>[><=]{1,2})\s*(?<patternSize>.*)/g.exec(pattern);
22-
if (regexResult === null) {
22+
if (
23+
regexResult === null ||
24+
regexResult.groups === undefined
25+
) {
2326
return false;
2427
}
2528
const { operator, patternSize } = regexResult.groups;
2629

27-
return kOperators[operator](localSize, bytes(patternSize));
30+
return kOperators[operator as keyof typeof kOperators](
31+
localSize,
32+
bytes(patternSize) ?? 0
33+
);
2834
}
2935

3036
export default sizeSatisfies;

workspaces/size-satisfies/test/test.js

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Import Node.js Dependencies
2+
import { test } from "node:test";
3+
import assert from "node:assert";
4+
5+
// Import Internal Dependencies
6+
import sizeSatisfies from "../src/index.ts";
7+
8+
test("return false for empty pattern", () => {
9+
assert.strictEqual(sizeSatisfies("", "45KB"), false);
10+
});
11+
12+
test("return false for pattern without operator", () => {
13+
assert.strictEqual(sizeSatisfies("45KB", "45KB"), false);
14+
});
15+
16+
test("return false for invalid operator", () => {
17+
assert.strictEqual(sizeSatisfies("!! 45KB", "45KB"), false);
18+
});
19+
20+
test("pattern with only an operator treats patternSize as 0", () => {
21+
assert.strictEqual(sizeSatisfies(">=", "45KB"), true);
22+
assert.strictEqual(sizeSatisfies(">", "0KB"), false);
23+
assert.strictEqual(sizeSatisfies("=", "0KB"), true);
24+
assert.strictEqual(sizeSatisfies("<", "45KB"), false);
25+
});
26+
27+
test("size as a numeric value", () => {
28+
assert.strictEqual(sizeSatisfies(">= 45KB", 46080), true);
29+
assert.strictEqual(sizeSatisfies("= 45KB", 46080), true);
30+
assert.strictEqual(sizeSatisfies("= 45KB", 2000), false);
31+
assert.strictEqual(sizeSatisfies("< 45KB", 0), true);
32+
});
33+
34+
test("size as an unparseable string falls back to 0", () => {
35+
assert.strictEqual(sizeSatisfies("> 0KB", "not_a_size"), false);
36+
assert.strictEqual(sizeSatisfies("= 0KB", "not_a_size"), true);
37+
assert.strictEqual(sizeSatisfies("<= 10KB", "not_a_size"), true);
38+
});
39+
40+
test("unparseable patternSize falls back to 0", () => {
41+
assert.strictEqual(sizeSatisfies(">= not_a_size", "10KB"), true);
42+
assert.strictEqual(sizeSatisfies("= not_a_size", 0), true);
43+
assert.strictEqual(sizeSatisfies("> not_a_size", 0), false);
44+
});
45+
46+
test(">= operator", () => {
47+
assert.strictEqual(sizeSatisfies(">= 45KB", "20MB"), true);
48+
assert.strictEqual(sizeSatisfies(">= 45KB", "45KB"), true);
49+
assert.strictEqual(sizeSatisfies(">= 45KB", "10B"), false);
50+
});
51+
52+
test("<= operator", () => {
53+
assert.strictEqual(sizeSatisfies("<= 45KB", "10B"), true);
54+
assert.strictEqual(sizeSatisfies("<= 45KB", "45KB"), true);
55+
assert.strictEqual(sizeSatisfies("<= 45KB", "20MB"), false);
56+
});
57+
58+
test("= operator", () => {
59+
assert.strictEqual(sizeSatisfies("= 45KB", "45KB"), true);
60+
assert.strictEqual(sizeSatisfies("= 45KB", "46KB"), false);
61+
});
62+
63+
test("> operator", () => {
64+
assert.strictEqual(sizeSatisfies("> 45KB", "46KB"), true);
65+
assert.strictEqual(sizeSatisfies("> 45KB", "45KB"), false);
66+
assert.strictEqual(sizeSatisfies("> 45KB", "44KB"), false);
67+
});
68+
69+
test("< operator", () => {
70+
assert.strictEqual(sizeSatisfies("< 45KB", "44KB"), true);
71+
assert.strictEqual(sizeSatisfies("< 45KB", "45KB"), false);
72+
assert.strictEqual(sizeSatisfies("< 45KB", "46KB"), false);
73+
});
74+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "./dist",
5+
"rootDir": "./src",
6+
},
7+
"include": ["src"],
8+
"exclude": ["node_modules", "dist"]
9+
}

0 commit comments

Comments
 (0)