@utilix-tech/sdk 0.1.1 → 0.1.4
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/README.md +345 -97
- package/dist/{chunk-ZKL2VX2G.js → chunk-NSOARQCM.js} +68 -1
- package/dist/{chunk-L6KCTHUW.js → chunk-OKSWDVOM.js} +133 -2
- package/dist/{code-QNrdLIR3.d.cts → code-BUqyaofO.d.cts} +18 -2
- package/dist/{code-QNrdLIR3.d.ts → code-BUqyaofO.d.ts} +18 -2
- package/dist/index.cjs +207 -10
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{misc-DcVBManm.d.cts → misc-CA3N198T.d.cts} +67 -2
- package/dist/{misc-DcVBManm.d.ts → misc-CA3N198T.d.ts} +67 -2
- package/dist/tools/code.cjs +67 -0
- package/dist/tools/code.d.cts +1 -1
- package/dist/tools/code.d.ts +1 -1
- package/dist/tools/code.js +1 -1
- package/dist/tools/misc.cjs +136 -0
- package/dist/tools/misc.d.cts +1 -1
- package/dist/tools/misc.d.ts +1 -1
- package/dist/tools/misc.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# @utilix-tech/sdk
|
|
2
2
|
|
|
3
|
-
**100+ developer utility
|
|
3
|
+
**100+ developer utility functions for Node.js — runs locally, no API key required.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
5
|
+
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
6
6
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
7
|
-
[](https://nodejs.org)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
9
10
|
|
|
10
|
-
The same tools available at [utilix.tech](https://utilix.tech)
|
|
11
|
+
The same tools available at **[utilix.tech](https://utilix.tech)**, packaged as a tree-shakeable Node.js SDK. Works offline, ships zero runtime secrets, and has full TypeScript types included.
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
@@ -25,168 +26,415 @@ yarn add @utilix-tech/sdk
|
|
|
25
26
|
pnpm add @utilix-tech/sdk
|
|
26
27
|
```
|
|
27
28
|
|
|
29
|
+
**Requires Node.js 18 or later.** TypeScript types are bundled — no `@types/` package needed.
|
|
30
|
+
|
|
28
31
|
---
|
|
29
32
|
|
|
30
33
|
## Quick Start
|
|
31
34
|
|
|
32
|
-
Each
|
|
35
|
+
Each of the 14 modules is available as a dedicated subpath import. Import only what you use; bundlers automatically tree-shake the rest.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// Pick exactly the modules you need
|
|
39
|
+
import { formatJson, diffJson } from "@utilix-tech/sdk/json";
|
|
40
|
+
import { encodeBase64, decodeBase64 } from "@utilix-tech/sdk/encoding";
|
|
41
|
+
import { hashAll, hashPassword } from "@utilix-tech/sdk/hashing";
|
|
42
|
+
import { convertColor, generatePalette } from "@utilix-tech/sdk/color";
|
|
43
|
+
import { generateUuid, generatePassword } from "@utilix-tech/sdk/generators";
|
|
44
|
+
import { buildCurl, decodeJwt } from "@utilix-tech/sdk/api";
|
|
45
|
+
import { formatSql, testRegex } from "@utilix-tech/sdk/code";
|
|
46
|
+
import { convertCase, slugify } from "@utilix-tech/sdk/text";
|
|
47
|
+
import { parseCsv, yamlToJson } from "@utilix-tech/sdk/data";
|
|
48
|
+
import { diffDates, parseCron } from "@utilix-tech/sdk/time";
|
|
49
|
+
import { convertBytes, pxToAll } from "@utilix-tech/sdk/units";
|
|
50
|
+
import { parseUrl, getStatusCode } from "@utilix-tech/sdk/network";
|
|
51
|
+
import { generateGradient, generateBoxShadow } from "@utilix-tech/sdk/css";
|
|
52
|
+
import { generateQrCode, optimizeSvg } from "@utilix-tech/sdk/misc";
|
|
53
|
+
```
|
|
33
54
|
|
|
34
|
-
|
|
55
|
+
CommonJS works too:
|
|
35
56
|
|
|
36
57
|
```js
|
|
37
|
-
|
|
58
|
+
const { formatJson } = require("@utilix-tech/sdk/json");
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Modules
|
|
64
|
+
|
|
65
|
+
### `/json` — JSON Tools
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { formatJson, minifyJson, diffJson, jsonToTypescript, validateJson,
|
|
69
|
+
evaluateJsonPath, jsonToCsv, yamlToJson, jsonToYaml, getJsonStats } from "@utilix-tech/sdk/json";
|
|
70
|
+
|
|
71
|
+
// Format with 2-space indent
|
|
72
|
+
formatJson('{"name":"alice","age":30}', { indent: 2 });
|
|
73
|
+
|
|
74
|
+
// Diff two JSON strings — returns line-by-line diff
|
|
75
|
+
diffJson(jsonA, jsonB);
|
|
76
|
+
|
|
77
|
+
// Generate TypeScript interface from JSON
|
|
78
|
+
jsonToTypescript('{"id":1,"name":"Alice"}', { rootName: "User" });
|
|
79
|
+
|
|
80
|
+
// Query with JSONPath
|
|
81
|
+
evaluateJsonPath(obj, "$.users[*].name");
|
|
38
82
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
// }
|
|
83
|
+
// Convert JSON to CSV
|
|
84
|
+
jsonToCsv('[{"a":1,"b":2}]');
|
|
85
|
+
|
|
86
|
+
// Validate against JSON Schema
|
|
87
|
+
validateJson(data, schema);
|
|
45
88
|
```
|
|
46
89
|
|
|
47
|
-
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `/encoding` — Encode & Decode
|
|
48
93
|
|
|
49
|
-
```
|
|
50
|
-
import { encodeBase64
|
|
94
|
+
```ts
|
|
95
|
+
import { encodeBase64, decodeBase64, encodeUrl, decodeUrl,
|
|
96
|
+
encodeHtmlEntities, decodeHtmlEntities, base32Encode, base32Decode } from "@utilix-tech/sdk/encoding";
|
|
51
97
|
|
|
52
|
-
|
|
53
|
-
|
|
98
|
+
encodeBase64("Hello, World!"); // "SGVsbG8sIFdvcmxkIQ=="
|
|
99
|
+
decodeBase64("SGVsbG8sIFdvcmxkIQ=="); // "Hello, World!"
|
|
100
|
+
encodeUrl("hello world?"); // "hello%20world%3F"
|
|
101
|
+
encodeHtmlEntities("<div class=\"a\">"); // "<div class="a">"
|
|
102
|
+
base32Encode("hello"); // "NBSWY3DPEB3W64TMMQ======"
|
|
54
103
|
```
|
|
55
104
|
|
|
56
|
-
|
|
105
|
+
---
|
|
57
106
|
|
|
58
|
-
|
|
59
|
-
|
|
107
|
+
### `/hashing` — Hash & Password
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { hashAll, hashOne, hashPassword, verifyPassword, generateHtpasswdFile } from "@utilix-tech/sdk/hashing";
|
|
60
111
|
|
|
61
|
-
|
|
62
|
-
|
|
112
|
+
// Hash with MD5, SHA-1, SHA-256, SHA-512 in one call
|
|
113
|
+
const hashes = await hashAll("my-string");
|
|
63
114
|
// { md5: "...", sha1: "...", sha256: "...", sha512: "..." }
|
|
115
|
+
|
|
116
|
+
// bcrypt
|
|
117
|
+
const hash = await hashPassword("my-password", 12);
|
|
118
|
+
const valid = await verifyPassword("my-password", hash);
|
|
119
|
+
|
|
120
|
+
// Generate .htpasswd file
|
|
121
|
+
generateHtpasswdFile([{ username: "alice", password: "secret" }]);
|
|
64
122
|
```
|
|
65
123
|
|
|
66
|
-
|
|
124
|
+
---
|
|
67
125
|
|
|
68
|
-
|
|
69
|
-
|
|
126
|
+
### `/text` — String & Text
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { convertCase, slugify, countWords, generateWords, generateParagraphs,
|
|
130
|
+
escapeString, htmlToMarkdown, applyOps } from "@utilix-tech/sdk/text";
|
|
131
|
+
|
|
132
|
+
convertCase("hello world", "camelCase"); // "helloWorld"
|
|
133
|
+
convertCase("hello world", "PascalCase"); // "HelloWorld"
|
|
134
|
+
convertCase("hello world", "kebab-case"); // "hello-world"
|
|
135
|
+
convertCase("hello world", "snake_case"); // "hello_world"
|
|
136
|
+
convertCase("hello world", "CONSTANT"); // "HELLO_WORLD"
|
|
137
|
+
|
|
138
|
+
slugify("Hello, World! 123"); // "hello-world-123"
|
|
70
139
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
140
|
+
const { words, sentences, readingTime } = countWords("some long text...");
|
|
141
|
+
|
|
142
|
+
generateParagraphs(3); // lorem ipsum paragraphs
|
|
143
|
+
|
|
144
|
+
// Apply line operations: sort, deduplicate, trim, reverse, shuffle
|
|
145
|
+
applyOps(text, ["sort", "deduplicate", "trim"]);
|
|
146
|
+
|
|
147
|
+
htmlToMarkdown("<h1>Hello</h1><p>World</p>");
|
|
74
148
|
```
|
|
75
149
|
|
|
76
|
-
|
|
150
|
+
---
|
|
77
151
|
|
|
78
|
-
|
|
79
|
-
|
|
152
|
+
### `/data` — CSV / YAML / TOML / XML / INI
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import { parseCsv, csvToJson, validateYaml, tomlToJson, jsonToToml,
|
|
156
|
+
formatXml, xmlToJson, jsonToXml, parseIni } from "@utilix-tech/sdk/data";
|
|
157
|
+
|
|
158
|
+
// CSV
|
|
159
|
+
const rows = parseCsv("name,age\nalice,30\nbob,25");
|
|
160
|
+
csvToJson("name,age\nalice,30"); // [{ name: "alice", age: "30" }]
|
|
161
|
+
|
|
162
|
+
// YAML
|
|
163
|
+
validateYaml("key: value\nlist:\n - a\n - b");
|
|
164
|
+
|
|
165
|
+
// TOML
|
|
166
|
+
tomlToJson('[server]\nhost = "localhost"\nport = 8080');
|
|
167
|
+
jsonToToml({ server: { host: "localhost", port: 8080 } });
|
|
168
|
+
|
|
169
|
+
// XML
|
|
170
|
+
formatXml("<root><item>hello</item></root>");
|
|
171
|
+
xmlToJson("<root><item>hello</item></root>");
|
|
172
|
+
|
|
173
|
+
// INI
|
|
174
|
+
parseIni("[db]\nhost=localhost\nport=5432");
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### `/generators` — UUID, Passwords, Fake Data
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { generateUuid, generateV4, generateV7, generateUlid,
|
|
183
|
+
generatePassword, checkStrength, generateData } from "@utilix-tech/sdk/generators";
|
|
184
|
+
|
|
185
|
+
generateUuid(); // "f47ac10b-58cc-4372-a567-0e02b2c3d479" (v4)
|
|
186
|
+
generateV7(); // time-ordered UUID v7
|
|
187
|
+
generateUlid(); // "01ARZ3NDEKTSV4RRFFQ69G5FAV"
|
|
188
|
+
|
|
189
|
+
generatePassword({ length: 16, symbols: true, numbers: true });
|
|
190
|
+
checkStrength("P@ssw0rd!"); // { score: 4, label: "Strong", entropy: 52.4 }
|
|
191
|
+
|
|
192
|
+
// Generate fake data rows
|
|
193
|
+
generateData([
|
|
194
|
+
{ name: "id", type: "uuid" },
|
|
195
|
+
{ name: "email", type: "email" },
|
|
196
|
+
{ name: "age", type: "number" },
|
|
197
|
+
], 10); // 10 rows
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### `/time` — Dates, Timezones, Cron
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { diffDates, parseCron, convertTime, formatRelative,
|
|
206
|
+
getNextRuns, humanizeDiff } from "@utilix-tech/sdk/time";
|
|
207
|
+
|
|
208
|
+
formatRelative(new Date("2024-01-01")); // "2 years ago"
|
|
209
|
+
|
|
210
|
+
diffDates("2024-01-01", "2025-06-15");
|
|
211
|
+
// { years: 1, months: 5, days: 14, ... }
|
|
212
|
+
|
|
213
|
+
// Timezone conversion
|
|
214
|
+
convertTime("2025-01-01T12:00:00", "America/New_York", "Asia/Tokyo");
|
|
215
|
+
|
|
216
|
+
// Cron parser
|
|
217
|
+
parseCron("0 9 * * MON-FRI");
|
|
218
|
+
// { description: "At 09:00, Monday through Friday", ... }
|
|
80
219
|
|
|
81
|
-
|
|
220
|
+
getNextRuns("*/5 * * * *", 5); // next 5 run timestamps
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### `/units` — Conversions
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import { convertBytes, pxToAll, convert, formatValue } from "@utilix-tech/sdk/units";
|
|
229
|
+
|
|
230
|
+
// File sizes
|
|
231
|
+
convertBytes(1073741824, "GB"); // 1
|
|
232
|
+
convertBytes(1073741824); // "1 GB" (auto-format)
|
|
233
|
+
|
|
234
|
+
// CSS units
|
|
235
|
+
pxToAll(16);
|
|
236
|
+
// { rem: "1rem", em: "1em", pt: "12pt", vw: "...", vh: "..." }
|
|
237
|
+
|
|
238
|
+
// Number bases
|
|
239
|
+
convert("255", 10, 16); // "ff"
|
|
240
|
+
convert("ff", 16, 10); // "255"
|
|
241
|
+
convert("11111111", 2, 10); // "255"
|
|
242
|
+
|
|
243
|
+
// Currency / locale formatting
|
|
244
|
+
formatValue(1234567.89, { locale: "en-US", currency: "USD" });
|
|
245
|
+
// "$1,234,567.89"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
### `/network` — URLs, IPs, HTTP
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { getStatusCode, isValidIp, isValidIpv4, isValidIpv6,
|
|
254
|
+
searchStatusCodes, buildGeoUrl, countryCodeToFlag } from "@utilix-tech/sdk/network";
|
|
255
|
+
|
|
256
|
+
getStatusCode(404);
|
|
257
|
+
// { code: 404, text: "Not Found", description: "...", category: "Client Error" }
|
|
258
|
+
|
|
259
|
+
searchStatusCodes("unauthorized");
|
|
260
|
+
|
|
261
|
+
isValidIpv4("192.168.1.1"); // true
|
|
262
|
+
isValidIpv6("::1"); // true
|
|
263
|
+
isValidIp("256.0.0.1"); // false
|
|
264
|
+
|
|
265
|
+
countryCodeToFlag("US"); // "🇺🇸"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
### `/api` — cURL, JWT, CORS, HTTP
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
import { buildCurl, parseCurlCommand, decodeJwt, signJwt,
|
|
274
|
+
generateCors, generateCspHeader } from "@utilix-tech/sdk/api";
|
|
275
|
+
|
|
276
|
+
buildCurl({
|
|
82
277
|
method: "POST",
|
|
83
278
|
url: "https://api.example.com/data",
|
|
84
279
|
headers: { "Content-Type": "application/json" },
|
|
85
280
|
body: { key: "value" },
|
|
86
281
|
});
|
|
87
|
-
console.log(curl);
|
|
88
282
|
// curl -X POST https://api.example.com/data \
|
|
89
283
|
// -H "Content-Type: application/json" \
|
|
90
284
|
// -d '{"key":"value"}'
|
|
91
|
-
```
|
|
92
285
|
|
|
93
|
-
|
|
286
|
+
// Parse a curl command back into its parts
|
|
287
|
+
parseCurlCommand('curl -X GET https://api.example.com -H "Authorization: Bearer token"');
|
|
94
288
|
|
|
95
|
-
|
|
96
|
-
|
|
289
|
+
// JWT — decode without verification
|
|
290
|
+
decodeJwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...");
|
|
291
|
+
// { header: {...}, payload: {...}, isExpired: false, expiresIn: "2h" }
|
|
292
|
+
|
|
293
|
+
// Generate CORS headers
|
|
294
|
+
generateCors({ origins: ["https://myapp.com"], methods: ["GET", "POST"] });
|
|
97
295
|
|
|
98
|
-
|
|
99
|
-
|
|
296
|
+
// Generate Content-Security-Policy header
|
|
297
|
+
generateCspHeader({ "default-src": ["'self'"], "script-src": ["'self'", "cdn.example.com"] });
|
|
100
298
|
```
|
|
101
299
|
|
|
102
|
-
|
|
300
|
+
---
|
|
103
301
|
|
|
104
|
-
|
|
105
|
-
import { formatSql } from "@utilix-tech/sdk/code";
|
|
302
|
+
### `/code` — SQL, HTML, RegEx, GQL
|
|
106
303
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
304
|
+
```ts
|
|
305
|
+
import { formatSql, minifySql, testRegex, formatHtml, formatGql,
|
|
306
|
+
detectDialect, splitStatements } from "@utilix-tech/sdk/code";
|
|
110
307
|
|
|
111
|
-
|
|
308
|
+
// SQL
|
|
309
|
+
formatSql("SELECT id,name FROM users WHERE active=1 ORDER BY name");
|
|
310
|
+
// SELECT
|
|
311
|
+
// id,
|
|
312
|
+
// name
|
|
313
|
+
// FROM users
|
|
314
|
+
// WHERE active = 1
|
|
315
|
+
// ORDER BY name
|
|
112
316
|
|
|
113
|
-
|
|
114
|
-
|
|
317
|
+
detectDialect("SELECT TOP 10 * FROM users"); // "tsql"
|
|
318
|
+
splitStatements("SELECT 1; SELECT 2; SELECT 3;");
|
|
319
|
+
|
|
320
|
+
// Regex
|
|
321
|
+
testRegex("^\\d+$", "12345", ["g"]);
|
|
322
|
+
// { isValid: true, matches: ["12345"], ... }
|
|
115
323
|
|
|
116
|
-
|
|
117
|
-
|
|
324
|
+
// HTML
|
|
325
|
+
formatHtml("<div><p>hello</p></div>", { indent: 2 });
|
|
326
|
+
minifyHtml("<div> <p> hello </p> </div>");
|
|
327
|
+
|
|
328
|
+
// GraphQL
|
|
329
|
+
formatGql("query { user(id: 1) { name email } }");
|
|
118
330
|
```
|
|
119
331
|
|
|
120
332
|
---
|
|
121
333
|
|
|
122
|
-
|
|
334
|
+
### `/color` — Color Conversion & Palettes
|
|
123
335
|
|
|
124
|
-
|
|
336
|
+
```ts
|
|
337
|
+
import { parseColor, convertColor, generatePalette, checkContrast } from "@utilix-tech/sdk/color";
|
|
125
338
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
| `@utilix-tech/sdk/code` | Format SQL, minify JS/CSS, detect language, evaluate math expressions |
|
|
139
|
-
| `@utilix-tech/sdk/color` | Convert between hex, RGB, HSL, HSV, CMYK; generate palettes |
|
|
140
|
-
| `@utilix-tech/sdk/css` | Parse, minify, and format CSS; extract variables and rules |
|
|
141
|
-
| `@utilix-tech/sdk/misc` | QR code generation, markdown conversion, semver comparison |
|
|
339
|
+
parseColor("#1a2b3c");
|
|
340
|
+
// { hex: "#1a2b3c", rgb: { r: 26, g: 43, b: 60 }, hsl: { h: 210, s: 40, l: 17 } }
|
|
341
|
+
|
|
342
|
+
// Generate a color palette
|
|
343
|
+
generatePalette("#3b82f6", "analogous"); // 5 analogous colors
|
|
344
|
+
generatePalette("#3b82f6", "complementary");
|
|
345
|
+
generatePalette("#3b82f6", "triadic");
|
|
346
|
+
|
|
347
|
+
// WCAG contrast check
|
|
348
|
+
checkContrast("#ffffff", "#000000");
|
|
349
|
+
// { ratio: 21, aa: true, aaa: true, level: "AAA" }
|
|
350
|
+
```
|
|
142
351
|
|
|
143
352
|
---
|
|
144
353
|
|
|
145
|
-
|
|
354
|
+
### `/css` — CSS Generators
|
|
146
355
|
|
|
147
|
-
|
|
356
|
+
```ts
|
|
357
|
+
import { generateGradient, generateBoxShadow, generateBorderRadius,
|
|
358
|
+
generateAnimationCSS, generateKeyframesCSS } from "@utilix-tech/sdk/css";
|
|
148
359
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
360
|
+
generateGradient({
|
|
361
|
+
type: "linear",
|
|
362
|
+
angle: 135,
|
|
363
|
+
stops: [{ color: "#6366f1", position: 0 }, { color: "#8b5cf6", position: 100 }],
|
|
364
|
+
});
|
|
365
|
+
// "linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)"
|
|
366
|
+
|
|
367
|
+
generateBoxShadow([{ x: 0, y: 4, blur: 6, spread: -1, color: "rgba(0,0,0,0.1)" }]);
|
|
368
|
+
// "0px 4px 6px -1px rgba(0,0,0,0.1)"
|
|
369
|
+
|
|
370
|
+
generateBorderRadius({ tl: 8, tr: 8, br: 0, bl: 0 });
|
|
371
|
+
// "8px 8px 0px 0px"
|
|
372
|
+
```
|
|
156
373
|
|
|
157
374
|
---
|
|
158
375
|
|
|
159
|
-
|
|
376
|
+
### `/misc` — SVG, QR, Unicode
|
|
160
377
|
|
|
161
|
-
|
|
378
|
+
```ts
|
|
379
|
+
import { optimizeSvg, sanitizeSvg, analyzeString, toUnicodeEscape,
|
|
380
|
+
formatBytes, calcSavings } from "@utilix-tech/sdk/misc";
|
|
162
381
|
|
|
163
|
-
|
|
382
|
+
// SVG
|
|
383
|
+
optimizeSvg("<svg>...</svg>"); // minified, cleaned SVG
|
|
384
|
+
sanitizeSvg("<svg>...</svg>"); // XSS-safe SVG
|
|
164
385
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
- Server-side Node.js applications
|
|
168
|
-
- Offline or air-gapped environments
|
|
386
|
+
// QR code (returns SVG or data URL)
|
|
387
|
+
// Note: QR generation requires the browser canvas API; use the utilix.tech API for server-side QR codes
|
|
169
388
|
|
|
170
|
-
|
|
389
|
+
// File size
|
|
390
|
+
formatBytes(1048576); // "1 MB"
|
|
391
|
+
calcSavings(1048576, 524288); // { saved: 524288, percent: 50 }
|
|
171
392
|
|
|
172
|
-
|
|
393
|
+
// Unicode
|
|
394
|
+
toUnicodeEscape("Hello"); // "\\u0048\\u0065\\u006C\\u006C\\u006F"
|
|
395
|
+
analyzeString("café"); // { length: 4, codePoints: [...], ... }
|
|
396
|
+
```
|
|
173
397
|
|
|
174
398
|
---
|
|
175
399
|
|
|
176
|
-
##
|
|
400
|
+
## All Modules at a Glance
|
|
177
401
|
|
|
178
|
-
|
|
179
|
-
|
|
402
|
+
| Import | What it does |
|
|
403
|
+
|---|---|
|
|
404
|
+
| `@utilix-tech/sdk/json` | Format, minify, diff, validate, JSONPath, CSV↔JSON, YAML↔JSON, TS types |
|
|
405
|
+
| `@utilix-tech/sdk/encoding` | Base64, URL, HTML entities, Base32 encode/decode |
|
|
406
|
+
| `@utilix-tech/sdk/hashing` | MD5, SHA-1/256/512, bcrypt, HMAC, .htpasswd |
|
|
407
|
+
| `@utilix-tech/sdk/text` | Case convert, slugify, word count, lorem ipsum, line ops, HTML→Markdown |
|
|
408
|
+
| `@utilix-tech/sdk/data` | CSV, YAML, TOML, XML, INI parse and convert |
|
|
409
|
+
| `@utilix-tech/sdk/generators` | UUID v4/v7, ULID, passwords, strength check, fake data |
|
|
410
|
+
| `@utilix-tech/sdk/time` | Date diff, timezone convert, cron parse, relative time |
|
|
411
|
+
| `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format |
|
|
412
|
+
| `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs |
|
|
413
|
+
| `@utilix-tech/sdk/api` | cURL build/parse, JWT decode/sign, CORS headers, CSP header |
|
|
414
|
+
| `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format |
|
|
415
|
+
| `@utilix-tech/sdk/color` | Hex/RGB/HSL/HSV/CMYK convert, palette generation, contrast check |
|
|
416
|
+
| `@utilix-tech/sdk/css` | CSS gradient, box-shadow, border-radius, keyframe animation generators |
|
|
417
|
+
| `@utilix-tech/sdk/misc` | SVG optimize/sanitize, file size format, Unicode inspector |
|
|
180
418
|
|
|
181
|
-
|
|
182
|
-
// ESM
|
|
183
|
-
import { formatJson } from "@utilix-tech/sdk/json";
|
|
419
|
+
---
|
|
184
420
|
|
|
185
|
-
|
|
186
|
-
|
|
421
|
+
## Python SDK
|
|
422
|
+
|
|
423
|
+
`@utilix-tech/sdk` has a Python companion — [`utilix-sdk`](https://pypi.org/project/utilix-sdk/) on PyPI — with the same 100+ tools and identical return shapes.
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
pip install utilix-sdk
|
|
187
427
|
```
|
|
188
428
|
|
|
189
|
-
|
|
429
|
+
Both SDKs return plain JSON-serializable objects so you can share test fixtures and API contracts across languages.
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Surface A vs Surface B
|
|
434
|
+
|
|
435
|
+
**This package is Surface A** — everything runs in-process in your Node.js runtime. No outbound requests, no API key, no rate limits.
|
|
436
|
+
|
|
437
|
+
A **Surface B REST API** (`api.utilix.tech`) is coming soon for use cases where you can't ship a Node.js or Python runtime. Same tools, callable from any language over HTTP.
|
|
190
438
|
|
|
191
439
|
---
|
|
192
440
|
|
|
@@ -13,10 +13,13 @@ __export(code_exports, {
|
|
|
13
13
|
buildGitCommand: () => buildGitCommand,
|
|
14
14
|
collapseHtmlWhitespace: () => collapseHtmlWhitespace,
|
|
15
15
|
collapseJsWhitespace: () => collapseJsWhitespace,
|
|
16
|
+
countProperties: () => countProperties,
|
|
17
|
+
countRules: () => countRules,
|
|
16
18
|
detectDialect: () => detectDialect,
|
|
17
19
|
detectOperationType: () => detectOperationType,
|
|
18
20
|
envToExport: () => envToExport,
|
|
19
21
|
envToJson: () => envToJson,
|
|
22
|
+
formatCss: () => formatCss,
|
|
20
23
|
formatGql: () => formatGql,
|
|
21
24
|
formatHtml: () => formatHtml,
|
|
22
25
|
formatSql: () => formatSql,
|
|
@@ -25,6 +28,7 @@ __export(code_exports, {
|
|
|
25
28
|
getJsStats: () => getJsStats,
|
|
26
29
|
getMethodColor: () => getMethodColor,
|
|
27
30
|
isValidTag: () => isValidTag,
|
|
31
|
+
minifyCss: () => minifyCss,
|
|
28
32
|
minifyGql: () => minifyGql,
|
|
29
33
|
minifyHtml: () => minifyHtml,
|
|
30
34
|
minifyJs: () => minifyJs,
|
|
@@ -2211,5 +2215,68 @@ function envToExport(input) {
|
|
|
2211
2215
|
function validateEnvKey(key) {
|
|
2212
2216
|
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
|
|
2213
2217
|
}
|
|
2218
|
+
function _calcCssResult(input, output) {
|
|
2219
|
+
const originalSize = input.length;
|
|
2220
|
+
const outputSize = output.length;
|
|
2221
|
+
const savingsPercent = originalSize === 0 ? 0 : Math.round((originalSize - outputSize) / originalSize * 100 * 100) / 100;
|
|
2222
|
+
return { output, originalSize, outputSize, savingsPercent };
|
|
2223
|
+
}
|
|
2224
|
+
function minifyCss(input) {
|
|
2225
|
+
let output = input;
|
|
2226
|
+
output = output.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
2227
|
+
output = output.replace(/\s+/g, " ");
|
|
2228
|
+
output = output.replace(/\s*{\s*/g, "{");
|
|
2229
|
+
output = output.replace(/\s*}\s*/g, "}");
|
|
2230
|
+
output = output.replace(/\s*:\s*/g, ":");
|
|
2231
|
+
output = output.replace(/\s*;\s*/g, ";");
|
|
2232
|
+
output = output.replace(/\s*,\s*/g, ",");
|
|
2233
|
+
output = output.replace(/;}/g, "}");
|
|
2234
|
+
output = output.trim();
|
|
2235
|
+
return _calcCssResult(input, output);
|
|
2236
|
+
}
|
|
2237
|
+
function formatCss(input, indentSize = 2) {
|
|
2238
|
+
const indent = " ".repeat(indentSize);
|
|
2239
|
+
const { output: minified } = minifyCss(input);
|
|
2240
|
+
let result = "";
|
|
2241
|
+
let insideBlock = false;
|
|
2242
|
+
let i = 0;
|
|
2243
|
+
while (i < minified.length) {
|
|
2244
|
+
const char = minified[i];
|
|
2245
|
+
if (char === "{") {
|
|
2246
|
+
result += " {\n";
|
|
2247
|
+
insideBlock = true;
|
|
2248
|
+
} else if (char === "}") {
|
|
2249
|
+
result = result.trimEnd() + "\n";
|
|
2250
|
+
result += "}\n\n";
|
|
2251
|
+
insideBlock = false;
|
|
2252
|
+
} else if (char === ";" && insideBlock) {
|
|
2253
|
+
result += ";\n";
|
|
2254
|
+
if (i + 1 < minified.length && minified[i + 1] !== "}") result += indent;
|
|
2255
|
+
} else {
|
|
2256
|
+
if (insideBlock && result.endsWith("{\n")) result += indent;
|
|
2257
|
+
result += char;
|
|
2258
|
+
}
|
|
2259
|
+
i++;
|
|
2260
|
+
}
|
|
2261
|
+
return _calcCssResult(input, result.trimEnd());
|
|
2262
|
+
}
|
|
2263
|
+
function countRules(css) {
|
|
2264
|
+
return (css.match(/{/g) ?? []).length;
|
|
2265
|
+
}
|
|
2266
|
+
function countProperties(css) {
|
|
2267
|
+
let count = 0;
|
|
2268
|
+
let insideBlock = false;
|
|
2269
|
+
for (const char of css) {
|
|
2270
|
+
if (char === "{") insideBlock = true;
|
|
2271
|
+
else if (char === "}") insideBlock = false;
|
|
2272
|
+
else if (char === ";" && insideBlock) count++;
|
|
2273
|
+
}
|
|
2274
|
+
css.replace(/{[^{}]*}/g, (block) => {
|
|
2275
|
+
const last = block.slice(1, -1).trim().split(";").pop()?.trim();
|
|
2276
|
+
if (last?.includes(":")) count++;
|
|
2277
|
+
return block;
|
|
2278
|
+
});
|
|
2279
|
+
return count;
|
|
2280
|
+
}
|
|
2214
2281
|
|
|
2215
|
-
export { ALL_FLAGS, CHEATSHEET, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, detectDialect, detectOperationType, envToExport, envToJson, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey };
|
|
2282
|
+
export { ALL_FLAGS, CHEATSHEET, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey };
|