sawit-utils 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +36 -0
- package/.github/workflows/publish-jsr.yml +24 -0
- package/.si.json +15 -0
- package/index.js +110 -0
- package/jsr.json +6 -0
- package/package.json +17 -0
- package/tests/index.test.js +10 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
|
+
|
|
4
|
+
name: Node.js Package
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [created]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: 24
|
|
19
|
+
- run: npm install
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: npm test
|
|
22
|
+
|
|
23
|
+
publish-npm:
|
|
24
|
+
needs: build
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: 24
|
|
31
|
+
registry-url: https://registry.npmjs.org/
|
|
32
|
+
- run: npm install
|
|
33
|
+
- run: npm ci
|
|
34
|
+
- run: npm publish
|
|
35
|
+
env:
|
|
36
|
+
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish to JSR
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
publish:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout
|
|
13
|
+
uses: actions/checkout@v6.0.2
|
|
14
|
+
|
|
15
|
+
- name: Setup Node
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: '24'
|
|
19
|
+
|
|
20
|
+
- name: Install Package
|
|
21
|
+
run: npm install
|
|
22
|
+
|
|
23
|
+
- name: Publish package
|
|
24
|
+
run: npx jsr publish
|
package/.si.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugin": "org.smartide.plugin.nodejs",
|
|
3
|
+
"run": "npm test",
|
|
4
|
+
"gui": false,
|
|
5
|
+
"intelligence": {
|
|
6
|
+
".json": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"run": "vscode-json-language-server --stdio"
|
|
9
|
+
},
|
|
10
|
+
".js": {
|
|
11
|
+
"enabled": false,
|
|
12
|
+
"run": "typescript-language-server --stdio"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import moment from "moment-timezone";
|
|
2
|
+
|
|
3
|
+
export function convertMsToDuration(ms) {
|
|
4
|
+
if (!ms || ms <= 0) return "0 seconds";
|
|
5
|
+
|
|
6
|
+
const duration = moment.duration(ms);
|
|
7
|
+
const hasLargerUnits = duration.asSeconds() >= 1;
|
|
8
|
+
|
|
9
|
+
const parts = [];
|
|
10
|
+
|
|
11
|
+
if (duration.years() > 0) parts.push(`${duration.years()} years`);
|
|
12
|
+
if (duration.months() > 0) parts.push(`${duration.months()} months`);
|
|
13
|
+
if (duration.weeks() > 0) parts.push(`${duration.weeks()} weeks`);
|
|
14
|
+
if (duration.days() > 0) parts.push(`${duration.days()} days`);
|
|
15
|
+
if (duration.hours() > 0) parts.push(`${duration.hours()} hours`);
|
|
16
|
+
if (duration.minutes() > 0) parts.push(`${duration.minutes()} minutes`);
|
|
17
|
+
if (duration.seconds() > 0) parts.push(`${duration.seconds()} seconds`);
|
|
18
|
+
|
|
19
|
+
if (!hasLargerUnits && duration.milliseconds() > 0)
|
|
20
|
+
parts.push(`${duration.milliseconds()} milliseconds`);
|
|
21
|
+
|
|
22
|
+
return parts.join(" ") || "0 detik";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function formatSize(byteCount, withPerSecond = false) {
|
|
26
|
+
if (!byteCount) return `0 yBytes${withPerSecond ? "/s" : ""}`;
|
|
27
|
+
|
|
28
|
+
let index = 8;
|
|
29
|
+
let size = byteCount;
|
|
30
|
+
const bytes = [
|
|
31
|
+
"yBytes",
|
|
32
|
+
"zBytes",
|
|
33
|
+
"aBytes",
|
|
34
|
+
"fBytes",
|
|
35
|
+
"pBytes",
|
|
36
|
+
"nBytes",
|
|
37
|
+
"µBytes",
|
|
38
|
+
"mBytes",
|
|
39
|
+
"Bytes",
|
|
40
|
+
"KiB",
|
|
41
|
+
"MiB",
|
|
42
|
+
"GiB",
|
|
43
|
+
"TiB",
|
|
44
|
+
"PiB",
|
|
45
|
+
"EiB",
|
|
46
|
+
"ZiB",
|
|
47
|
+
"YiB",
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
while (size < 1 && index > 0) {
|
|
51
|
+
size *= 1024;
|
|
52
|
+
index--;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
while (size >= 1024 && index < bytes.length - 1) {
|
|
56
|
+
size /= 1024;
|
|
57
|
+
index++;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return `${size.toFixed(2)} ${bytes[index]}${withPerSecond ? "/s" : ""}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function generateUID(id) {
|
|
64
|
+
if (!id) return null;
|
|
65
|
+
|
|
66
|
+
let hash = 0;
|
|
67
|
+
for (let i = 0; i < id.length; i++) {
|
|
68
|
+
const charCode = id.charCodeAt(i);
|
|
69
|
+
hash = (hash * 31 + charCode) % 1000000007;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const uniquePart = id.split("").reverse().join("").charCodeAt(0).toString(16);
|
|
73
|
+
let uid = `${Math.abs(hash).toString(16).toLowerCase()}-${uniquePart}`;
|
|
74
|
+
return uid;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getRandomElement(array) {
|
|
78
|
+
if (!array || !array.length || array.length === 0) return null;
|
|
79
|
+
return array[Math.floor(Math.random() * array.length)];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function isUrl(url) {
|
|
83
|
+
if (!url) return false;
|
|
84
|
+
return /(https?:\/\/[^\s]+)/g.test(url);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function delay(ms) {
|
|
88
|
+
if (!ms) return null;
|
|
89
|
+
return new Promise((res) => setTimeout(res, ms));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const formatUptime = (startTime) => {
|
|
93
|
+
const uptime = Date.now() - startTime;
|
|
94
|
+
const seconds = Math.floor((uptime / 1000) % 60);
|
|
95
|
+
const minutes = Math.floor((uptime / (1000 * 60)) % 60);
|
|
96
|
+
const hours = Math.floor((uptime / (1000 * 60 * 60)) % 24);
|
|
97
|
+
const days = Math.floor(uptime / (1000 * 60 * 60 * 24));
|
|
98
|
+
return `${days}d ${hours}h ${minutes}m ${seconds}s`;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const escapeHTML = (text) => {
|
|
102
|
+
if (!text) return "";
|
|
103
|
+
return text
|
|
104
|
+
.toString()
|
|
105
|
+
.replace(/&/g, "&")
|
|
106
|
+
.replace(/</g, "<")
|
|
107
|
+
.replace(/>/g, ">")
|
|
108
|
+
.replace(/"/g, """)
|
|
109
|
+
.replace(/'/g, "'");
|
|
110
|
+
};
|
package/jsr.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sawit-utils",
|
|
3
|
+
"description": "A palm-based utility for single-ball programmers who think palms are trees.",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node index.js",
|
|
8
|
+
"test": "vitest"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"moment": "^2.30.1",
|
|
12
|
+
"moment-timezone": "^0.6.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"vitest": "^4.0.18"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { expect, test, toBe } from "vitest";
|
|
2
|
+
import { convertMsToDuration, formatSize } from "../index.js";
|
|
3
|
+
|
|
4
|
+
test("convert 10000ms to equal 10s", () => {
|
|
5
|
+
expect(convertMsToDuration(10000)).toBe("10 seconds");
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("format 100000000bytes to equal 95.37 MiB", () => {
|
|
9
|
+
expect(formatSize(100000000)).toBe("95.37 MiB");
|
|
10
|
+
});
|