@kikiutils/shared 13.4.0 → 13.5.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kikiutils/shared",
3
3
  "type": "module",
4
- "version": "13.4.0",
4
+ "version": "13.5.0",
5
5
  "description": "A lightweight and modular utility library for modern JavaScript and TypeScript — includes secure hashing, flexible logging, datetime tools, Vue/web helpers, storage abstraction, and more.",
6
6
  "author": "kiki-kanri",
7
7
  "license": "MIT",
@@ -33,34 +33,38 @@
33
33
  ],
34
34
  "sideEffects": false,
35
35
  "exports": {
36
- "./buffer": "./dist/buffer.js",
37
- "./clipboard": "./dist/clipboard.js",
38
- "./consola": "./dist/consola.js",
39
- "./crypto-hash": "./dist/crypto-hash.js",
40
- "./datetime": "./dist/datetime.js",
41
- "./element-plus": "./dist/element-plus.js",
42
- "./enum": "./dist/enum.js",
43
- "./env": "./dist/env.js",
44
- "./event-awaiter": "./dist/event-awaiter.js",
45
- "./general": "./dist/general.js",
46
- "./hash": "./dist/hash.js",
47
- "./math": "./dist/math.js",
48
- "./number": "./dist/number.js",
49
- "./object": "./dist/object.js",
50
- "./pino": "./dist/pino.js",
51
- "./random": "./dist/random.js",
52
- "./storage/enhanced/local": "./dist/storage/enhanced/local/index.js",
53
- "./storage/enhanced/local/core": "./dist/storage/enhanced/local/core.js",
54
- "./storage/enhanced/local/keyed-store": "./dist/storage/enhanced/local/keyed-store.js",
55
- "./storage/enhanced/redis": "./dist/storage/enhanced/redis/index.js",
56
- "./storage/enhanced/redis/core": "./dist/storage/enhanced/redis/core.js",
57
- "./storage/enhanced/redis/keyed-store": "./dist/storage/enhanced/redis/keyed-store.js",
58
- "./storage/lru/keyed-store": "./dist/storage/lru/keyed-store.js",
59
- "./string": "./dist/string.js",
60
- "./url": "./dist/url.js",
61
- "./vue": "./dist/vue.js",
62
- "./web": "./dist/web.js",
63
- "./package.json": "./package.json"
36
+ "./*": "./dist/*.js",
37
+ "./package.json": "./package.json",
38
+ "./storage/enhanced/local": {
39
+ "types": "./dist/storage/enhanced/local/index.d.ts",
40
+ "import": "./dist/storage/enhanced/local/index.js",
41
+ "require": null
42
+ },
43
+ "./storage/enhanced/local/index": {
44
+ "types": null,
45
+ "import": null,
46
+ "require": null
47
+ },
48
+ "./storage/enhanced/redis": {
49
+ "types": "./dist/storage/enhanced/redis/index.d.ts",
50
+ "import": "./dist/storage/enhanced/redis/index.js",
51
+ "require": null
52
+ },
53
+ "./storage/enhanced/redis/index": {
54
+ "types": null,
55
+ "import": null,
56
+ "require": null
57
+ },
58
+ "./types": {
59
+ "types": "./dist/types/index.d.ts",
60
+ "import": null,
61
+ "require": null
62
+ },
63
+ "./types/index": {
64
+ "types": null,
65
+ "import": null,
66
+ "require": null
67
+ }
64
68
  },
65
69
  "files": [
66
70
  "./dist",
@@ -147,26 +151,31 @@
147
151
  "@kikiutils/eslint-config": "^3.0.1",
148
152
  "@kikiutils/tsconfigs": "^5.0.5",
149
153
  "@noble/hashes": "^2.0.0",
150
- "@types/node": "^24.5.0",
154
+ "@types/fs-extra": "^11.0.4",
155
+ "@types/jsonfile": "^6.1.4",
156
+ "@types/node": "^24.5.2",
157
+ "@types/ssh2": "^1.15.5",
151
158
  "@vitest/coverage-v8": "^3.2.4",
152
159
  "async-validator": "^4.2.5",
160
+ "bson": "^6.10.4",
153
161
  "consola": "^3.4.2",
154
162
  "cross-env": "^10.0.0",
155
163
  "date-fns": "^4.1.0",
156
164
  "decimal.js": "^10.6.0",
157
165
  "depcheck": "^1.4.7",
158
- "element-plus": "^2.11.2",
166
+ "element-plus": "^2.11.3",
167
+ "fs-extra": "^11.3.2",
159
168
  "ioredis": "^5.7.0",
160
169
  "jsdom": "^27.0.0",
161
170
  "lru-cache": "^11.2.1",
162
171
  "millify": "^6.1.0",
163
- "pino": "^9.9.5",
172
+ "node-ssh": "^13.2.1",
173
+ "pino": "^9.10.0",
164
174
  "pino-pretty": "^13.1.1",
165
- "publint": "^0.3.12",
175
+ "publint": "^0.3.13",
166
176
  "superjson": "^2.2.2",
167
177
  "ts-unused-exports": "^11.0.1",
168
- "tsconfck": "^3.1.6",
169
- "tsdown": "^0.15.1",
178
+ "tsdown": "^0.15.2",
170
179
  "typescript": "^5.9.2",
171
180
  "unplugin-unused": "^0.5.3",
172
181
  "vitest": "^3.2.4",
@@ -175,7 +184,9 @@
175
184
  },
176
185
  "pnpm": {
177
186
  "onlyBuiltDependencies": [
187
+ "cpu-features",
178
188
  "esbuild",
189
+ "ssh2",
179
190
  "unrs-resolver",
180
191
  "vue-demi"
181
192
  ]
@@ -0,0 +1,428 @@
1
+ import type { Buffer } from 'node:buffer';
2
+ import type { Abortable } from 'node:events';
3
+ import type * as fs from 'node:fs';
4
+ import * as fsp from 'node:fs/promises';
5
+ import {
6
+ basename,
7
+ dirname,
8
+ extname,
9
+ format,
10
+ isAbsolute,
11
+ join,
12
+ normalize,
13
+ parse,
14
+ relative,
15
+ resolve,
16
+ toNamespacedPath,
17
+ } from 'node:path';
18
+ import type * as nodePath from 'node:path';
19
+
20
+ import * as fsExtra from 'fs-extra';
21
+ import type {
22
+ JFReadOptions,
23
+ JFWriteOptions,
24
+ } from 'jsonfile';
25
+
26
+ export type DoNotRemoveOrUseThisType = typeof fsExtra;
27
+ type DropFirstParameters<T extends (...args: any) => any> = Parameters<T> extends [any, ...infer R] ? R : never;
28
+ export type PathLike = fs.PathLike | Path;
29
+
30
+ /**
31
+ * Class representing a file system path with various utility methods for path operations.
32
+ *
33
+ * All methods in the `Path` class are immutable, returning new instances with modified values
34
+ * and leaving the original instance unchanged.
35
+ */
36
+ export class Path {
37
+ readonly #value: string;
38
+
39
+ constructor(...paths: PathLike[]) {
40
+ this.#value = join(...this.#toStrings(paths));
41
+ }
42
+
43
+ // Symbols
44
+ [Symbol.for('nodejs.util.inspect.custom')]() {
45
+ return this.#value;
46
+ }
47
+
48
+ [Symbol.toPrimitive](hint: string) {
49
+ if (hint === 'number') throw new TypeError('Cannot convert a Path to a number');
50
+ return this.#value;
51
+ }
52
+
53
+ // Private methods
54
+ #newInstance(...paths: PathLike[]) {
55
+ return new Path(...paths);
56
+ }
57
+
58
+ #toStrings(paths: PathLike[]) {
59
+ return paths.map((path) => path.toString());
60
+ }
61
+
62
+ // Public getters
63
+
64
+ /**
65
+ * @see {@link nodePath.dirname}
66
+ */
67
+ get parent() {
68
+ return this.dirname();
69
+ }
70
+
71
+ /**
72
+ * Returns the internal path string value.
73
+ */
74
+ get value() {
75
+ return this.#value;
76
+ }
77
+
78
+ // Public static methods
79
+
80
+ /**
81
+ * @see {@link nodePath.format}
82
+ */
83
+ static format(pathObject: nodePath.FormatInputPathObject) {
84
+ return new Path(format(pathObject));
85
+ }
86
+
87
+ /**
88
+ * @see {@link nodePath.resolve}
89
+ */
90
+ static resolve(...paths: PathLike[]) {
91
+ return new this(...paths).resolve();
92
+ }
93
+
94
+ // Public base methods
95
+
96
+ /**
97
+ * @see {@link nodePath.basename}
98
+ */
99
+ basename(suffix?: string) {
100
+ return basename(this.#value, suffix);
101
+ }
102
+
103
+ /**
104
+ * @see {@link nodePath.dirname}
105
+ */
106
+ dirname() {
107
+ return this.#newInstance(dirname(this.#value));
108
+ }
109
+
110
+ /**
111
+ * @see {@link nodePath.extname}
112
+ */
113
+ extname() {
114
+ return extname(this.#value);
115
+ }
116
+
117
+ /**
118
+ * @see {@link nodePath.isAbsolute}
119
+ */
120
+ isAbsolute() {
121
+ return isAbsolute(this.#value);
122
+ }
123
+
124
+ /**
125
+ * @see {@link nodePath.normalize}
126
+ */
127
+ normalize() {
128
+ return this.#newInstance(normalize(this.#value));
129
+ }
130
+
131
+ /**
132
+ * @see {@link nodePath.join}
133
+ */
134
+ join(...paths: PathLike[]) {
135
+ return this.#newInstance(this.#value, ...this.#toStrings(paths));
136
+ }
137
+
138
+ /**
139
+ * @see {@link nodePath.parse}
140
+ */
141
+ parse() {
142
+ return parse(this.#value);
143
+ }
144
+
145
+ /**
146
+ * @see {@link nodePath.relative}
147
+ */
148
+ relative(to: PathLike) {
149
+ return this.#newInstance(relative(this.#value, to.toString()));
150
+ }
151
+
152
+ /**
153
+ * @see {@link nodePath.resolve}
154
+ */
155
+ resolve() {
156
+ return this.#newInstance(resolve(this.#value));
157
+ }
158
+
159
+ toJSON() {
160
+ return this.#value;
161
+ }
162
+
163
+ /**
164
+ * @see {@link nodePath.toNamespacedPath}
165
+ */
166
+ toNamespacedPath() {
167
+ return toNamespacedPath(this.#value);
168
+ }
169
+
170
+ /**
171
+ * Converts the Path instance to a string.
172
+ * This method returns the internal path string value,
173
+ * making it useful for implicit and explicit string conversions.
174
+ */
175
+ toString() {
176
+ return this.#value;
177
+ }
178
+
179
+ // Some commonly used promise fs methods
180
+
181
+ /**
182
+ * @see {@link fsp.access}
183
+ */
184
+ access(...args: DropFirstParameters<typeof fsp.access>) {
185
+ return fsp.access(this.#value, ...args);
186
+ }
187
+
188
+ /**
189
+ * @see {@link fsp.appendFile}
190
+ */
191
+ appendFile(...args: DropFirstParameters<typeof fsp.appendFile>) {
192
+ return fsp.appendFile(this.#value, ...args);
193
+ }
194
+
195
+ /**
196
+ * @see {@link fsp.chmod}
197
+ */
198
+ chmod(...args: DropFirstParameters<typeof fsp.chmod>) {
199
+ return fsp.chmod(this.#value, ...args);
200
+ }
201
+
202
+ /**
203
+ * @see {@link fsp.chown}
204
+ */
205
+ chown(...args: DropFirstParameters<typeof fsp.chown>) {
206
+ return fsp.chown(this.#value, ...args);
207
+ }
208
+
209
+ /**
210
+ * @see {@link fsp.copyFile}
211
+ */
212
+ copyFile(...args: DropFirstParameters<typeof fsp.copyFile>) {
213
+ return fsp.copyFile(this.#value, ...args);
214
+ }
215
+
216
+ /**
217
+ * @see {@link fsp.mkdir}
218
+ */
219
+ mkdir(
220
+ options: fs.MakeDirectoryOptions & {
221
+ recursive: true;
222
+ },
223
+ ): Promise<string>;
224
+ mkdir(
225
+ options?:
226
+ | (fs.MakeDirectoryOptions & {
227
+ recursive?: false;
228
+ })
229
+ | fs.Mode
230
+ | null,
231
+ ): Promise<void>;
232
+ mkdir(options?: fs.MakeDirectoryOptions | fs.Mode | null): Promise<string | undefined>;
233
+ mkdir(...args: any): any {
234
+ return fsp.mkdir(this.#value, ...args);
235
+ }
236
+
237
+ /**
238
+ * @see {@link fsp.open}
239
+ */
240
+ open(...args: DropFirstParameters<typeof fsp.open>) {
241
+ return fsp.open(this.#value, ...args);
242
+ }
243
+
244
+ /**
245
+ * @see {@link fsp.readdir}
246
+ */
247
+ readdir(
248
+ path: PathLike,
249
+ options?:
250
+ | BufferEncoding
251
+ | (fs.ObjectEncodingOptions & {
252
+ recursive?: boolean;
253
+ withFileTypes?: false;
254
+ })
255
+ | null,
256
+ ): Promise<string[]>;
257
+ readdir(
258
+ path: PathLike,
259
+ options:
260
+ | 'buffer'
261
+ | {
262
+ encoding: 'buffer';
263
+ recursive?: boolean;
264
+ withFileTypes?: false;
265
+ },
266
+ ): Promise<Buffer[]>;
267
+ readdir(
268
+ path: PathLike,
269
+ options?:
270
+ | BufferEncoding
271
+ | (fs.ObjectEncodingOptions & {
272
+ recursive?: boolean;
273
+ withFileTypes?: false;
274
+ })
275
+ | null,
276
+ ): Promise<Buffer[] | string[]>;
277
+ readdir(
278
+ path: PathLike,
279
+ options: fs.ObjectEncodingOptions & {
280
+ recursive?: boolean;
281
+ withFileTypes: true;
282
+ },
283
+ ): Promise<fs.Dirent[]>;
284
+ readdir(
285
+ path: PathLike,
286
+ options: {
287
+ encoding: 'buffer';
288
+ recursive?: boolean;
289
+ withFileTypes: true;
290
+ },
291
+ ): Promise<fs.Dirent<Buffer>[]>;
292
+ readdir(...args: any): any {
293
+ return fsp.readdir(this.#value, ...args);
294
+ }
295
+
296
+ /**
297
+ * @see {@link fsp.readFile}
298
+ */
299
+ readFile(
300
+ options?:
301
+ | (Abortable & {
302
+ encoding?: null;
303
+ flag?: fs.OpenMode;
304
+ })
305
+ | null,
306
+ ): Promise<Buffer>;
307
+ readFile(
308
+ options:
309
+ | (Abortable & {
310
+ encoding: BufferEncoding;
311
+ flag?: fs.OpenMode;
312
+ })
313
+ | BufferEncoding,
314
+ ): Promise<string>;
315
+ readFile(
316
+ options?:
317
+ | (
318
+ & Abortable
319
+ & fs.ObjectEncodingOptions
320
+ & { flag?: fs.OpenMode }
321
+ )
322
+ | BufferEncoding
323
+ | null,
324
+ ): Promise<Buffer | string>;
325
+ readFile(...args: any): any {
326
+ return fsp.readFile(this.#value, ...args);
327
+ }
328
+
329
+ /**
330
+ * @see {@link fsp.rename}
331
+ */
332
+ rename(newPath: PathLike) {
333
+ return fsp.rename(this.#value, newPath.toString());
334
+ }
335
+
336
+ /**
337
+ * @see {@link fsp.rm}
338
+ */
339
+ rm(...args: DropFirstParameters<typeof fsp.rm>) {
340
+ return fsp.rm(this.#value, ...args);
341
+ }
342
+
343
+ /**
344
+ * @see {@link fsp.rmdir}
345
+ */
346
+ rmdir(...args: DropFirstParameters<typeof fsp.rmdir>) {
347
+ return fsp.rmdir(this.#value, ...args);
348
+ }
349
+
350
+ /**
351
+ * @see {@link fsp.stat}
352
+ */
353
+ stat(
354
+ opts?: fs.StatOptions & {
355
+ bigint?: false;
356
+ },
357
+ ): Promise<fs.Stats>;
358
+ stat(
359
+ opts: fs.StatOptions & {
360
+ bigint: true;
361
+ },
362
+ ): Promise<fs.BigIntStats>;
363
+ stat(opts?: fs.StatOptions): Promise<fs.BigIntStats | fs.Stats>;
364
+ stat(...args: any): any {
365
+ return fsp.stat(this.#value, ...args);
366
+ }
367
+
368
+ /**
369
+ * @see {@link fsp.truncate}
370
+ */
371
+ truncate(...args: DropFirstParameters<typeof fsp.truncate>) {
372
+ return fsp.truncate(this.#value, ...args);
373
+ }
374
+
375
+ /**
376
+ * @see {@link fsp.unlink}
377
+ */
378
+ unlink() {
379
+ return fsp.unlink(this.#value);
380
+ }
381
+
382
+ /**
383
+ * @see {@link fsp.writeFile}
384
+ */
385
+ writeFile(...args: DropFirstParameters<typeof fsp.writeFile>) {
386
+ return fsp.writeFile(this.#value, ...args);
387
+ }
388
+
389
+ // Some commonly used promise fs extra methods
390
+
391
+ /**
392
+ * @see {@link fsExtra.ensureDir}
393
+ */
394
+ ensureDir(options?: fsExtra.EnsureDirOptions | number) {
395
+ return fsExtra.ensureDir(this.#value, options);
396
+ }
397
+
398
+ /**
399
+ * @see {@link fsExtra.ensureDir}
400
+ */
401
+ mkdirp = this.ensureDir;
402
+
403
+ /**
404
+ * @see {@link fsExtra.ensureDir}
405
+ */
406
+ mkdirs = this.ensureDir;
407
+
408
+ /**
409
+ * @see {@link fsExtra.readJson}
410
+ */
411
+ async readJson<T = any>(options?: JFReadOptions) {
412
+ return await fsExtra.readJson(this.#value, options) as T;
413
+ }
414
+
415
+ /**
416
+ * @see {@link fsExtra.remove}
417
+ */
418
+ remove() {
419
+ return fsExtra.remove(this.#value);
420
+ }
421
+
422
+ /**
423
+ * @see {@link fsExtra.writeJson}
424
+ */
425
+ writeJson(data: any, options?: JFWriteOptions) {
426
+ return fsExtra.writeJson(this.#value, data, options);
427
+ }
428
+ }